@mineproness/tensorloop 2.1.55 → 2.1.57

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/index.js +14 -20
  2. package/package.json +5 -2
  3. package/readme.md +907 -72
  4. package/src/Embedding/index.d.ts +5 -5
  5. package/src/Embedding/index.js +118 -33
  6. package/src/FFN/index.d.ts +5 -5
  7. package/src/FFN/index.js +34 -39
  8. package/src/Linear/index.d.ts +7 -8
  9. package/src/Linear/index.js +173 -49
  10. package/src/OperationManager.js +100 -0
  11. package/src/Relu/index.d.ts +5 -0
  12. package/src/Relu/index.js +103 -0
  13. package/src/SelfAttention/index.d.ts +7 -13
  14. package/src/SelfAttention/index.js +108 -55
  15. package/src/Softmax/index.d.ts +4 -3
  16. package/src/Softmax/index.js +192 -12
  17. package/src/Tokenizer/index.d.ts +1 -0
  18. package/src/Tokenizer/index.js +92 -7
  19. package/src/TransformerBlock/index.d.ts +6 -7
  20. package/src/TransformerBlock/index.js +24 -23
  21. package/src/getVec.js +28 -0
  22. package/src/shaders/CalculateAcc.wgsl +50 -0
  23. package/src/shaders/CalculateLoss.wgsl +35 -0
  24. package/src/shaders/ComputeDInput.wgsl +32 -0
  25. package/src/shaders/EB.wgsl +31 -0
  26. package/src/shaders/EF.wgsl +25 -0
  27. package/src/shaders/LB.wgsl +57 -0
  28. package/src/shaders/LF.wgsl +44 -0
  29. package/src/shaders/RB.wgsl +37 -0
  30. package/src/shaders/RF.wgsl +33 -0
  31. package/src/shaders/ReductionFunction.wgsl +28 -0
  32. package/src/shaders/SB.wgsl +36 -0
  33. package/src/shaders/SF.wgsl +65 -0
  34. package/src/shaders/SoftmaxBackward.wgsl +31 -0
  35. package/src/shaders/attentionShader/CompueFinalForwardOutput.wgsl +29 -0
  36. package/src/shaders/attentionShader/ComputeDA.wgsl +30 -0
  37. package/src/shaders/attentionShader/ComputeDV.wgsl +37 -0
  38. package/src/shaders/attentionShader/ComputeK.wgsl +30 -0
  39. package/src/shaders/attentionShader/ComputedQ.wgsl +31 -0
  40. package/src/shaders/attentionShader/attentionSocres.wgsl +40 -0
  41. package/src/shaders/attentionShader/sumGradient.wgsl +24 -0
  42. package/src/GELU/index.d.ts +0 -6
  43. package/src/GELU/index.js +0 -33
  44. package/src/GetConfigs.js +0 -35
  45. package/src/Model/index.d.ts +0 -10
  46. package/src/Model/index.js +0 -88
  47. package/src/PositionEmbedding/index.d.ts +0 -11
  48. package/src/PositionEmbedding/index.js +0 -49
  49. package/src/ReLU/index.d.ts +0 -5
  50. package/src/ReLU/index.js +0 -17
  51. package/src/gpiInit.js +0 -764
@@ -1,10 +1,9 @@
1
1
  export class TransformerBlock{
2
- constructor(embeddingSize: number, configs:{
3
- dirname: string,
4
- activation: "relu" | "gelu"
2
+ constructor(device: GPUAdapter, embeddingSize: number, configs: {
3
+ dirname: string
5
4
  })
6
- Save(): void
7
- clearInputCache() : void
8
- forward(input: Float32Array[]) : Float32Array[]
9
- backward(dOutput: Float32Array[], LearningRate: number) : Float32Array[]
5
+ async forward(input : GPUBuffer) : Promise<GPUBuffer>
6
+ async backward(outInput : GPUBuffer, lr : number) : Promise<GPUBuffer>
7
+ async ClearInputCache() : Promise<void>
8
+ async Save() : Promise<void>
10
9
  }
@@ -1,30 +1,31 @@
1
- import { SelfAttention } from '../SelfAttention/index.js'
2
- import { FFN } from '../FFN/index.js'
3
- import fs from 'fs'
4
- export class TransformerBlock {
1
+ import {SelfAttention} from '../SelfAttention/index.js'
2
+ import {FFN} from '../FFN/index.js'
3
+ import {existsSync, mkdirSync} from 'fs'
4
+
5
+ export class TransformerBlock{
6
+ attention;
5
7
  ffn;
6
- selfAttention;
7
- constructor(embeddingSize, configs) {
8
- if(!fs.existsSync(configs.dirname)) fs.mkdirSync(configs.dirname)
9
- this.ffn = new FFN(embeddingSize, configs.activation, configs)
10
- this.selfAttention = new SelfAttention(embeddingSize, configs)
8
+ constructor(device, embeddingSize, configs){
9
+ if(!existsSync(configs.dirname)) mkdirSync(configs.dirname);
10
+ this.attention = new SelfAttention(device, embeddingSize, configs)
11
+ this.ffn = new FFN(device, embeddingSize, configs)
11
12
  }
12
- forward(input) {
13
- const attention = this.selfAttention.forward(input)
14
- return this.ffn.forward(attention)
13
+ async forward(input){
14
+ const xAtt = await this.attention.forward(input);
15
+ const xFF = await this.ffn.forward(xAtt);
16
+ return xFF
15
17
  }
16
- backward(dOutput, learningRate) {
17
- const dAttention = this.ffn.backward(dOutput, learningRate)
18
- return this.selfAttention.backward(dAttention, learningRate)
18
+ async backward(outGradient, lr){
19
+ const dAtt = await this.ffn.backward(outGradient, lr);
20
+ const dFF = await this.attention.backward(dAtt, lr)
21
+ return dFF
19
22
  }
20
- clearInputCache() {
21
- this.ffn.ClearInputCache()
22
- this.selfAttention.key.ClearInputCache()
23
- this.selfAttention.query.ClearInputCache()
24
- this.selfAttention.value.ClearInputCache()
23
+ async ClearInputCache(){
24
+ await this.ffn.ClearInputCache()
25
+ await this.attention.ClearInputCache()
25
26
  }
26
- Save() {
27
- this.selfAttention.Save()
28
- this.ffn.Save()
27
+ async Save(){
28
+ await this.ffn.Save()
29
+ await this.attention.Save()
29
30
  }
30
31
  }
package/src/getVec.js ADDED
@@ -0,0 +1,28 @@
1
+ import fs from 'fs'
2
+
3
+
4
+ export function getVector(filename, size, bias) {
5
+ if (!fs.existsSync(filename)) {
6
+ return null;
7
+ }
8
+ const bufferFloat32Array = fs.readFileSync(filename)
9
+ const r = new Float32Array(bufferFloat32Array.buffer, bufferFloat32Array.byteOffset, bufferFloat32Array.byteLength / 4);
10
+ if (r.length < size) {
11
+ const output = new Float32Array(size);
12
+ for(let a = 0; a < size; a++){
13
+ let num = r[a];
14
+ if(num){
15
+ output[a] = num;
16
+ }else{
17
+ output[a] = bias ? 0 : (Math.random() * 2 - 1) * 0.02
18
+ }
19
+ }
20
+ } else {
21
+ return r
22
+ }
23
+ }
24
+
25
+ export function SaveVector(filename, vectors) {
26
+ const buffer = Buffer.from(vectors.buffer)
27
+ fs.writeFileSync(filename, buffer)
28
+ }
@@ -0,0 +1,50 @@
1
+ struct Params{
2
+ vocabSize: u32,
3
+ tokenCount: u32
4
+ }
5
+
6
+ @group(0) @binding(0)
7
+
8
+ var <uniform> params : Params;
9
+
10
+
11
+ @group(0) @binding(1)
12
+
13
+ var <storage, read_write> probs : array<f32>;
14
+
15
+ @group(0) @binding(3)
16
+
17
+ var <storage, read_write> tToken : array<u32>;
18
+
19
+ @group(0) @binding(2)
20
+
21
+
22
+ var <storage, read_write> result : array<f32>;
23
+
24
+
25
+ @compute @workgroup_size(1)
26
+
27
+ fn main(@builtin(global_invocation_id) id : vec3<u32>){
28
+ let x = id.x;
29
+
30
+ var correct = 0.0;
31
+ for(var a = 0u; a < params.tokenCount; a++){
32
+ var bestVal = - 3.402823e38;
33
+ var maxToken = 0u;
34
+ var start = a * params.vocabSize;
35
+ let end = start + params.vocabSize;
36
+ for(var t = start; t < end; t++){
37
+ let val = probs[t];
38
+ if(bestVal < val){
39
+ bestVal = val;
40
+ maxToken = t - start;
41
+ }
42
+ }
43
+ if(maxToken == tToken[a]){
44
+ correct += 1.0;
45
+ }
46
+
47
+ }
48
+ correct /= f32(params.tokenCount);
49
+ result[x] = correct;
50
+ }
@@ -0,0 +1,35 @@
1
+ struct Params {
2
+ vocabSize: u32,
3
+ tokenCount: u32,
4
+ }
5
+
6
+ @group(0) @binding(0)
7
+
8
+ var <storage, read> probs : vec2<f32>;
9
+
10
+ @group(0) @binding(1)
11
+
12
+ var <storage, read> targetToken : array<f32>;
13
+
14
+ @group(0) @binding(2)
15
+
16
+ var <storage, read_write> loss : vec2<f32>;
17
+
18
+ @group(0) @binding(3)
19
+
20
+ var <uniform> params: Params;
21
+
22
+
23
+ @compute @workgroup_size(256)
24
+
25
+ fn main(@builtin(global_invocation_id) id : vec3<u32>) {
26
+ let index = id.x;
27
+ let token = index / params.vocabSize;
28
+ let vocabIndex = index % params.vocabSize;
29
+ let start = token * params.vocabSize;
30
+ let end = start + params.vocabSize;
31
+ var targetIndex = targetToken[token];
32
+ let total: u32 = params.tokenCount * params.vocabSize;
33
+ let probalitils = probs[u32(targetIndex)];
34
+ loss[index] = -log(probalitils + 1e-15);
35
+ }
@@ -0,0 +1,32 @@
1
+ struct Params {
2
+ vocabSize: f32,
3
+ tokenCount: f32,
4
+ lr: f32,
5
+ inputSize: f32,
6
+ }
7
+
8
+ @group(0) @binding(0)
9
+ var<storage, read_write> weight: array<f32>;
10
+ @group(0) @binding(1)
11
+ var<storage, read> outGradient: array<f32>;
12
+ @group(0) @binding(3)
13
+ var<uniform> params: Params;
14
+ @group(0) @binding(4)
15
+ var<storage, read_write> dInput: array<f32>;
16
+ @compute @workgroup_size(256)
17
+ fn main(@builtin(global_invocation_id) id: vec3<u32>) {
18
+ let index = id.x;
19
+ let total = params.tokenCount * params.inputSize;
20
+ if (index >= u32(total)) {
21
+ return;
22
+ }
23
+ let token =index / u32(params.inputSize);
24
+ let inputIndex = index % u32(params.inputSize);
25
+ var gradInput = 0.0;
26
+ for (var i = 0u; i < u32(params.vocabSize); i++) {
27
+ let w = weight[i * u32(params.inputSize) + inputIndex];
28
+ let grad = outGradient[token * u32(params.vocabSize) + i];
29
+ gradInput += grad * w;
30
+ }
31
+ dInput[index] = max(-1.0, min(1.0,gradInput));
32
+ }
@@ -0,0 +1,31 @@
1
+ struct Params{
2
+ lr: f32
3
+ }
4
+
5
+
6
+ @group(0) @binding(0)
7
+
8
+ var <storage, read_write> embeddings: array<f32>;
9
+
10
+ @group(0) @binding(1)
11
+
12
+ var <storage, read_write> outputGradient: array<f32>;
13
+
14
+ @group(0) @binding(2)
15
+
16
+ var <storage, read_write> tokens: array<u32>;
17
+
18
+ @group(0) @binding(3)
19
+ var <uniform> params : Params;
20
+
21
+ const embeddingSize = %embeddingSize%u;
22
+
23
+ @compute @workgroup_size(256)
24
+
25
+ fn main(@builtin(global_invocation_id) id : vec3<u32>){
26
+ let dim = id.x % embeddingSize;
27
+ let tokenIndex = id.x / embeddingSize;
28
+ let tokenID = tokens[tokenIndex];
29
+ let embeddingIDx = tokenID * embeddingSize + dim;
30
+ embeddings[embeddingIDx] -= params.lr * outputGradient[id.x];
31
+ }
@@ -0,0 +1,25 @@
1
+ @group(0) @binding(0)
2
+
3
+ var <storage, read_write> embeddings: array<f32>;
4
+
5
+ @group(0) @binding(1)
6
+
7
+ var <storage, read_write> output: array<f32>;
8
+
9
+ @group(0) @binding(2)
10
+
11
+ var <storage, read_write> tokens: array<u32>;
12
+
13
+ const embeddingSize = %embeddingSize%u;
14
+
15
+ @compute @workgroup_size(256)
16
+
17
+ fn main(@builtin(global_invocation_id) id : vec3<u32>){
18
+ let dim = id.x % embeddingSize;
19
+ let tokenIndex = id.x / embeddingSize;
20
+
21
+ let tokenID = tokens[tokenIndex];
22
+
23
+ let embeddingIDx = tokenID * embeddingSize + dim;
24
+ output[id.x] = embeddings[embeddingIDx];
25
+ }
@@ -0,0 +1,57 @@
1
+ struct Params {
2
+ vocabSize: f32,
3
+ tokenCount: f32,
4
+ lr: f32,
5
+ inputSize: f32
6
+ }
7
+
8
+ @group(0) @binding(0)
9
+
10
+ var<storage, read_write> bias: array<f32>;
11
+
12
+ @group(0) @binding(1)
13
+
14
+ var<storage, read_write> weight: array<f32>;
15
+
16
+ @group(0) @binding(2)
17
+
18
+ var<storage, read_write> outGradient: array<f32>;
19
+
20
+ @group(0) @binding(3)
21
+
22
+ var<storage, read_write> input: array<f32>;
23
+
24
+ @group(0) @binding(4)
25
+
26
+ var<uniform> params: Params;
27
+
28
+ @compute @workgroup_size(256)
29
+
30
+ fn main(@builtin(global_invocation_id) id: vec3<u32>) {
31
+ let index = id.x;
32
+
33
+ let totalWeights = u32(params.inputSize * params.vocabSize);
34
+ let token = index / u32(params.inputSize);
35
+ if (index >= totalWeights) {
36
+ return;
37
+ }
38
+ let outputIndex = index / u32(params.inputSize);
39
+ let inputIndex = index % u32(params.inputSize);
40
+ var dWeights = 0.0;
41
+ for (var token = 0u; token < u32(params.tokenCount); token++) {
42
+ let inputValue = input[token * u32(params.inputSize) + inputIndex];
43
+ let gradient = outGradient[token * u32(params.vocabSize) + outputIndex];
44
+ let dW = inputValue * gradient;
45
+ dWeights += f32(dW);
46
+ }
47
+ let vClap = weight[index] - params.lr * max(- 3.0, min(3.0, dWeights));
48
+ weight[index] = vClap;
49
+ if (inputIndex == 0u) {
50
+ var dBias = 0.0;
51
+ for (var token = 0u; token < u32(params.tokenCount); token++) {
52
+ dBias += f32(outGradient[token * u32(params.vocabSize) + outputIndex]);
53
+ }
54
+ bias[outputIndex] = bias[outputIndex] - params.lr * max(- 3.0, min(3.0, dBias));
55
+
56
+ }
57
+ }
@@ -0,0 +1,44 @@
1
+ struct Params {
2
+ inputSize: u32,
3
+ outputSize: u32,
4
+ tokenCount: u32,
5
+ }
6
+
7
+ @group(0) @binding(0)
8
+
9
+ var<storage, read_write> weights: array<f32>;
10
+
11
+ @group(0) @binding(1)
12
+
13
+ var<storage, read_write> output: array<f32>;
14
+
15
+ @group(0) @binding(2)
16
+
17
+ var<storage, read_write> input: array<f32>;
18
+
19
+ @group(0) @binding(3)
20
+
21
+ var<storage, read_write> bias: array<f32>;
22
+
23
+ @group(0) @binding(4)
24
+ var<uniform> params: Params;
25
+
26
+ @compute @workgroup_size(256)
27
+
28
+ fn main(@builtin(global_invocation_id) id: vec3<u32>) {
29
+ let index = id.x;
30
+ let total = params.tokenCount * params.outputSize;
31
+ if (index >= total) {
32
+ // output[index] = f32(total);
33
+ return;
34
+ }
35
+ let token = index / params.outputSize;
36
+ let outIndex = index % params.outputSize;
37
+ var sum = bias[outIndex];
38
+ for (var i = 0u; i < params.inputSize; i++) {
39
+ let inputIndex = token * params.inputSize + i;
40
+ let weightIndex = outIndex * params.inputSize + i;
41
+ sum += input[inputIndex] * weights[weightIndex];
42
+ }
43
+ output[index] = sum;
44
+ }
@@ -0,0 +1,37 @@
1
+ struct Param {
2
+ embeddingSize: u32,
3
+ tokenCount: u32
4
+ }
5
+
6
+ @group(0) @binding(0)
7
+
8
+ var<storage, read> input: vec2<f32>;
9
+
10
+ @group(0) @binding(1)
11
+
12
+ var<uniform> params: Param;
13
+
14
+ @group(0) @binding(2)
15
+
16
+ var<storage, read_write> output: vec2<f32>;
17
+
18
+ @group(0) @binding(3)
19
+
20
+ var<storage, read_write> inputGradient: vec2<f32>;
21
+ @compute @workgroup_size(256)
22
+
23
+ fn main(@builtin(global_invocation_id) id: vec3<u32>) {
24
+ let index = id.x;
25
+ let total = params.embeddingSize * params.tokenCount;
26
+ if (index >= total) {
27
+ return;
28
+ }
29
+ let x = input[index];
30
+ let grad = inputGradient[index];
31
+ if (x > 0) {
32
+ output[index] = grad;
33
+ }
34
+ else {
35
+ output[index] = grad * 0.02;
36
+ }
37
+ }
@@ -0,0 +1,33 @@
1
+ struct Param {
2
+ embeddingSize: u32,
3
+ tokenCount: u32
4
+ }
5
+
6
+ @group(0) @binding(0)
7
+
8
+ var<storage, read> input: vec2<f32>;
9
+
10
+ @group(0) @binding(1)
11
+
12
+ var<uniform> params: Param;
13
+
14
+ @group(0) @binding(2)
15
+
16
+ var<storage, read_write> output: vec2<f32>;
17
+
18
+ @compute @workgroup_size(256)
19
+
20
+ fn main(@builtin(global_invocation_id) id: vec3<u32>) {
21
+ let index = id.x;
22
+ let total = params.embeddingSize * params.tokenCount;
23
+ if (index >= total) {
24
+ return;
25
+ }
26
+ let x = input[index];
27
+ if (x > 0) {
28
+ output[index] = x;
29
+ }
30
+ else {
31
+ output[index] = x * 0.02;
32
+ }
33
+ }
@@ -0,0 +1,28 @@
1
+ struct Parmas {
2
+ vocabSize: u32,
3
+ count: u32
4
+ }
5
+
6
+ @group(0) @binding(0)
7
+
8
+ var<storage, read> data: array<f32>;
9
+
10
+ @group(0) @binding(1)
11
+
12
+ var<storage, read_write> result: array<f32>;
13
+
14
+ @group(0) @binding(2)
15
+
16
+ var<uniform> params: Parmas;
17
+
18
+ @compute @workgroup_size(1)
19
+
20
+ fn main(@builtin(global_invocation_id) id: vec3<u32>) {
21
+ let index = id.x;
22
+ var sum = 0.0;
23
+ for (var i = 0u; i < params.count; i++) {
24
+ sum += data[i];
25
+ }
26
+ sum /= f32(params.count);
27
+ result[index] = sum;
28
+ }
@@ -0,0 +1,36 @@
1
+ struct Params {
2
+ vocabSize: u32,
3
+ tokenCount: u32
4
+ }
5
+
6
+ @group(0) @binding(0)
7
+
8
+ var<storage, read> probs: array<f32>;
9
+
10
+ @group(0) @binding(1)
11
+
12
+ var<storage, read_write> output: array<f32>;
13
+
14
+ @group(0) @binding(2)
15
+
16
+ var<storage, read_write> targetToken: array<f32>;
17
+
18
+ @group(0) @binding(3)
19
+
20
+ var<uniform> params: Params;
21
+
22
+ @compute @workgroup_size(256)
23
+
24
+ fn main(@builtin(global_invocation_id) id: vec3<u32>) {
25
+ let index = id.x;
26
+ let token = index / params.vocabSize;
27
+ let vocabIndex = index % params.vocabSize;
28
+ let start = token * params.vocabSize;
29
+ let end = start + params.vocabSize;
30
+ var targetIndex = targetToken[token];
31
+ let total: u32 = params.tokenCount * params.vocabSize;
32
+ output[index] = probs[index];
33
+ if(vocabIndex == u32(targetIndex)){
34
+ output[index] -= 1;
35
+ }
36
+ }
@@ -0,0 +1,65 @@
1
+ struct Params {
2
+ vocabSize: u32,
3
+ tokenCount: u32,
4
+ }
5
+
6
+ @group(0) @binding(0)
7
+ var<storage, read> logits: array<f32>;
8
+
9
+ @group(0) @binding(1)
10
+ var<storage, read_write> output: array<f32>;
11
+
12
+ @group(0) @binding(2)
13
+ var<uniform> params: Params;
14
+
15
+ var<workgroup> sharedMax: array<f32, 256>;
16
+ var<workgroup> sharedSum: array<f32, 256>;
17
+
18
+ @compute @workgroup_size(256)
19
+ fn main(@builtin(workgroup_id) wg: vec3<u32>, @builtin(local_invocation_id) lid: vec3<u32>,) {
20
+ let token = wg.x;
21
+ let tid = lid.x;
22
+ if (token >= params.tokenCount) {
23
+ return;
24
+ }
25
+ let start = token * params.vocabSize;
26
+ var localMax = - 3.402823e38;
27
+ var i = tid;
28
+ while (i < params.vocabSize) {
29
+ localMax = max(localMax, logits[start + i]);
30
+ i += 256;
31
+ }
32
+ sharedMax[tid] = localMax;
33
+ workgroupBarrier();
34
+ var stride = 128u;
35
+ while (stride > 0u) {
36
+ if (tid < stride) {
37
+ sharedMax[tid] = max(sharedMax[tid], sharedMax[tid + stride]);
38
+ }
39
+ workgroupBarrier();
40
+ stride /= 2u;
41
+ }
42
+ let maxLogit = sharedMax[0];
43
+ var localSum = 0.0;
44
+ i = tid;
45
+ while (i < params.vocabSize) {
46
+ localSum += exp(logits[start + i] - maxLogit);
47
+ i += 256;
48
+ }
49
+ sharedSum[tid] = localSum;
50
+ workgroupBarrier();
51
+ stride = 128u;
52
+ while (stride > 0u) {
53
+ if (tid < stride) {
54
+ sharedSum[tid] += sharedSum[tid + stride];
55
+ }
56
+ workgroupBarrier();
57
+ stride /= 2u;
58
+ }
59
+ let sum = sharedSum[0];
60
+ i = tid;
61
+ while (i < params.vocabSize) {
62
+ output[start + i] = exp(logits[start + i] - maxLogit) / sum;
63
+ i += 256;
64
+ }
65
+ }
@@ -0,0 +1,31 @@
1
+ struct Params {
2
+ tokens: u32,
3
+ embeddingSize: u32,
4
+ }
5
+ @group(0) @binding(0)
6
+ var<storage, read> P: array<f32>;
7
+ @group(0) @binding(1)
8
+ var<storage, read> dP: array<f32>;
9
+ @group(0) @binding(2)
10
+ var<storage, read_write> output: array<f32>;
11
+ @group(0) @binding(3)
12
+ var<uniform> params: Params;
13
+
14
+ @compute @workgroup_size(256)
15
+
16
+ fn main(@builtin(global_invocation_id) id: vec3<u32>) {
17
+ let index = id.x;
18
+ let total = params.tokens * params.tokens;
19
+ if (index >= total) {
20
+ return;
21
+ }
22
+ let row = index / params.tokens;
23
+ var dot = 0.0;
24
+ for (var i = 0u; i < params.tokens; i++) {
25
+ let pos = row * params.tokens + i;
26
+ dot += P[pos] * dP[pos];
27
+ }
28
+ let p = P[index];
29
+ let dp = dP[index];
30
+ output[index] = clamp(p * (dp - dot), -1.0, 1.0);
31
+ }
@@ -0,0 +1,29 @@
1
+ struct Params {
2
+ tokens: u32,
3
+ embeddingSize: u32,
4
+ }
5
+ @group(0) @binding(0)
6
+ var<storage, read> weights: array<f32>;
7
+ @group(0) @binding(1)
8
+ var<storage, read> value: array<f32>;
9
+ @group(0) @binding(2)
10
+ var<storage, read_write> output: array<f32>;
11
+ @group(0) @binding(3)
12
+ var<uniform> params: Params;
13
+ @compute @workgroup_size(256)
14
+ fn main(@builtin(global_invocation_id) id: vec3<u32>) {
15
+ let index = id.x;
16
+ let total =params.tokens * params.embeddingSize;
17
+ if (index >= total) {
18
+ return;
19
+ }
20
+ let row = index / params.embeddingSize;
21
+ let dim = index % params.embeddingSize;
22
+ var sum = 0.0;
23
+ for (var j = 0u; j < params.tokens; j++) {
24
+ let weight = weights[row * params.tokens + j];
25
+ let v =value[j * params.embeddingSize + dim];
26
+ sum += weight * v;
27
+ }
28
+ output[index] = sum;
29
+ }
@@ -0,0 +1,30 @@
1
+ struct Params {
2
+ contextSize: u32,
3
+ embeddingSize: u32,
4
+ }
5
+ @group(0) @binding(0)
6
+ var<storage, read> dOutput: array<f32>;
7
+ @group(0) @binding(1)
8
+ var<storage, read> V: array<f32>;
9
+ @group(0) @binding(2)
10
+ var<storage, read_write> dA: array<f32>;
11
+ @group(0) @binding(3)
12
+ var<uniform> params: Params;
13
+ @compute @workgroup_size(16, 16)
14
+ fn main(@builtin(global_invocation_id) id: vec3<u32>) {
15
+ let row = id.x;
16
+ let col = id.y;
17
+ let T = params.contextSize;
18
+ let D = params.embeddingSize;
19
+ if (row >= T || col >= T) {
20
+ return;
21
+ }
22
+ var sum = 0.0;
23
+ for (var k = 0u; k < D; k++) {
24
+ let dOutputIndex = row * D + k;
25
+ let vIndex = col * D + k;
26
+ sum += dOutput[dOutputIndex] * V[vIndex];
27
+ }
28
+ let outputIndex = row * T + col;
29
+ dA[outputIndex] = sum;
30
+ }