main
cuh 251 lines 5.51 KB
Raw
1 /*
2 * Adapted from
3 * https://github.com/NVIDIA/FasterTransformer/blob/release/v5.3_tag/src/fastertransformer/kernels/decoder_masked_multihead_attention/decoder_masked_multihead_attention_template.hpp
4 * and
5 * https://github.com/NVIDIA/FasterTransformer/blob/release/v5.3_tag/src/fastertransformer/kernels/decoder_masked_multihead_attention_utils.h
6 * Copyright (c) 2023, The vLLM team.
7 * Copyright (c) 2020-2023, NVIDIA CORPORATION. All rights reserved.
8 *
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
12 *
13 * http://www.apache.org/licenses/LICENSE-2.0
14 *
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 */
21 #pragma once
22
23 #include "attention_generic.cuh"
24
25 #include <stdint.h>
26
27 namespace vllm {
28
29 // Define custom FP32 vector data types.
30 struct Float4_ {
31 float2 x;
32 float2 y;
33 };
34
35 struct Float8_ {
36 float2 x;
37 float2 y;
38 float2 z;
39 float2 w;
40 };
41
42 // FP32 vector types for Q, K, V.
43 template <>
44 struct Vec<float, 1> {
45 using Type = float;
46 };
47 template <>
48 struct Vec<float, 2> {
49 using Type = float2;
50 };
51 template <>
52 struct Vec<float, 4> {
53 using Type = float4;
54 };
55
56 // FP32 accumulator vector types corresponding to Vec.
57 template <>
58 struct FloatVec<float> {
59 using Type = float;
60 };
61 template <>
62 struct FloatVec<float2> {
63 using Type = float2;
64 };
65 template <>
66 struct FloatVec<float4> {
67 using Type = float4;
68 };
69
70 // Vector addition.
71 inline __device__ float add(float a, float b) { return a + b; }
72
73 inline __device__ float2 add(float2 a, float2 b) {
74 float2 c;
75 c.x = add(a.x, b.x);
76 c.y = add(a.y, b.y);
77 return c;
78 }
79
80 inline __device__ float4 add(float4 a, float4 b) {
81 float4 c;
82 c.x = add(a.x, b.x);
83 c.y = add(a.y, b.y);
84 c.z = add(a.z, b.z);
85 c.w = add(a.w, b.w);
86 return c;
87 }
88
89 // Vector multiplication.
90 template <>
91 inline __device__ float mul<float, float>(float a, float b) {
92 return a * b;
93 }
94
95 template <>
96 inline __device__ float2 mul(float2 a, float2 b) {
97 float2 c;
98 c.x = a.x * b.x;
99 c.y = a.y * b.y;
100 return c;
101 }
102
103 template <>
104 inline __device__ float2 mul(float a, float2 b) {
105 float2 c;
106 c.x = a * b.x;
107 c.y = a * b.y;
108 return c;
109 }
110
111 template <>
112 inline __device__ float4 mul(float4 a, float4 b) {
113 float4 c;
114 c.x = a.x * b.x;
115 c.y = a.y * b.y;
116 c.z = a.z * b.z;
117 c.w = a.w * b.w;
118 return c;
119 }
120
121 template <>
122 inline __device__ float4 mul(float a, float4 b) {
123 float4 c;
124 c.x = a * b.x;
125 c.y = a * b.y;
126 c.z = a * b.z;
127 c.w = a * b.w;
128 return c;
129 }
130
131 // Vector fused multiply-add.
132 inline __device__ float fma(float a, float b, float c) { return a * b + c; }
133
134 inline __device__ float2 fma(float2 a, float2 b, float2 c) {
135 float2 d;
136 d.x = fma(a.x, b.x, c.x);
137 d.y = fma(a.y, b.y, c.y);
138 return d;
139 }
140
141 inline __device__ float2 fma(float a, float2 b, float2 c) {
142 float2 d;
143 d.x = fma(a, b.x, c.x);
144 d.y = fma(a, b.y, c.y);
145 return d;
146 }
147
148 inline __device__ float4 fma(float4 a, float4 b, float4 c) {
149 float4 d;
150 d.x = fma(a.x, b.x, c.x);
151 d.y = fma(a.y, b.y, c.y);
152 d.z = fma(a.z, b.z, c.z);
153 d.w = fma(a.w, b.w, c.w);
154 return d;
155 }
156
157 inline __device__ float4 fma(float a, float4 b, float4 c) {
158 float4 d;
159 d.x = fma(a, b.x, c.x);
160 d.y = fma(a, b.y, c.y);
161 d.z = fma(a, b.z, c.z);
162 d.w = fma(a, b.w, c.w);
163 return d;
164 }
165
166 inline __device__ Float4_ fma(float a, Float4_ b, Float4_ c) {
167 Float4_ d;
168 d.x = fma(a, b.x, c.x);
169 d.y = fma(a, b.y, c.y);
170 return d;
171 }
172
173 inline __device__ Float8_ fma(float a, Float8_ b, Float8_ c) {
174 Float8_ d;
175 d.x = fma(a, b.x, c.x);
176 d.y = fma(a, b.y, c.y);
177 d.z = fma(a, b.z, c.z);
178 d.w = fma(a, b.w, c.w);
179 return d;
180 }
181
182 // Vector sum.
183 template <>
184 inline __device__ float sum(float v) {
185 return v;
186 }
187
188 template <>
189 inline __device__ float sum(float2 v) {
190 return v.x + v.y;
191 }
192
193 template <>
194 inline __device__ float sum(float4 v) {
195 return v.x + v.y + v.z + v.w;
196 }
197
198 template <>
199 inline __device__ float sum(Float4_ v) {
200 return v.x.x + v.x.y + v.y.x + v.y.y;
201 }
202
203 template <>
204 inline __device__ float sum(Float8_ v) {
205 return v.x.x + v.x.y + v.y.x + v.y.y + v.z.x + v.z.y + v.w.x + v.w.y;
206 }
207
208 // Vector dot product.
209 inline __device__ float dot(float a, float b) { return a * b; }
210
211 inline __device__ float dot(float2 a, float2 b) {
212 float2 c = mul<float2, float2, float2>(a, b);
213 return c.x + c.y;
214 }
215
216 inline __device__ float dot(Float4_ a, Float4_ b) {
217 float2 acc = mul<float2, float2, float2>(a.x, b.x);
218 acc = fma(a.y, b.y, acc);
219 return acc.x + acc.y;
220 }
221
222 inline __device__ float dot(Float8_ a, Float8_ b) {
223 float2 acc = mul<float2, float2, float2>(a.x, b.x);
224 acc = fma(a.y, b.y, acc);
225 acc = fma(a.z, b.z, acc);
226 acc = fma(a.w, b.w, acc);
227 return acc.x + acc.y;
228 }
229
230 // From float to float.
231 inline __device__ void from_float(float& dst, float src) { dst = src; }
232
233 inline __device__ void from_float(float2& dst, float2 src) { dst = src; }
234
235 inline __device__ void from_float(float4& dst, float4 src) { dst = src; }
236
237 // From float to float.
238 inline __device__ float to_float(float u) { return u; }
239
240 inline __device__ float2 to_float(float2 u) { return u; }
241
242 inline __device__ float4 to_float(float4 u) { return u; }
243
244 inline __device__ Float4_ to_float(Float4_ u) { return u; }
245
246 inline __device__ Float8_ to_float(Float8_ u) { return u; }
247
248 // Zero-out a variable.
249 inline __device__ void zero(float& dst) { dst = 0.f; }
250
251 } // namespace vllm