Skip to content

Commit c756214

Browse files
Grigorii Khvatskiigopherbot
Grigorii Khvatskii
authored andcommitted
cpu: add support for AVX-VNNI and IFMA detection
Added detection for x86 AVX-VNNI (VEX-coded Vector Neural Network Instructions) and AVX-IFMA (VEX-coded Integer Fused Multiply Add), including both the base VNNI set and the Int8 extention. Fixes golang/go#71142 Change-Id: I9e8d18b2e8bf81d5d4313a4a47fdf731fb3d44dd GitHub-Last-Rev: 32ea443 GitHub-Pull-Request: #242 Reviewed-on: https://go-review.googlesource.com/c/sys/+/641155 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Michael Pratt <mpratt@google.com> Auto-Submit: Ian Lance Taylor <iant@google.com> Reviewed-by: Ian Lance Taylor <iant@google.com>
1 parent 1c14dca commit c756214

File tree

3 files changed

+54
-4
lines changed

3 files changed

+54
-4
lines changed

cpu/cpu.go

+3
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@ var X86 struct {
7272
HasSSSE3 bool // Supplemental streaming SIMD extension 3
7373
HasSSE41 bool // Streaming SIMD extension 4 and 4.1
7474
HasSSE42 bool // Streaming SIMD extension 4 and 4.2
75+
HasAVXIFMA bool // Advanced vector extension Integer Fused Multiply Add
76+
HasAVXVNNI bool // Advanced vector extension Vector Neural Network Instructions
77+
HasAVXVNNIInt8 bool // Advanced vector extension Vector Neural Network Int8 instructions
7578
_ CacheLinePad
7679
}
7780

cpu/cpu_test.go

+34
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,40 @@ func TestAVX512HasAVX2AndAVX(t *testing.T) {
4141
}
4242
}
4343

44+
func TestAVX512BF16HasAVX512(t *testing.T) {
45+
if runtime.GOARCH == "amd64" {
46+
if cpu.X86.HasAVX512BF16 && !cpu.X86.HasAVX512 {
47+
t.Fatal("HasAVX512 expected true, got false")
48+
}
49+
}
50+
}
51+
52+
func TestAVXVNNIHasAVX(t *testing.T) {
53+
if cpu.X86.HasAVXVNNI && !cpu.X86.HasAVX {
54+
t.Fatal("HasAVX expected true, got false")
55+
}
56+
}
57+
58+
func TestAVXIFMAHasAVXVNNIAndAVX(t *testing.T) {
59+
if cpu.X86.HasAVXIFMA && !cpu.X86.HasAVX {
60+
t.Fatal("HasAVX expected true, got false")
61+
}
62+
63+
if cpu.X86.HasAVXIFMA && !cpu.X86.HasAVXVNNI {
64+
t.Fatal("HasAVXVNNI expected true, got false")
65+
}
66+
}
67+
68+
func TestAVXVNNIInt8HasAVXVNNIAndAVX(t *testing.T) {
69+
if cpu.X86.HasAVXVNNIInt8 && !cpu.X86.HasAVXVNNI {
70+
t.Fatal("HasAVXVNNI expected true, got false")
71+
}
72+
73+
if cpu.X86.HasAVXVNNIInt8 && !cpu.X86.HasAVX {
74+
t.Fatal("HasAVX expected true, got false")
75+
}
76+
}
77+
4478
func TestARM64minimalFeatures(t *testing.T) {
4579
if runtime.GOARCH != "arm64" || runtime.GOOS == "ios" {
4680
return

cpu/cpu_x86.go

+17-4
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ func initOptions() {
5353
{Name: "sse41", Feature: &X86.HasSSE41},
5454
{Name: "sse42", Feature: &X86.HasSSE42},
5555
{Name: "ssse3", Feature: &X86.HasSSSE3},
56+
{Name: "avxifma", Feature: &X86.HasAVXIFMA},
57+
{Name: "avxvnni", Feature: &X86.HasAVXVNNI},
58+
{Name: "avxvnniint8", Feature: &X86.HasAVXVNNIInt8},
5659

5760
// These capabilities should always be enabled on amd64:
5861
{Name: "sse2", Feature: &X86.HasSSE2, Required: runtime.GOARCH == "amd64"},
@@ -106,7 +109,7 @@ func archInit() {
106109
return
107110
}
108111

109-
_, ebx7, ecx7, edx7 := cpuid(7, 0)
112+
eax7, ebx7, ecx7, edx7 := cpuid(7, 0)
110113
X86.HasBMI1 = isSet(3, ebx7)
111114
X86.HasAVX2 = isSet(5, ebx7) && osSupportsAVX
112115
X86.HasBMI2 = isSet(8, ebx7)
@@ -134,14 +137,24 @@ func archInit() {
134137
X86.HasAVX512VAES = isSet(9, ecx7)
135138
X86.HasAVX512VBMI2 = isSet(6, ecx7)
136139
X86.HasAVX512BITALG = isSet(12, ecx7)
137-
138-
eax71, _, _, _ := cpuid(7, 1)
139-
X86.HasAVX512BF16 = isSet(5, eax71)
140140
}
141141

142142
X86.HasAMXTile = isSet(24, edx7)
143143
X86.HasAMXInt8 = isSet(25, edx7)
144144
X86.HasAMXBF16 = isSet(22, edx7)
145+
146+
// These features depend on the second level of extended features.
147+
if eax7 >= 1 {
148+
eax71, _, _, edx71 := cpuid(7, 1)
149+
if X86.HasAVX512 {
150+
X86.HasAVX512BF16 = isSet(5, eax71)
151+
}
152+
if X86.HasAVX {
153+
X86.HasAVXIFMA = isSet(23, eax71)
154+
X86.HasAVXVNNI = isSet(4, eax71)
155+
X86.HasAVXVNNIInt8 = isSet(4, edx71)
156+
}
157+
}
145158
}
146159

147160
func isSet(bitpos uint, value uint32) bool {

0 commit comments

Comments
 (0)