Skip to content

Commit 00a7f0f

Browse files
committed
add helper test scripts
1 parent 3c5b89d commit 00a7f0f

File tree

4 files changed

+389
-0
lines changed

4 files changed

+389
-0
lines changed

helpers/build.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#!/bin/sh
2+
3+
cc -march=native -O2 send_params.c -o helper

helpers/export_bp.m

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
function [] = export_bp(output, bp)
2+
3+
fd = fopen(output, "w");
4+
5+
print_u32 = @(fd, u32) fprintf(fd, "%d", u32);
6+
print_f32 = @(fd, f32) fprintf(fd, "%e", f32);
7+
print_v2 = @(fd, v2) fprintf(fd, "{.x = %0.03f, .y = %0.03f}", v2.x, v2.y);
8+
print_uv2 = @(fd, uv2) fprintf(fd, "{.x = %d, .y = %d}", uv2.x, uv2.y);
9+
print_uv4 = @(fd, uv4) fprintf(fd, "{.x = %d, .y = %d, .z = %d, .w = %d}", uv4.x, uv4.y, uv4.z, uv4.w);
10+
%print_arr = @(fd, arr) fprintf(fd, "{"); fprintf(fd, " %d,", arr); fprintf(fd, "}");
11+
12+
fprintf(fd, "static BeamformerParameters bp = {\n");
13+
fprintf(fd, ".channel_mapping = {"); fprintf(fd, " %d,", bp.channel_mapping); fprintf(fd, "},\n");
14+
fprintf(fd, ".uforces_channels = {"); fprintf(fd, " %d,", bp.uforces_channels); fprintf(fd, "},\n");
15+
fprintf(fd, ".lpf_coefficients = {"); fprintf(fd, " %e,", bp.lpf_coefficients); fprintf(fd, "},\n");
16+
fprintf(fd, ".dec_data_dim = "); print_uv4(fd, bp.dec_data_dim); fprintf(fd, ",\n");
17+
fprintf(fd, ".output_points = "); print_uv4(fd, bp.output_points); fprintf(fd, ",\n");
18+
fprintf(fd, ".rf_raw_dim = "); print_uv2(fd, bp.rf_raw_dim); fprintf(fd, ",\n");
19+
fprintf(fd, ".output_min_xz = "); print_v2(fd, bp.output_min_xz); fprintf(fd, ",\n");
20+
fprintf(fd, ".output_max_xz = "); print_v2(fd, bp.output_max_xz); fprintf(fd, ",\n");
21+
fprintf(fd, ".xdc_min_xy = "); print_v2(fd, bp.xdc_min_xy); fprintf(fd, ",\n");
22+
fprintf(fd, ".xdc_max_xy = "); print_v2(fd, bp.xdc_max_xy); fprintf(fd, ",\n");
23+
fprintf(fd, ".channel_offset = "); print_u32(fd, bp.channel_offset); fprintf(fd, ",\n");
24+
fprintf(fd, ".lpf_order = "); print_u32(fd, bp.lpf_order); fprintf(fd, ",\n");
25+
fprintf(fd, ".speed_of_sound = "); print_f32(fd, bp.speed_of_sound); fprintf(fd, ",\n");
26+
fprintf(fd, ".sampling_frequency = "); print_f32(fd, bp.sampling_frequency); fprintf(fd, ",\n");
27+
fprintf(fd, ".center_frequency = "); print_f32(fd, bp.center_frequency); fprintf(fd, ",\n");
28+
fprintf(fd, ".focal_depth = "); print_f32(fd, bp.focal_depth); fprintf(fd, ",\n");
29+
fprintf(fd, ".time_offset = "); print_f32(fd, bp.time_offset); fprintf(fd, ",\n");
30+
fprintf(fd, "};\n");
31+
32+
fclose(fd);
33+
34+
end

helpers/load_vrs.m

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
clear all;
2+
3+
openProject("../others/Ultrasound-Beamforming/Ultrasound-Beamforming.prj");
4+
5+
vrs_path = "/tmp/downloads";
6+
vrs_prefix = "240723_ATS539_Contrast_uFORCES-32-TxRow";
7+
%vrs_prefix = "240723_ATS539_Resolution_uFORCES-32-TxRow";
8+
%vrs_prefix = "240723_ATS539_Resolution_FORCES-TxRow";
9+
%vrs_prefix = "240723_ATS539_Contrast_FORCES-TxRow";
10+
vrs_name = vrs_prefix + "_Intensity_03.vrs";
11+
12+
pipe_name = '/tmp/beamformer_data_fifo';
13+
smem_name = '/ogl_beamformer_parameters';
14+
15+
vrs = VRSFile(fullfile(vrs_path, vrs_name));
16+
data = vrs.GetData();
17+
18+
load(fullfile(vrs_path, "postEnv.mat"), "Trans", "Receive", "Resource", "TW");
19+
load(fullfile(vrs_path, "preEnv.mat"), "sparseElements", "scan");
20+
21+
receive = Receive([Receive.bufnum] == 1);
22+
receive_orientation = scan.TransmitEvents(1).ImagingPattern.ReceiveOrientation;
23+
24+
bp.output_min_xz = struct('x', -21.5e-3, 'y', 15e-3);
25+
bp.output_max_xz = struct('x', 21.5e-3, 'y', 60e-3);
26+
27+
bp.output_points.x = 256;
28+
bp.output_points.y = 1024;
29+
bp.output_points.z = 1;
30+
bp.output_points.w = 0;
31+
32+
bp.rf_raw_dim = struct('x', size(data, 1), 'y', size(data, 2));
33+
bp.dec_data_dim.x = max(1 + [receive.endSample] - [receive.startSample], [], "all");
34+
bp.dec_data_dim.y = 128;
35+
bp.dec_data_dim.z = max([receive.acqNum]);
36+
bp.dec_data_dim.w = 0;
37+
38+
bp.sampling_frequency = receive(1).samplesPerWave * Trans.frequency(1) * 1e6;
39+
bp.center_frequency = Trans.frequency * 1e6;
40+
bp.speed_of_sound = Resource.Parameters.speedOfSound;
41+
42+
bp.time_offset = TW(1).Parameters(3) / bp.center_frequency;
43+
44+
bp.channel_mapping = Trans.ConnectorES - 1;
45+
if (exist('sparseElements'))
46+
bp.uforces_channels = sparseElements(1:length(sparseElements)/2) - 1;
47+
else
48+
bp.uforces_channels = 1:128 - 1;
49+
end
50+
51+
bp.channel_offset = 0 + 128 * receive_orientation.Contains(tobe.Orientation.Column);
52+
53+
die_size = scan.Die.GetSize();
54+
bp.xdc_min_xy = struct('x', -die_size(1) / 2, 'y', -die_size(2) / 2);
55+
bp.xdc_max_xy = struct('x', die_size(1) / 2, 'y', die_size(2) / 2);
56+
57+
bp.focal_depth = 0;
58+
59+
% NOTE: effectively disables lpf
60+
%bp.lpf_order = 0;
61+
%bp.lpf_coefficients = 1;
62+
%bp.center_frequency = 0;
63+
64+
bp.lpf_coefficients = [0.00150425278148001, 0.00663627704153171, 0.0183467992553614, 0.0386288031294497, ...
65+
0.0668063601697744, 0.0985254555140267, 0.126486796857306, 0.142954931338469, ...
66+
0.142954931338469, 0.126486796857306, 0.0985254555140267, 0.0668063601697744, ...
67+
0.0386288031294497, 0.0183467992553614, 0.00663627704153171, 0.00150425278148001];
68+
bp.lpf_order = numel(bp.lpf_coefficients) - 1;
69+
70+
loadlibrary('ogl_beamformer_lib')
71+
calllib('ogl_beamformer_lib', 'set_beamformer_parameters', smem_name, bp)
72+
%while (true)
73+
%tic()
74+
calllib('ogl_beamformer_lib', 'send_data', pipe_name, smem_name, data, bp.rf_raw_dim)
75+
%toc()
76+
%end
77+
unloadlibrary('ogl_beamformer_lib')

helpers/send_params.c

Lines changed: 275 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,275 @@
1+
#include <stdarg.h>
2+
#include <stddef.h>
3+
#include <stdint.h>
4+
#include <stdio.h>
5+
#include <stdlib.h>
6+
#include <string.h>
7+
#include <time.h>
8+
9+
typedef uint8_t u8;
10+
typedef int16_t i16;
11+
typedef int32_t i32;
12+
typedef uint32_t u32;
13+
typedef uint32_t b32;
14+
typedef float f32;
15+
typedef double f64;
16+
typedef ptrdiff_t size;
17+
18+
typedef struct { f32 x, y; } v2;
19+
typedef struct { u32 x, y; } uv2;
20+
typedef struct { u32 x, y, z, w; } uv4;
21+
22+
#include "../beamformer_parameters.h"
23+
24+
typedef struct {
25+
BeamformerParameters raw;
26+
b32 upload;
27+
} BeamformerParametersFull;
28+
29+
#include "/tmp/downloads/240723_ATS539_Resolution_uFORCES-32-TxRow_bp_inc.h"
30+
//#include "/tmp/downloads/240723_ATS539_Contrast_FORCES-TxRow_bp_inc.h"
31+
//#include "/tmp/downloads/240723_ATS539_Resolution_FORCES-TxRow_bp_inc.h"
32+
33+
#define GIGABYTE (1024UL * 1024UL * 1024UL)
34+
35+
static void __attribute__((noreturn))
36+
die(char *fmt, ...)
37+
{
38+
va_list ap;
39+
40+
va_start(ap, fmt);
41+
vfprintf(stderr, fmt, ap);
42+
va_end(ap);
43+
44+
exit(1);
45+
}
46+
47+
48+
#if defined(__unix__)
49+
#include <fcntl.h>
50+
#include <sys/mman.h>
51+
#include <sys/stat.h>
52+
#include <unistd.h>
53+
54+
#define OS_PIPE_NAME "/tmp/beamformer_data_fifo"
55+
#define OS_SMEM_NAME "/ogl_beamformer_parameters"
56+
57+
#define OS_INVALID_FILE (-1)
58+
typedef i32 os_file;
59+
typedef struct {
60+
os_file file;
61+
char *name;
62+
} os_pipe;
63+
#elif defined(_WIN32)
64+
#include <windows.h>
65+
66+
#define OS_PIPE_NAME "\\\\.\\pipe\\beamformer_data_fifo"
67+
#define OS_SMEM_NAME "Local\\ogl_beamformer_parameters"
68+
69+
#define OS_INVALID_FILE (INVALID_HANDLE_VALUE)
70+
typedef HANDLE os_file;
71+
typedef struct {
72+
os_file file;
73+
char *name;
74+
} os_pipe;
75+
76+
#else
77+
#error Unsupported Platform
78+
#endif
79+
80+
static volatile BeamformerParametersFull *g_bp;
81+
static os_pipe g_pipe = {.file = OS_INVALID_FILE};
82+
83+
#if defined(__unix__)
84+
static void *
85+
os_read_file(char *fname)
86+
{
87+
i32 fd = open(fname, O_RDONLY);
88+
if (fd < 0)
89+
die("os_read_file: couldn't open file: %s\n", fname);
90+
91+
struct stat st;
92+
if (stat(fname, &st) < 0)
93+
die("os_read_file: couldn't stat file\n");
94+
95+
void *out = malloc(st.st_size);
96+
if (!out)
97+
die("os_read_file: couldn't alloc space for reading\n");
98+
99+
size rlen = read(fd, out, st.st_size);
100+
close(fd);
101+
102+
if (rlen != st.st_size)
103+
die("os_read_file: couldn't read file: %s\n", fname);
104+
105+
return out;
106+
}
107+
108+
static os_pipe
109+
os_open_named_pipe(char *name)
110+
{
111+
return (os_pipe){.file = open(name, O_WRONLY), .name = name};
112+
}
113+
114+
static size
115+
os_write_to_pipe(os_pipe p, void *data, size len)
116+
{
117+
size written = 0, w = 0;
118+
do {
119+
written += w;
120+
w = write(p.file, data, len);
121+
} while(written != len && w != 0);
122+
return written;
123+
}
124+
125+
static BeamformerParametersFull *
126+
os_open_shared_memory_area(char *name)
127+
{
128+
i32 fd = shm_open(name, O_RDWR, S_IRUSR|S_IWUSR);
129+
if (fd == -1)
130+
return NULL;
131+
132+
BeamformerParametersFull *new;
133+
new = mmap(NULL, sizeof(*new), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
134+
close(fd);
135+
136+
if (new == MAP_FAILED)
137+
return NULL;
138+
139+
return new;
140+
}
141+
142+
#elif defined(_WIN32)
143+
144+
static void *
145+
os_read_file(char *fname)
146+
{
147+
HANDLE h = CreateFileA(fname, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0);
148+
if (h == INVALID_HANDLE_VALUE)
149+
die("os_read_file: couldn't open file: %s\n", fname);
150+
151+
BY_HANDLE_FILE_INFORMATION fileinfo;
152+
if (!GetFileInformationByHandle(h, &fileinfo))
153+
die("os_get_file_stats: couldn't get file info\n", stderr);
154+
155+
void *out = malloc(fileinfo.nFileSizeLow);
156+
if (!out)
157+
die("os_read_file: couldn't alloc space for reading\n");
158+
159+
DWORD rlen = 0;
160+
if (!ReadFile(h, out, fileinfo.nFileSizeLow, &rlen, 0) && rlen != fileinfo.nFileSizeLow)
161+
die("os_read_file: couldn't read file: %s\n", fname);
162+
CloseHandle(h);
163+
164+
return out;
165+
}
166+
167+
static os_pipe
168+
os_open_named_pipe(char *name)
169+
{
170+
HANDLE pipe = CreateFileA(name, GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
171+
return (os_pipe){.file = pipe, .name = name};
172+
}
173+
174+
static size
175+
os_write_to_pipe(os_pipe p, void *data, size len)
176+
{
177+
DWORD bytes_written;
178+
WriteFile(p.file, data, len, &bytes_written, 0);
179+
return bytes_written;
180+
}
181+
182+
static BeamformerParametersFull *
183+
os_open_shared_memory_area(char *name)
184+
{
185+
HANDLE h = OpenFileMappingA(FILE_MAP_ALL_ACCESS, FALSE, name);
186+
if (h == OS_INVALID_FILE)
187+
return NULL;
188+
189+
BeamformerParametersFull *new;
190+
new = MapViewOfFile(h, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(*new));
191+
CloseHandle(h);
192+
193+
return new;
194+
}
195+
#endif
196+
197+
static void
198+
check_shared_memory(char *name)
199+
{
200+
if (g_bp)
201+
return;
202+
g_bp = os_open_shared_memory_area(name);
203+
if (g_bp == NULL)
204+
die("failed to open shared memory\n");
205+
}
206+
207+
static size
208+
send_data(char *pipe_name, char *shm_name, i16 *data, uv2 data_dim)
209+
{
210+
if (g_pipe.file == OS_INVALID_FILE) {
211+
g_pipe = os_open_named_pipe(pipe_name);
212+
if (g_pipe.file == OS_INVALID_FILE) {
213+
printf("Failed to open named pipe: %s\n", pipe_name);
214+
exit(1);
215+
}
216+
}
217+
218+
check_shared_memory(shm_name);
219+
/* TODO: this probably needs a mutex around it if we want to change it here */
220+
g_bp->raw.rf_raw_dim = data_dim;
221+
size data_size = data_dim.x * data_dim.y * sizeof(i16);
222+
size written = os_write_to_pipe(g_pipe, data, data_size);
223+
if (written != data_size)
224+
printf("Failed to write full data to pipe: wrote: %ld/%ld\n", written, data_size);
225+
g_bp->upload = 1;
226+
227+
return written;
228+
}
229+
230+
231+
static void
232+
set_beamformer_parameters(char *shm_name, BeamformerParameters *new_bp)
233+
{
234+
check_shared_memory(shm_name);
235+
236+
if (!g_bp)
237+
return;
238+
239+
u8 *src = (u8 *)new_bp, *dest = (u8 *)&g_bp->raw;
240+
for (size i = 0; i < sizeof(BeamformerParameters); i++)
241+
dest[i] = src[i];
242+
g_bp->upload = 1;
243+
}
244+
245+
int
246+
main(i32 argc, char *argv[])
247+
{
248+
if (!strcmp(argv[1], "params")) {
249+
set_beamformer_parameters(OS_SMEM_NAME, &bp);
250+
} else if (!strcmp(argv[1], "data")) {
251+
if (argc != 3)
252+
die("usage: %s data file_name\n", argv[0]);
253+
i16 *data = os_read_file(argv[2]);
254+
if (!data)
255+
die("failed to read data: %s!\n", argv[2]);
256+
size written = 0;
257+
i32 fcount = 0;
258+
f32 frame_time = 0;
259+
clock_t timestamp;
260+
while (1) {
261+
if (fcount == 5) {
262+
printf("Last Frame Time: %0.03f [ms]; Throughput: %0.03f [GB/s]\n",
263+
frame_time * 1e3,
264+
(double)(written)/(frame_time * (double)(GIGABYTE)));
265+
fcount = 0;
266+
}
267+
timestamp = clock();
268+
written = send_data(OS_PIPE_NAME, OS_SMEM_NAME, data, bp.rf_raw_dim);
269+
frame_time = (f32)(clock() - timestamp)/(f32)CLOCKS_PER_SEC;
270+
fcount++;
271+
}
272+
}
273+
274+
return 0;
275+
}

0 commit comments

Comments
 (0)