Skip to content

Commit 0e29d54

Browse files
committed
tmp: IUS cross plane loaders
1 parent d056161 commit 0e29d54

File tree

2 files changed

+796
-0
lines changed

2 files changed

+796
-0
lines changed

tests/ius_2025.c

Lines changed: 365 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,365 @@
1+
/* See LICENSE for license details. */
2+
3+
#define LIB_FN function
4+
#include "ogl_beamformer_lib.c"
5+
6+
typedef enum {
7+
#define X(type, id, ...) DASShaderKind_##type = id,
8+
DAS_SHADER_KIND_LIST
9+
#undef X
10+
DASShaderKind_Count
11+
} DASShaderKind;
12+
13+
#include <stdarg.h>
14+
#include <stdio.h>
15+
#include <stdlib.h>
16+
#include <zstd.h>
17+
18+
global i32 g_output_points[4] = {512, 1, 1024, 1};
19+
global v2 g_axial_extent = {{ 5e-3f, 55e-3f}};
20+
global v2 g_lateral_extent = {{-27e-3f, 27e-3f}};
21+
global f32 g_f_number = 0.5f;
22+
23+
#define ZEMP_BP_MAGIC (uint64_t)0x5042504D455AFECAull
24+
typedef struct {
25+
u64 magic;
26+
u32 version;
27+
u16 decode_mode;
28+
u16 beamform_mode;
29+
u32 raw_data_dim[4];
30+
u32 decoded_data_dim[4];
31+
f32 xdc_element_pitch[2];
32+
f32 xdc_transform[16]; /* NOTE: column major order */
33+
i16 channel_mapping[256];
34+
f32 transmit_angles[256];
35+
f32 focal_depths[256];
36+
i16 sparse_elements[256];
37+
i16 hadamard_rows[256];
38+
f32 speed_of_sound;
39+
f32 center_frequency;
40+
f32 sampling_frequency;
41+
f32 time_offset;
42+
i32 transmit_mode;
43+
} zemp_bp_v1;
44+
45+
#define die(...) die_((char *)__func__, __VA_ARGS__)
46+
function no_return void
47+
die_(char *function_name, char *format, ...)
48+
{
49+
if (function_name)
50+
fprintf(stderr, "%s: ", function_name);
51+
52+
va_list ap;
53+
54+
va_start(ap, format);
55+
vfprintf(stderr, format, ap);
56+
va_end(ap);
57+
58+
os_exit(1);
59+
}
60+
61+
#if OS_LINUX
62+
63+
#include <fcntl.h>
64+
#include <sys/stat.h>
65+
#include <unistd.h>
66+
67+
function void os_init_timer(void) { }
68+
69+
function f64
70+
os_get_time(void)
71+
{
72+
f64 result = (f64)os_get_timer_counter() / (f64)os_get_timer_frequency();
73+
return result;
74+
}
75+
76+
function s8
77+
os_read_file_simp(char *fname)
78+
{
79+
s8 result;
80+
i32 fd = open(fname, O_RDONLY);
81+
if (fd < 0)
82+
die("couldn't open file: %s\n", fname);
83+
84+
struct stat st;
85+
if (stat(fname, &st) < 0)
86+
die("couldn't stat file\n");
87+
88+
result.len = st.st_size;
89+
result.data = malloc((uz)st.st_size);
90+
if (!result.data)
91+
die("couldn't alloc space for reading\n");
92+
93+
iz rlen = read(fd, result.data, (u32)st.st_size);
94+
close(fd);
95+
96+
if (rlen != st.st_size)
97+
die("couldn't read file: %s\n", fname);
98+
99+
return result;
100+
}
101+
102+
#elif OS_WINDOWS
103+
104+
global w32_context os_context;
105+
106+
function void
107+
os_init_timer(void)
108+
{
109+
os_context.timer_frequency = os_get_timer_frequency();
110+
}
111+
112+
function f64
113+
os_get_time(void)
114+
{
115+
f64 result = (f64)os_get_timer_counter() / (f64)os_context.timer_frequency;
116+
return result;
117+
}
118+
119+
function s8
120+
os_read_file_simp(char *fname)
121+
{
122+
s8 result;
123+
iptr h = CreateFileA(fname, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0);
124+
if (h == INVALID_FILE)
125+
die("couldn't open file: %s\n", fname);
126+
127+
w32_file_info fileinfo;
128+
if (!GetFileInformationByHandle(h, &fileinfo))
129+
die("couldn't get file info\n", stderr);
130+
131+
result.len = fileinfo.nFileSizeLow;
132+
result.data = malloc(fileinfo.nFileSizeLow);
133+
if (!result.data)
134+
die("couldn't alloc space for reading\n");
135+
136+
i32 rlen = 0;
137+
if (!ReadFile(h, result.data, (i32)fileinfo.nFileSizeLow, &rlen, 0) && rlen != (i32)fileinfo.nFileSizeLow)
138+
die("couldn't read file: %s\n", fname);
139+
CloseHandle(h);
140+
141+
return result;
142+
}
143+
144+
#else
145+
#error Unsupported Platform
146+
#endif
147+
148+
function void
149+
stream_ensure_termination(Stream *s, u8 byte)
150+
{
151+
b32 found = 0;
152+
if (!s->errors && s->widx > 0)
153+
found = s->data[s->widx - 1] == byte;
154+
if (!found) {
155+
s->errors |= s->cap - 1 < s->widx;
156+
if (!s->errors)
157+
s->data[s->widx++] = byte;
158+
}
159+
}
160+
161+
function void *
162+
decompress_zstd_data(s8 raw)
163+
{
164+
uz requested_size = ZSTD_getFrameContentSize(raw.data, (uz)raw.len);
165+
void *out = malloc(requested_size);
166+
if (out) {
167+
uz decompressed = ZSTD_decompress(out, requested_size, raw.data, (uz)raw.len);
168+
if (decompressed != requested_size) {
169+
free(out);
170+
out = 0;
171+
}
172+
}
173+
return out;
174+
}
175+
176+
function zemp_bp_v1 *
177+
read_zemp_bp_v1(u8 *path)
178+
{
179+
s8 raw = os_read_file_simp((char *)path);
180+
zemp_bp_v1 *result = 0;
181+
if (raw.len == sizeof(zemp_bp_v1) && *(u64 *)raw.data == ZEMP_BP_MAGIC) {
182+
if (((zemp_bp_v1 *)raw.data)->version == 1)
183+
result = (zemp_bp_v1 *)raw.data;
184+
}
185+
return result;
186+
}
187+
188+
function void
189+
beamformer_parameters_from_zemp_bp_v1(BeamformerParameters *out, zemp_bp_v1 *zbp)
190+
{
191+
mem_copy(out->xdc_transform, zbp->xdc_transform, sizeof(out->xdc_transform));
192+
mem_copy(out->xdc_element_pitch, zbp->xdc_element_pitch, sizeof(out->xdc_element_pitch));
193+
mem_copy(out->raw_data_dimensions, zbp->raw_data_dim, sizeof(out->raw_data_dimensions));
194+
195+
out->sample_count = zbp->decoded_data_dim[0];
196+
out->channel_count = zbp->decoded_data_dim[1];
197+
out->acquisition_count = zbp->decoded_data_dim[2];
198+
out->transmit_mode = (u8)((zbp->transmit_mode & 2) >> 1);
199+
out->receive_mode = (u8)((zbp->transmit_mode & 1) >> 0);
200+
out->decode = (u8)zbp->decode_mode;
201+
out->das_shader_id = zbp->beamform_mode;
202+
out->time_offset = zbp->time_offset;
203+
out->sampling_frequency = zbp->sampling_frequency;
204+
out->demodulation_frequency = zbp->center_frequency;
205+
out->speed_of_sound = zbp->speed_of_sound;
206+
}
207+
208+
#define shift_n(v, c, n) v += n, c -= n
209+
#define shift(v, c) shift_n(v, c, 1)
210+
211+
function void
212+
usage(char *argv0)
213+
{
214+
die("%s base_path\n"
215+
, argv0);
216+
}
217+
218+
function i16 *
219+
decompress_data_at_work_index(Stream *path_base, u32 index)
220+
{
221+
stream_append_byte(path_base, '_');
222+
stream_append_u64_width(path_base, index, 2);
223+
stream_append_s8(path_base, s8(".zst"));
224+
stream_ensure_termination(path_base, 0);
225+
226+
s8 compressed_data = os_read_file_simp((char *)path_base->data);
227+
i16 *result = decompress_zstd_data(compressed_data);
228+
if (!result)
229+
die("failed to decompress data: %s\n", path_base->data);
230+
free(compressed_data.data);
231+
232+
return result;
233+
}
234+
235+
function b32
236+
send_frame_at(i16 *restrict i16_data, BeamformerParameters *restrict bp, BeamformerViewPlaneTag tag, u8 block)
237+
{
238+
u32 data_size = bp->raw_data_dimensions[0] * bp->raw_data_dimensions[1] * sizeof(i16);
239+
b32 result = beamformer_push_data_with_compute(i16_data, data_size, tag, block);
240+
if (!result) printf("lib error: %s\n", beamformer_get_last_error_string());
241+
242+
return result;
243+
}
244+
245+
function void
246+
execute_study_with_block(s8 study, Stream path, f32 chirp_length, BeamformerViewPlaneTag tag, u8 block)
247+
{
248+
fprintf(stderr, "showing: %.*s\n", (i32)study.len, study.data);
249+
250+
stream_append_s8(&path, study);
251+
stream_ensure_termination(&path, OS_PATH_SEPARATOR_CHAR);
252+
stream_append_s8(&path, study);
253+
i32 path_work_index = path.widx;
254+
255+
stream_append_s8(&path, s8(".bp"));
256+
stream_ensure_termination(&path, 0);
257+
258+
zemp_bp_v1 *zbp = read_zemp_bp_v1(path.data);
259+
if (!zbp) die("failed to unpack parameters file\n");
260+
261+
BeamformerParameters bp = {0};
262+
beamformer_parameters_from_zemp_bp_v1(&bp, zbp);
263+
264+
mem_copy(bp.output_points, g_output_points, sizeof(bp.output_points));
265+
bp.output_points[3] = 1;
266+
267+
bp.output_min_coordinate[0] = g_lateral_extent.x;
268+
bp.output_min_coordinate[1] = 0;
269+
bp.output_min_coordinate[2] = g_axial_extent.x;
270+
271+
bp.output_max_coordinate[0] = g_lateral_extent.y;
272+
bp.output_max_coordinate[1] = 0;
273+
bp.output_max_coordinate[2] = g_axial_extent.y;
274+
275+
bp.f_number = g_f_number;
276+
bp.beamform_plane = tag;
277+
bp.interpolate = 1;
278+
279+
bp.decimation_rate = 1;
280+
281+
bp.demodulation_frequency = bp.sampling_frequency / 4;
282+
bp.sampling_mode = BeamformerSamplingMode_4X;
283+
284+
BeamformerFilterParameters kaiser = {0};
285+
kaiser.Kaiser.beta = 5.65f;
286+
kaiser.Kaiser.cutoff_frequency = 2.0e6f;
287+
kaiser.Kaiser.length = 36;
288+
289+
beamformer_create_filter(BeamformerFilterKind_Kaiser, (f32 *)&kaiser, sizeof(kaiser.Kaiser) / sizeof(f32),
290+
bp.sampling_frequency / 2, 0, 0, block);
291+
beamformer_set_pipeline_stage_parameters_at(0, 0, block);
292+
293+
#if 0
294+
BeamformerFilterParameters matched = {0};
295+
typeof(matched.MatchedChirp) *mp = &matched.MatchedChirp;
296+
mp->duration = chirp_length;
297+
mp->min_frequency = 2.9e6 - zbp->demodulation_frequency;
298+
mp->max_frequency = 6.0e6 - zbp->demodulation_frequency;
299+
300+
beamformer_create_filter(BeamformerFilterKind_MatchedChirp, (f32 *)mp,
301+
sizeof(matched.MatchedChirp) / sizeof(f32),
302+
bp.sampling_frequency / 2, 1, 0, block);
303+
beamformer_set_pipeline_stage_parameters_at(0, 0, block);
304+
#endif
305+
306+
if (zbp->beamform_mode == DASShaderKind_UHERCULES || zbp->beamform_mode == DASShaderKind_UFORCES)
307+
beamformer_push_sparse_elements_at(zbp->sparse_elements, bp.acquisition_count, block);
308+
309+
{
310+
alignas(64) v2 focal_vectors[countof(zbp->focal_depths)];
311+
for (u32 i = 0; i < countof(zbp->focal_depths); i++)
312+
focal_vectors[i] = (v2){{zbp->transmit_angles[i], zbp->focal_depths[i]}};
313+
beamformer_push_focal_vectors_at((f32 *)focal_vectors, countof(focal_vectors), block);
314+
}
315+
316+
beamformer_push_channel_mapping_at(zbp->channel_mapping, countof(zbp->channel_mapping), block);
317+
beamformer_push_parameters_at(&bp, block);
318+
319+
i32 shader_stages[16];
320+
u32 shader_stage_count = 0;
321+
shader_stages[shader_stage_count++] = BeamformerShaderKind_Demodulate;
322+
shader_stages[shader_stage_count++] = BeamformerShaderKind_Decode;
323+
shader_stages[shader_stage_count++] = BeamformerShaderKind_DAS;
324+
325+
beamformer_push_pipeline_at(shader_stages, shader_stage_count, BeamformerDataKind_Int16, block);
326+
327+
stream_reset(&path, path_work_index);
328+
i16 *data = decompress_data_at_work_index(&path, 0);
329+
330+
send_frame_at(data, &bp, tag, block);
331+
332+
free(zbp);
333+
free(data);
334+
}
335+
336+
extern i32
337+
main(i32 argc, char *argv[])
338+
{
339+
if (argc != 2) usage(argv[0]);
340+
341+
os_init_timer();
342+
343+
if (!beamformer_set_global_timeout(1000)) die((char *)beamformer_get_last_error_string());
344+
if (!beamformer_reserve_parameter_blocks(2)) die((char *)beamformer_get_last_error_string());
345+
346+
Arena arena = os_alloc_arena(KB(8));
347+
Stream path = arena_stream(arena);
348+
stream_append_s8(&path, c_str_to_s8(argv[1]));
349+
stream_ensure_termination(&path, OS_PATH_SEPARATOR_CHAR);
350+
351+
execute_study_with_block(s8("250319_A06_7.80MHz_ATS539_Cyst_FORCES-TxRow"), path, 0, BeamformerViewPlaneTag_YZ, 0);
352+
execute_study_with_block(s8("250319_A06_7.80MHz_ATS539_Cyst_FORCES-TxColumn"), path, 0, BeamformerViewPlaneTag_XZ, 1);
353+
fprintf(stderr, "press enter to continue...");
354+
if (fgetc(stdin) == EOF) return 0;
355+
356+
execute_study_with_block(s8("250319_A06_7.80MHz_ATS539_Cyst_TPW-128-TxColumn"), path, 0, BeamformerViewPlaneTag_YZ, 0);
357+
execute_study_with_block(s8("250319_A06_7.80MHz_ATS539_Cyst_TPW-128-TxColumn"), path, 0, BeamformerViewPlaneTag_XZ, 1);
358+
fprintf(stderr, "press enter to continue...");
359+
if (fgetc(stdin) == EOF) return 0;
360+
361+
execute_study_with_block(s8("250319_A06_7.80MHz_ATS539_Cyst_VLS-128-TxColumn"), path, 0, BeamformerViewPlaneTag_YZ, 0);
362+
execute_study_with_block(s8("250319_A06_7.80MHz_ATS539_Cyst_VLS-128-TxColumn"), path, 0, BeamformerViewPlaneTag_XZ, 1);
363+
364+
return 0;
365+
}

0 commit comments

Comments
 (0)