hadamard.glsl (2457B)
1 /* See LICENSE for license details. */ 2 layout(local_size_x = 32, local_size_y = 32, local_size_z = 1) in; 3 4 layout(std430, binding = 1) readonly restrict buffer buffer_1 { 5 int rf_data[]; 6 }; 7 8 layout(std430, binding = 2) writeonly restrict buffer buffer_2 { 9 vec2 out_data[]; 10 }; 11 12 layout(std430, binding = 3) readonly restrict buffer buffer_3 { 13 int hadamard[]; 14 }; 15 16 void main() 17 { 18 /* NOTE: each invocation takes a time sample and a receive channel. 19 * It first maps the column to the correct column in the rf data then 20 * does the dot product with the equivalent row of the hadamard matrix. 21 * The result is stored to the equivalent row, column index of the output. 22 */ 23 uint time_sample = gl_GlobalInvocationID.x; 24 uint channel = gl_GlobalInvocationID.y; 25 uint acq = gl_GlobalInvocationID.z; 26 27 /* NOTE: offsets for storing the results in the output data */ 28 uint out_off = dec_data_dim.x * dec_data_dim.y * acq + dec_data_dim.x * channel + time_sample; 29 30 /* NOTE: channel mapping is stored as u16s so we must do this to extract the final value */ 31 uint ch_array_idx = ((channel + channel_offset) / 8); 32 uint ch_vec_idx = ((channel + channel_offset) % 8) / 2; 33 uint ch_elem_lfs = ((channel + channel_offset) & 1u) * 16; 34 uint rf_channel = (channel_mapping[ch_array_idx][ch_vec_idx] << ch_elem_lfs) >> 16; 35 36 /* NOTE: stride is the number of samples between acquistions; off is the 37 * index of the first acquisition for this channel and time sample */ 38 uint rf_stride = dec_data_dim.x; 39 uint rf_off = rf_raw_dim.x * rf_channel + time_sample; 40 41 /* NOTE: rf_data index and stride considering the data is i16 not i32 */ 42 uint ridx = rf_off / 2; 43 uint ridx_delta = rf_stride / 2; 44 45 /* NOTE: rf_data is i16 so each access grabs two time samples at time. 46 * We need to shift arithmetically (maintaining the sign) to get the 47 * desired element. If the time sample is even we take the upper half 48 * and if its odd we take the lower half. */ 49 uint lfs = ((~time_sample) & 1u) * 16; 50 51 /* NOTE: Compute N-D dot product */ 52 int sum = 0; 53 if (decode == 1) { 54 /* NOTE: offset to get the correct column in hadamard matrix */ 55 uint hoff = dec_data_dim.z * acq; 56 57 for (int i = 0; i < dec_data_dim.z; i++) { 58 int data = (rf_data[ridx] << lfs) >> 16; 59 sum += hadamard[hoff + i] * data; 60 ridx += ridx_delta; 61 } 62 } else { 63 ridx += ridx_delta * acq; 64 sum = (rf_data[ridx] << lfs) >> 16; 65 } 66 out_data[out_off] = vec2(float(sum), 0); 67 }