| 828 | } |
| 829 | |
| 830 | class DeEmbedBlockClass extends Block { |
| 831 | constructor() { |
| 832 | super(); |
| 833 | this.name = "deembed"; |
| 834 | } |
| 835 | |
| 836 | getPipeline() { |
| 837 | const pipelineCacheKey = this.name; // No param optimization. |
| 838 | if (this.pipelineCache.has(pipelineCacheKey)) return this.pipelineCache.get(pipelineCacheKey); |
| 839 | const pipeline = this.initPipeline(this.deEmbedShader, [this.u_s_Layout, this.r_r_Layout], `${this.name}_Pipeline`); |
| 840 | this.pipelineCache.set(pipelineCacheKey, pipeline); |
| 841 | return pipeline; |
| 842 | } |
| 843 | |
| 844 | newInstance(n_embd, vocab_size, padded_vocab_size, seq_length, vocab_chunk_size, embedBuffer, deEmbeddingsBuffers) { |
| 845 | const deEmbedPipeline = this.getPipeline(); |
| 846 | const slicedEmbedOutputBuffer = this.initBuffer(["storage", "copy_to"], [n_embd]); |
| 847 | const deEmbedOutputBuffer = this.initBuffer(["map_read", "copy_to"], [vocab_size]); |
| 848 | |
| 849 | const sliceEmbedCopyCommand = { |
| 850 | flag: "copy", |
| 851 | src: embedBuffer, |
| 852 | srcOffset: this.bufferSize(seq_length - 1, n_embd), |
| 853 | dst: slicedEmbedOutputBuffer, |
| 854 | dstOffset: 0, |
| 855 | size: this.bufferSize(1, n_embd), |
| 856 | }; |
| 857 | |
| 858 | const deEmbedPasses = deEmbeddingsBuffers.flatMap((embdBuffer, i) => { |
| 859 | // Some future optimizations where we can assume that vocab_size is consistent. |
| 860 | const uniformBuffer = this.initUniform(4, [[0, new Uint32Array([vocab_chunk_size, Math.ceil(vocab_chunk_size / 4), Math.ceil(n_embd / 4)])]]); |
| 861 | const resultBuffer = this.initResultBuffer([vocab_chunk_size]); |
| 862 | const opBindGroup = this.initBindGroup(this.u_s_Layout, [uniformBuffer, resultBuffer], `${this.name}_OpG`); |
| 863 | const inputBindGroup = this.initBindGroup(this.r_r_Layout, [slicedEmbedOutputBuffer, embdBuffer], `${this.name}_InputG`); |
| 864 | const workgroups = { x: wgSize(vocab_chunk_size, 32), y: 1, z: 1 }; |
| 865 | |
| 866 | return [ |
| 867 | { |
| 868 | flag: "compute", |
| 869 | pipeline: deEmbedPipeline, |
| 870 | groups: [opBindGroup, inputBindGroup], |
| 871 | workgroups, |
| 872 | }, |
| 873 | { |
| 874 | flag: "copy", |
| 875 | src: resultBuffer, |
| 876 | srcOffset: 0, |
| 877 | dst: deEmbedOutputBuffer, |
| 878 | dstOffset: i * this.bufferSize(vocab_chunk_size), |
| 879 | size: i == deEmbeddingsBuffers.length - 1 ? this.bufferSize(vocab_chunk_size - (padded_vocab_size - vocab_size)) : this.bufferSize(vocab_chunk_size), |
| 880 | }, |
| 881 | ]; |
| 882 | }); |
| 883 | |
| 884 | return { |
| 885 | resultBuffer: deEmbedOutputBuffer, |
| 886 | passes: [sliceEmbedCopyCommand, ...deEmbedPasses], |
| 887 | }; |
nothing calls this directly
no outgoing calls
no test coverage detected