← Back to C-Kernel-Engine Docs Doxygen Source Documentation
 
Loading...
Searching...
No Matches
recurrent_state_kernels.c File Reference
#include "ckernel_engine.h"
#include <limits.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>

Go to the source code of this file.

Functions

static int recurrent_conv_backward_extents (int history_len, int num_seqs, int num_tokens, int q_dim, int k_dim, int v_dim, int *channels_out, int *total_len_out, size_t *elements_out)
 
void recurrent_conv_state_update_backward (const float *d_conv_x, const float *d_state_out, float *d_state_in, float *d_q, float *d_k, float *d_v, int history_len, int num_seqs, int num_tokens, int q_dim, int k_dim, int v_dim)
 
void recurrent_conv_state_update_backward_workspace (const float *d_conv_x, const float *d_state_out, float *d_state_in, float *d_q, float *d_k, float *d_v, float *d_conv_total, int history_len, int num_seqs, int num_tokens, int q_dim, int k_dim, int v_dim)
 
void recurrent_conv_state_update_forward (const float *state_in, const float *q, const float *k, const float *v, float *conv_x, float *state_out, int history_len, int num_seqs, int num_tokens, int q_dim, int k_dim, int v_dim)
 

Function Documentation

◆ recurrent_conv_backward_extents()

static int recurrent_conv_backward_extents ( int  history_len,
int  num_seqs,
int  num_tokens,
int  q_dim,
int  k_dim,
int  v_dim,
int *  channels_out,
int *  total_len_out,
size_t *  elements_out 
)
static

Definition at line 58 of file recurrent_state_kernels.c.

66 {
67 if (history_len < 0 || num_seqs <= 0 || num_tokens < 0 || q_dim < 0 ||
68 k_dim < 0 || v_dim < 0 || q_dim > INT_MAX - k_dim ||
69 q_dim + k_dim > INT_MAX - v_dim || history_len > INT_MAX - num_tokens) {
70 return 0;
71 }
72 const int channels = q_dim + k_dim + v_dim;
73 const int total_len = history_len + num_tokens;
74 if (channels == 0 || total_len == 0) {
75 return 0;
76 }
77 size_t elements = (size_t)num_seqs;
78 if ((size_t)total_len > SIZE_MAX / elements) {
79 return 0;
80 }
81 elements *= (size_t)total_len;
82 if ((size_t)channels > SIZE_MAX / elements) {
83 return 0;
84 }
85 *channels_out = channels;
86 *total_len_out = total_len;
87 *elements_out = elements * (size_t)channels;
88 return 1;
89}

Referenced by recurrent_conv_state_update_backward(), and recurrent_conv_state_update_backward_workspace().

◆ recurrent_conv_state_update_backward()

void recurrent_conv_state_update_backward ( const float *  d_conv_x,
const float *  d_state_out,
float *  d_state_in,
float *  d_q,
float *  d_k,
float *  d_v,
int  history_len,
int  num_seqs,
int  num_tokens,
int  q_dim,
int  k_dim,
int  v_dim 
)

Definition at line 160 of file recurrent_state_kernels.c.

171 {
172 int channels = 0;
173 int total_len = 0;
174 size_t elements = 0;
176 history_len, num_seqs, num_tokens, q_dim, k_dim, v_dim,
177 &channels, &total_len, &elements) ||
178 elements > SIZE_MAX / sizeof(float)) {
179 return;
180 }
181 (void)channels;
182 (void)total_len;
183 float *workspace = (float *)malloc(elements * sizeof(float));
184 if (!workspace) {
185 return;
186 }
188 d_conv_x, d_state_out, d_state_in, d_q, d_k, d_v, workspace,
189 history_len, num_seqs, num_tokens, q_dim, k_dim, v_dim);
190 free(workspace);
191}
static int recurrent_conv_backward_extents(int history_len, int num_seqs, int num_tokens, int q_dim, int k_dim, int v_dim, int *channels_out, int *total_len_out, size_t *elements_out)
void recurrent_conv_state_update_backward_workspace(const float *d_conv_x, const float *d_state_out, float *d_state_in, float *d_q, float *d_k, float *d_v, float *d_conv_total, int history_len, int num_seqs, int num_tokens, int q_dim, int k_dim, int v_dim)

References recurrent_conv_backward_extents(), and recurrent_conv_state_update_backward_workspace().

◆ recurrent_conv_state_update_backward_workspace()

void recurrent_conv_state_update_backward_workspace ( const float *  d_conv_x,
const float *  d_state_out,
float *  d_state_in,
float *  d_q,
float *  d_k,
float *  d_v,
float *  d_conv_total,
int  history_len,
int  num_seqs,
int  num_tokens,
int  q_dim,
int  k_dim,
int  v_dim 
)

Definition at line 91 of file recurrent_state_kernels.c.

103 {
104 int channels = 0;
105 int total_len = 0;
106 size_t elements = 0;
107 if (!d_conv_x || !d_state_out || !d_state_in || !d_q || !d_k || !d_v ||
108 !d_conv_total || !recurrent_conv_backward_extents(
109 history_len, num_seqs, num_tokens, q_dim, k_dim, v_dim,
110 &channels, &total_len, &elements)) {
111 return;
112 }
113 if (elements > SIZE_MAX / sizeof(float)) {
114 return;
115 }
116
117 memcpy(d_conv_total, d_conv_x, elements * sizeof(float));
118
119 for (int seq = 0; seq < num_seqs; ++seq) {
120 const float *d_state_out_seq = d_state_out + (size_t) seq * (size_t) channels * (size_t) history_len;
121 float *d_conv_seq = d_conv_total + (size_t) seq * (size_t) channels * (size_t) total_len;
122 for (int ch = 0; ch < channels; ++ch) {
123 float *dst = d_conv_seq + (size_t) ch * (size_t) total_len + (size_t) num_tokens;
124 const float *src = d_state_out_seq + (size_t) ch * (size_t) history_len;
125 for (int idx = 0; idx < history_len; ++idx) {
126 dst[idx] += src[idx];
127 }
128 }
129 }
130
131 for (int seq = 0; seq < num_seqs; ++seq) {
132 const float *d_conv_seq = d_conv_total + (size_t) seq * (size_t) channels * (size_t) total_len;
133 float *d_state_in_seq = d_state_in + (size_t) seq * (size_t) channels * (size_t) history_len;
134
135 for (int ch = 0; ch < channels; ++ch) {
136 memcpy(
137 d_state_in_seq + (size_t) ch * (size_t) history_len,
138 d_conv_seq + (size_t) ch * (size_t) total_len,
139 (size_t) history_len * sizeof(float));
140 }
141
142 for (int tok = 0; tok < num_tokens; ++tok) {
143 const int row = seq * num_tokens + tok;
144 float *d_q_row = d_q + (size_t) row * (size_t) q_dim;
145 float *d_k_row = d_k + (size_t) row * (size_t) k_dim;
146 float *d_v_row = d_v + (size_t) row * (size_t) v_dim;
147 for (int col = 0; col < q_dim; ++col) {
148 d_q_row[col] = d_conv_seq[(size_t) col * (size_t) total_len + (size_t) (history_len + tok)];
149 }
150 for (int col = 0; col < k_dim; ++col) {
151 d_k_row[col] = d_conv_seq[(size_t) (q_dim + col) * (size_t) total_len + (size_t) (history_len + tok)];
152 }
153 for (int col = 0; col < v_dim; ++col) {
154 d_v_row[col] = d_conv_seq[(size_t) (q_dim + k_dim + col) * (size_t) total_len + (size_t) (history_len + tok)];
155 }
156 }
157 }
158}

References recurrent_conv_backward_extents().

Referenced by recurrent_conv_state_update_backward().

◆ recurrent_conv_state_update_forward()

void recurrent_conv_state_update_forward ( const float *  state_in,
const float *  q,
const float *  k,
const float *  v,
float *  conv_x,
float *  state_out,
int  history_len,
int  num_seqs,
int  num_tokens,
int  q_dim,
int  k_dim,
int  v_dim 
)

Definition at line 8 of file recurrent_state_kernels.c.

19 {
20 const int channels = q_dim + k_dim + v_dim;
21 const int total_len = history_len + num_tokens;
22 for (int seq = 0; seq < num_seqs; ++seq) {
23 const float *state_seq = state_in + (size_t) seq * (size_t) channels * (size_t) history_len;
24 float *conv_seq = conv_x + (size_t) seq * (size_t) channels * (size_t) total_len;
25 float *state_out_seq = state_out + (size_t) seq * (size_t) channels * (size_t) history_len;
26 for (int ch = 0; ch < channels; ++ch) {
27 memcpy(
28 conv_seq + (size_t) ch * (size_t) total_len,
29 state_seq + (size_t) ch * (size_t) history_len,
30 (size_t) history_len * sizeof(float));
31 }
32
33 for (int tok = 0; tok < num_tokens; ++tok) {
34 const int row = seq * num_tokens + tok;
35 const float *q_row = q + (size_t) row * (size_t) q_dim;
36 const float *k_row = k + (size_t) row * (size_t) k_dim;
37 const float *v_row = v + (size_t) row * (size_t) v_dim;
38 for (int col = 0; col < q_dim; ++col) {
39 conv_seq[(size_t) col * (size_t) total_len + (size_t) (history_len + tok)] = q_row[col];
40 }
41 for (int col = 0; col < k_dim; ++col) {
42 conv_seq[(size_t) (q_dim + col) * (size_t) total_len + (size_t) (history_len + tok)] = k_row[col];
43 }
44 for (int col = 0; col < v_dim; ++col) {
45 conv_seq[(size_t) (q_dim + k_dim + col) * (size_t) total_len + (size_t) (history_len + tok)] = v_row[col];
46 }
47 }
48
49 for (int ch = 0; ch < channels; ++ch) {
50 memcpy(
51 state_out_seq + (size_t) ch * (size_t) history_len,
52 conv_seq + (size_t) ch * (size_t) total_len + (size_t) num_tokens,
53 (size_t) history_len * sizeof(float));
54 }
55 }
56}

Referenced by ck_test_recurrent_conv_state_update().