mirror of
git://git.code.sf.net/p/sbcl/sbcl
synced 2026-09-10 07:26:40 -04:00
feat(sb-simd): add modular AVX-512_FP16 vector support (f16.32, f16.16, f16.8)
- cpu-identification.lisp: add avx512fp16-supported-p detection via CPUID
leaf 7 subleaf 0 EDX bit 23.
- packages.lisp: export avx512fp16-supported-p and define sb-simd-avx512fp16
package extending sb-simd-avx512dq.
- instruction-sets/avx512fp16.lisp: define :avx512fp16 instruction set
introducing half-precision float vectors:
* f16.32 (512-bit ZMM, 32 lanes)
* f16.16 (256-bit YMM, 16 lanes)
* f16.8 (128-bit XMM, 8 lanes)
* Vector arithmetic (vaddph, vsubph, vmulph, vdivph, vsqrtph, vminph,
vmaxph, vrcpph, vrsqrtph, vscalefph)
* FMA with :encoding :fma (vfmadd213ph, vfmsub213ph, vfnmadd213ph, vfnmsub213ph)
* Conversions (f32.16 <-> f16.16, s32.16 <-> f16.16)
* Bitwise logic and casts
- define-custom-vops.lisp: add f16.32-not to def-not macrolet.
- x86-64-fake-vops.lisp: add f16.8-broadcast, f16.16-broadcast, and
f16.32-broadcast fake VOPs.
- record.lisp & test-suite/utilities.lisp: replace deprecated
:sb-simd-pack-256 and :sb-simd-pack-512 feature guards with :x86-64.
- test-packages.lisp: validate sb-simd-avx512fp16 symbol bindings.
This commit is contained in:
parent
16a029c1e0
commit
0dc8bb88d2
|
|
@ -60,7 +60,12 @@
|
|||
|
||||
(defun avx512vl-supported-p ()
|
||||
(and (>= (cpuid 0) 7)
|
||||
(logbitp 31 (nth-value 1 (cpuid 7 0))))))
|
||||
(logbitp 31 (nth-value 1 (cpuid 7 0)))))
|
||||
|
||||
(defun avx512fp16-supported-p ()
|
||||
(and (>= (cpuid 0) 7)
|
||||
(avx512f-supported-p)
|
||||
(logbitp 23 (nth-value 3 (cpuid 7 0))))))
|
||||
|
||||
#-x86-64
|
||||
(progn
|
||||
|
|
@ -104,6 +109,9 @@
|
|||
nil)
|
||||
|
||||
(defun avx512vl-supported-p ()
|
||||
nil)
|
||||
|
||||
(defun avx512fp16-supported-p ()
|
||||
nil))
|
||||
|
||||
(defun neon-supported-p ()
|
||||
|
|
|
|||
|
|
@ -365,7 +365,8 @@
|
|||
(def-not sb-simd-avx512bw::u8.64-not)
|
||||
(def-not sb-simd-avx512bw::u16.32-not)
|
||||
(def-not sb-simd-avx512bw::s8.64-not)
|
||||
(def-not sb-simd-avx512bw::s16.32-not)))
|
||||
(def-not sb-simd-avx512bw::s16.32-not)
|
||||
(def-not sb-simd-avx512fp16::f16.32-not)))
|
||||
;; Neon
|
||||
#+arm64
|
||||
(progn
|
||||
|
|
|
|||
121
contrib/sb-simd/code/instruction-sets/avx512fp16.lisp
Normal file
121
contrib/sb-simd/code/instruction-sets/avx512fp16.lisp
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
(in-package #:sb-simd-avx512fp16)
|
||||
|
||||
(define-instruction-set :avx512fp16
|
||||
(:test (avx512fp16-supported-p))
|
||||
(:include :avx512dq)
|
||||
(:scalars
|
||||
(f16 16 (unsigned-byte 16) #:unsigned-num (#:unsigned-reg)))
|
||||
(:simd-packs
|
||||
(f16.32 f16 512 #:simd-pack-512-ub16 (#:int-avx512-reg))
|
||||
(f16.16 f16 256 #:simd-pack-256-ub16 (#:int-avx2-reg))
|
||||
(f16.8 f16 128 #:simd-pack-ub16 (#:int-sse-reg)))
|
||||
(:simd-casts
|
||||
(f16.32 f16.32-broadcast)
|
||||
(f16.16 f16.16-broadcast)
|
||||
(f16.8 f16.8-broadcast))
|
||||
(:reinterpret-casts
|
||||
(f16.32! f16.32!-from-p128 f16.32!-from-p256 f16.32!-from-p512)
|
||||
(f16.16! f16.16!-from-p128 f16.16!-from-p256 f16.16!-from-p512)
|
||||
(f16.8! f16.8!-from-p128 f16.8!-from-p256 f16.8!-from-p512))
|
||||
(:instructions
|
||||
;; Reinterprets
|
||||
(f16.32!-from-p128 #:vmovdqu64 (f16.32) (p128) :cost 1 :encoding :move :always-translatable nil)
|
||||
(f16.32!-from-p256 #:vmovdqu64 (f16.32) (p256) :cost 1 :encoding :move :always-translatable nil)
|
||||
(f16.32!-from-p512 #:vmovdqu64 (f16.32) (p512) :cost 1 :encoding :move :always-translatable nil)
|
||||
|
||||
(f16.16!-from-p128 #:vmovdqu (f16.16) (p128) :cost 1 :encoding :move :always-translatable nil)
|
||||
(f16.16!-from-p256 #:vmovdqu (f16.16) (p256) :cost 1 :encoding :move :always-translatable nil)
|
||||
(f16.16!-from-p512 #:vextracti32x8 (f16.16) (p512) :cost 1 :suffix '(0) :always-translatable nil)
|
||||
|
||||
(f16.8!-from-p128 #:movdqu (f16.8) (p128) :cost 1 :encoding :move :always-translatable nil)
|
||||
(f16.8!-from-p256 #:vextracti128 (f16.8) (p256) :cost 1 :suffix '(0) :always-translatable nil)
|
||||
(f16.8!-from-p512 #:vextracti32x4 (f16.8) (p512) :cost 1 :suffix '(0) :always-translatable nil)
|
||||
|
||||
;; f16.32
|
||||
(f16.32-broadcast nil (f16.32) (f16) :cost 1 :encoding :fake-vop)
|
||||
(two-arg-f16.32+ #:vaddph (f16.32) (f16.32 f16.32) :cost 1 :associative t)
|
||||
(two-arg-f16.32- #:vsubph (f16.32) (f16.32 f16.32) :cost 1)
|
||||
(two-arg-f16.32* #:vmulph (f16.32) (f16.32 f16.32) :cost 1 :associative t)
|
||||
(two-arg-f16.32/ #:vdivph (f16.32) (f16.32 f16.32) :cost 1)
|
||||
(f16.32-sqrt #:vsqrtph (f16.32) (f16.32) :cost 1)
|
||||
(two-arg-f16.32-min #:vminph (f16.32) (f16.32 f16.32) :cost 1 :associative t)
|
||||
(two-arg-f16.32-max #:vmaxph (f16.32) (f16.32 f16.32) :cost 1 :associative t)
|
||||
(f16.32-rcp #:vrcpph (f16.32) (f16.32) :cost 1)
|
||||
(f16.32-rsqrt #:vrsqrtph (f16.32) (f16.32) :cost 1)
|
||||
(f16.32-scalef #:vscalefph (f16.32) (f16.32 f16.32) :cost 1)
|
||||
|
||||
(f16.32-fmadd #:vfmadd213ph (f16.32) (f16.32 f16.32 f16.32) :cost 1 :encoding :fma)
|
||||
(f16.32-fmsub #:vfmsub213ph (f16.32) (f16.32 f16.32 f16.32) :cost 1 :encoding :fma)
|
||||
(f16.32-fnmadd #:vfnmadd213ph (f16.32) (f16.32 f16.32 f16.32) :cost 1 :encoding :fma)
|
||||
(f16.32-fnmsub #:vfnmsub213ph (f16.32) (f16.32 f16.32 f16.32) :cost 1 :encoding :fma)
|
||||
|
||||
(two-arg-f16.32-and #:vpandd (f16.32) (f16.32 f16.32) :cost 1 :associative t)
|
||||
(two-arg-f16.32-or #:vpord (f16.32) (f16.32 f16.32) :cost 1 :associative t)
|
||||
(two-arg-f16.32-xor #:vpxord (f16.32) (f16.32 f16.32) :cost 1 :associative t)
|
||||
(f16.32-andc1 #:vpandnd (f16.32) (f16.32 f16.32) :cost 1)
|
||||
(f16.32-not nil (f16.32) (f16.32) :cost 1 :encoding :custom)
|
||||
|
||||
;; f16.16
|
||||
(f16.16-broadcast nil (f16.16) (f16) :cost 1 :encoding :fake-vop)
|
||||
(two-arg-f16.16+ #:vaddph (f16.16) (f16.16 f16.16) :cost 1 :associative t)
|
||||
(two-arg-f16.16- #:vsubph (f16.16) (f16.16 f16.16) :cost 1)
|
||||
(two-arg-f16.16* #:vmulph (f16.16) (f16.16 f16.16) :cost 1 :associative t)
|
||||
(two-arg-f16.16/ #:vdivph (f16.16) (f16.16 f16.16) :cost 1)
|
||||
(f16.16-sqrt #:vsqrtph (f16.16) (f16.16) :cost 1)
|
||||
(two-arg-f16.16-min #:vminph (f16.16) (f16.16 f16.16) :cost 1 :associative t)
|
||||
(two-arg-f16.16-max #:vmaxph (f16.16) (f16.16 f16.16) :cost 1 :associative t)
|
||||
(f16.16-rcp #:vrcpph (f16.16) (f16.16) :cost 1)
|
||||
(f16.16-rsqrt #:vrsqrtph (f16.16) (f16.16) :cost 1)
|
||||
|
||||
(f16.16-fmadd #:vfmadd213ph (f16.16) (f16.16 f16.16 f16.16) :cost 1 :encoding :fma)
|
||||
(f16.16-fmsub #:vfmsub213ph (f16.16) (f16.16 f16.16 f16.16) :cost 1 :encoding :fma)
|
||||
(f16.16-fnmadd #:vfnmadd213ph (f16.16) (f16.16 f16.16 f16.16) :cost 1 :encoding :fma)
|
||||
(f16.16-fnmsub #:vfnmsub213ph (f16.16) (f16.16 f16.16 f16.16) :cost 1 :encoding :fma)
|
||||
|
||||
;; f16.8
|
||||
(f16.8-broadcast nil (f16.8) (f16) :cost 1 :encoding :fake-vop)
|
||||
(two-arg-f16.8+ #:vaddph (f16.8) (f16.8 f16.8) :cost 1 :associative t)
|
||||
(two-arg-f16.8- #:vsubph (f16.8) (f16.8 f16.8) :cost 1)
|
||||
(two-arg-f16.8* #:vmulph (f16.8) (f16.8 f16.8) :cost 1 :associative t)
|
||||
(two-arg-f16.8/ #:vdivph (f16.8) (f16.8 f16.8) :cost 1)
|
||||
(f16.8-sqrt #:vsqrtph (f16.8) (f16.8) :cost 1)
|
||||
(two-arg-f16.8-min #:vminph (f16.8) (f16.8 f16.8) :cost 1 :associative t)
|
||||
(two-arg-f16.8-max #:vmaxph (f16.8) (f16.8 f16.8) :cost 1 :associative t)
|
||||
(f16.8-rcp #:vrcpph (f16.8) (f16.8) :cost 1)
|
||||
(f16.8-rsqrt #:vrsqrtph (f16.8) (f16.8) :cost 1)
|
||||
|
||||
(f16.8-fmadd #:vfmadd213ph (f16.8) (f16.8 f16.8 f16.8) :cost 1 :encoding :fma)
|
||||
(f16.8-fmsub #:vfmsub213ph (f16.8) (f16.8 f16.8 f16.8) :cost 1 :encoding :fma)
|
||||
(f16.8-fnmadd #:vfnmadd213ph (f16.8) (f16.8 f16.8 f16.8) :cost 1 :encoding :fma)
|
||||
(f16.8-fnmsub #:vfnmsub213ph (f16.8) (f16.8 f16.8 f16.8) :cost 1 :encoding :fma)
|
||||
|
||||
;; Conversions
|
||||
(f32.16-from-f16.16 #:vcvtph2psx (f32.16) (f16.16) :cost 3)
|
||||
(f16.16-from-f32.16 #:vcvtps2phx (f16.16) (f32.16) :cost 3)
|
||||
(f16.16-from-s32.16 #:vcvtdq2ph (f16.16) (s32.16) :cost 3)
|
||||
(s32.16-from-f16.16 #:vcvtph2dq (s32.16) (f16.16) :cost 3))
|
||||
(:associatives
|
||||
(f16.32+ two-arg-f16.32+ 0)
|
||||
(f16.32* two-arg-f16.32* 1)
|
||||
(f16.32-min two-arg-f16.32-min nil)
|
||||
(f16.32-max two-arg-f16.32-max nil)
|
||||
(f16.32-and two-arg-f16.32-and +u16-true+)
|
||||
(f16.32-or two-arg-f16.32-or +u16-false+)
|
||||
(f16.32-xor two-arg-f16.32-xor +u16-false+)
|
||||
|
||||
(f16.16+ two-arg-f16.16+ 0)
|
||||
(f16.16* two-arg-f16.16* 1)
|
||||
(f16.16-min two-arg-f16.16-min nil)
|
||||
(f16.16-max two-arg-f16.16-max nil)
|
||||
|
||||
(f16.8+ two-arg-f16.8+ 0)
|
||||
(f16.8* two-arg-f16.8* 1)
|
||||
(f16.8-min two-arg-f16.8-min nil)
|
||||
(f16.8-max two-arg-f16.8-max nil))
|
||||
(:reducers
|
||||
(f16.32- two-arg-f16.32- 0)
|
||||
(f16.32/ two-arg-f16.32/ 1)
|
||||
(f16.16- two-arg-f16.16- 0)
|
||||
(f16.16/ two-arg-f16.16/ 1)
|
||||
(f16.8- two-arg-f16.8- 0)
|
||||
(f16.8/ two-arg-f16.8/ 1)))
|
||||
|
|
@ -257,6 +257,7 @@
|
|||
#:avx512cd-supported-p
|
||||
#:avx512bw-supported-p
|
||||
#:avx512vl-supported-p
|
||||
#:avx512fp16-supported-p
|
||||
#:neon-supported-p))
|
||||
|
||||
(progn
|
||||
|
|
@ -2513,6 +2514,83 @@
|
|||
#:u64.8*
|
||||
#:s64.8*))
|
||||
|
||||
#+x86-64
|
||||
(defpackage #:sb-simd-avx512fp16
|
||||
(:use #:common-lisp #:sb-simd-internals #:sb-simd-avx512dq)
|
||||
#0#
|
||||
#1#
|
||||
#8#
|
||||
#9#
|
||||
#10#
|
||||
#12#
|
||||
#13#
|
||||
#14#
|
||||
#15=
|
||||
(:export
|
||||
#:f16
|
||||
;; f16.32
|
||||
#:f16.32
|
||||
#:f16.32!
|
||||
#:f16.32-broadcast
|
||||
#:f16.32+
|
||||
#:f16.32-
|
||||
#:f16.32*
|
||||
#:f16.32/
|
||||
#:f16.32-sqrt
|
||||
#:f16.32-min
|
||||
#:f16.32-max
|
||||
#:f16.32-rcp
|
||||
#:f16.32-rsqrt
|
||||
#:f16.32-scalef
|
||||
#:f16.32-fmadd
|
||||
#:f16.32-fmsub
|
||||
#:f16.32-fnmadd
|
||||
#:f16.32-fnmsub
|
||||
#:f16.32-and
|
||||
#:f16.32-or
|
||||
#:f16.32-xor
|
||||
#:f16.32-andc1
|
||||
#:f16.32-not
|
||||
;; f16.16
|
||||
#:f16.16
|
||||
#:f16.16!
|
||||
#:f16.16-broadcast
|
||||
#:f16.16+
|
||||
#:f16.16-
|
||||
#:f16.16*
|
||||
#:f16.16/
|
||||
#:f16.16-sqrt
|
||||
#:f16.16-min
|
||||
#:f16.16-max
|
||||
#:f16.16-rcp
|
||||
#:f16.16-rsqrt
|
||||
#:f16.16-fmadd
|
||||
#:f16.16-fmsub
|
||||
#:f16.16-fnmadd
|
||||
#:f16.16-fnmsub
|
||||
;; f16.8
|
||||
#:f16.8
|
||||
#:f16.8!
|
||||
#:f16.8-broadcast
|
||||
#:f16.8+
|
||||
#:f16.8-
|
||||
#:f16.8*
|
||||
#:f16.8/
|
||||
#:f16.8-sqrt
|
||||
#:f16.8-min
|
||||
#:f16.8-max
|
||||
#:f16.8-rcp
|
||||
#:f16.8-rsqrt
|
||||
#:f16.8-fmadd
|
||||
#:f16.8-fmsub
|
||||
#:f16.8-fnmadd
|
||||
#:f16.8-fnmsub
|
||||
;; conversions
|
||||
#:f32.16-from-f16.16
|
||||
#:f16.16-from-f32.16
|
||||
#:f16.16-from-s32.16
|
||||
#:s32.16-from-f16.16))
|
||||
|
||||
#+arm64
|
||||
(defpackage #:sb-simd-arm64
|
||||
(:use #:common-lisp #:sb-simd-internals #:sb-simd)
|
||||
|
|
|
|||
|
|
@ -181,14 +181,14 @@
|
|||
(defun scalar-record-p (x)
|
||||
(typep x '(and value-record (not simd-record))))
|
||||
|
||||
#-sb-simd-pack-256
|
||||
#-(or x86-64 sb-simd-pack-256)
|
||||
(progn
|
||||
(defstruct phony-simd-pack-256)
|
||||
(deftype simd-pack-256 (&optional element-type)
|
||||
(declare (ignore element-type))
|
||||
'phony-simd-pack-256))
|
||||
|
||||
#-sb-simd-pack-512
|
||||
#-(or x86-64 sb-simd-pack-512)
|
||||
(progn
|
||||
(defstruct phony-simd-pack-512)
|
||||
(deftype simd-pack-512 (&optional element-type)
|
||||
|
|
@ -202,10 +202,10 @@
|
|||
(ecase bits
|
||||
(128 (find-symbol "SIMD-PACK" "SB-EXT"))
|
||||
(256 (or (find-symbol "SIMD-PACK-256" "SB-EXT")
|
||||
#-sb-simd-pack-256
|
||||
#-(or x86-64 sb-simd-pack-256)
|
||||
'simd-pack-256))
|
||||
(512 (or (find-symbol "SIMD-PACK-512" "SB-EXT")
|
||||
#-sb-simd-pack-512
|
||||
#-(or x86-64 sb-simd-pack-512)
|
||||
'simd-pack-512)))))
|
||||
(cond ((not base-type) 't)
|
||||
((not scalar-record-name) base-type)
|
||||
|
|
|
|||
|
|
@ -1545,3 +1545,12 @@
|
|||
(define-fake-vop s16.32!-from-s16 (x)
|
||||
(%s16.32-broadcast x))
|
||||
|
||||
(define-fake-vop sb-simd-avx512fp16:f16.8-broadcast (x)
|
||||
(sb-simd-avx512fp16::%f16.8!-from-p128 (sb-simd-sse2::%u16.8-broadcast x)))
|
||||
|
||||
(define-fake-vop sb-simd-avx512fp16:f16.16-broadcast (x)
|
||||
(sb-simd-avx512fp16::%f16.16!-from-p256 (sb-simd-avx::%u16.16-broadcast x)))
|
||||
|
||||
(define-fake-vop sb-simd-avx512fp16:f16.32-broadcast (x)
|
||||
(sb-simd-avx512fp16::%f16.32!-from-p512 (sb-simd-avx512bw::%u16.32-broadcast x)))
|
||||
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
(:file "avx512f" :if-feature :x86-64)
|
||||
(:file "avx512bw" :if-feature :x86-64)
|
||||
(:file "avx512dq" :if-feature :x86-64)
|
||||
(:file "avx512fp16" :if-feature :x86-64)
|
||||
(:file "arm64" :if-feature :arm64)
|
||||
(:file "neon" :if-feature :arm64)))
|
||||
(:file "define-types")
|
||||
|
|
|
|||
|
|
@ -18,7 +18,8 @@
|
|||
(check-package '#:sb-simd-avx2)
|
||||
(check-package '#:sb-simd-avx512f :skip '(f32-fmaddsub f32-fmsubadd f64-fmaddsub f64-fmsubadd))
|
||||
(check-package '#:sb-simd-avx512bw :skip '(f32-fmaddsub f32-fmsubadd f64-fmaddsub f64-fmsubadd))
|
||||
(check-package '#:sb-simd-avx512dq :skip '(f32-fmaddsub f32-fmsubadd f64-fmaddsub f64-fmsubadd)))
|
||||
(check-package '#:sb-simd-avx512dq :skip '(f32-fmaddsub f32-fmsubadd f64-fmaddsub f64-fmsubadd))
|
||||
(check-package '#:sb-simd-avx512fp16 :skip '(f32-fmaddsub f32-fmsubadd f64-fmaddsub f64-fmsubadd)))
|
||||
#+arm64
|
||||
(check-package '#:sb-simd-neon)
|
||||
;; Ensure that every instruction has a corresponding VOP.
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@
|
|||
(sb-vm::%simd-pack-ref-64 pack 2)
|
||||
(sb-vm::%simd-pack-ref-64 pack 3)))
|
||||
|
||||
#+sb-simd-pack-512
|
||||
#+(or x86-64 sb-simd-pack-512)
|
||||
(defun %simd-pack-512-ub64s (pack)
|
||||
(values (sb-vm::%simd-pack-ref-64 pack 0)
|
||||
(sb-vm::%simd-pack-ref-64 pack 1)
|
||||
|
|
@ -61,13 +61,13 @@
|
|||
(multiple-value-bind (a0 a1) (%simd-pack-ub64s a)
|
||||
(multiple-value-bind (b0 b1) (%simd-pack-ub64s b)
|
||||
(and (= a0 b0) (= a1 b1))))))
|
||||
#+sb-simd-pack-256
|
||||
#+(or x86-64 sb-simd-pack-256)
|
||||
(sb-ext:simd-pack-256
|
||||
(when (sb-ext:simd-pack-256-p b)
|
||||
(multiple-value-bind (a0 a1 a2 a3) (%simd-pack-256-ub64s a)
|
||||
(multiple-value-bind (b0 b1 b2 b3) (%simd-pack-256-ub64s b)
|
||||
(and (= a0 b0) (= a1 b1) (= a2 b2) (= a3 b3))))))
|
||||
#+sb-simd-pack-512
|
||||
#+(or x86-64 sb-simd-pack-512)
|
||||
(sb-ext:simd-pack-512
|
||||
(when (sb-ext:simd-pack-512-p b)
|
||||
(multiple-value-bind (a0 a1 a2 a3 a4 a5 a6 a7) (%simd-pack-512-ub64s a)
|
||||
|
|
|
|||
Loading…
Reference in a new issue