Skip to content

Feature/blocking test #281

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 23 commits into from
May 27, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Undo probes and use xsim for tests
  • Loading branch information
xhuw committed May 19, 2025
commit d88f3e70893a5231a98cf512ea2f72c955b68c56
23 changes: 0 additions & 23 deletions lib_audio_dsp/api/stages/adsp_pipeline.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,6 @@ typedef struct
/// @privatesection
adsp_mux_t input_mux;
adsp_mux_t output_mux;
bool probe;
int probe_id;
} adsp_pipeline_t;

/// Pass samples into the DSP pipeline.
Expand All @@ -86,11 +84,6 @@ typedef struct
/// of samples large enough to pass to the stage that it is connected to.
static inline void adsp_pipeline_source(adsp_pipeline_t *adsp, int32_t **data)
{
int probe_id = adsp->probe_id;
bool probe = adsp->probe;
if(probe) {
xscope_int(probe_id, 2);
}
for (size_t chan_id = 0; chan_id < adsp->input_mux.n_chan; chan_id++)
{
adsp_mux_elem_t cfg = adsp->input_mux.chan_cfg[chan_id];
Expand All @@ -109,11 +102,6 @@ static inline void adsp_pipeline_source(adsp_pipeline_t *adsp, int32_t **data)
/// of samples large enough to pass to the stage that it is connected to.
static inline void adsp_pipeline_sink(adsp_pipeline_t *adsp, int32_t **data)
{
int probe_id = adsp->probe_id;
bool probe = adsp->probe;
if(probe) {
xscope_int(probe_id, 1);
}
for (size_t chan_id = 0; chan_id < adsp->output_mux.n_chan; chan_id++)
{
adsp_mux_elem_t cfg = adsp->output_mux.chan_cfg[chan_id];
Expand All @@ -124,17 +112,6 @@ static inline void adsp_pipeline_sink(adsp_pipeline_t *adsp, int32_t **data)
}


static inline void adsp_pipeline_clear_probe(adsp_pipeline_t *adsp)
{
int probe_id = adsp->probe_id;
bool probe = adsp->probe;
if(probe) {
xscope_int(probe_id, 0);
}
}



/// Non-blocking receive from the pipeline. It is risky to use this API in an isochronous
/// application as the sink thread can lose synchronisation with the source thread which can
/// cause the source thread to block.
Expand Down
27 changes: 5 additions & 22 deletions python/audio_dsp/design/pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -476,18 +476,7 @@ def _gen_chan_buf_write(channel, edge, frame_size):
"""Generate the C code to write to a channel."""
return f"chan_out_buf_word({channel}, (uint32_t*){edge}, {frame_size});\n"

class ProbeValues(IntEnum):
WORKING = 0
IN = 1
OUT = 2

def c(self, thread_idx):
return f"xscope_int({_probe_name(thread_idx)}, {self.value})"

def _probe_name(thread_idx):
return f"ADSP_PROBE_T{thread_idx}"

def _generate_dsp_threads(resolved_pipeline, include_probes: bool):
def _generate_dsp_threads(resolved_pipeline):
"""
Create the source string for all of the dsp threads.

Expand Down Expand Up @@ -587,7 +576,6 @@ def _generate_dsp_threads(resolved_pipeline, include_probes: bool):
control += f"\t\t{name}_control(modules[{i}]->state, &modules[{i}]->control);\n"

read = f"\tint read_count = {len(in_edges)};\n" # TODO use bitfield and guarded cases to prevent
read += f"\t{ProbeValues.IN.c(thread_index)};\n"
# the same channel being read twice
if len(in_edges.values()):
read += "\tSELECT_RES(\n"
Expand Down Expand Up @@ -633,7 +621,6 @@ def _generate_dsp_threads(resolved_pipeline, include_probes: bool):
read += "\t}\n"

process = "\tstart_ts = get_reference_time();\n\n"
process += f"\t{ProbeValues.WORKING.c(thread_index)};\n"

for stage_thread_index, (stage_index, name, _) in enumerate(thread):
input_edges = [edge for edge in all_edges if edge[1][0] == stage_index]
Expand All @@ -655,7 +642,6 @@ def _generate_dsp_threads(resolved_pipeline, include_probes: bool):
profile += "\t}\n"

out = ""
out += f"\t{ProbeValues.OUT.c(thread_index)};\n"
for out_index, (dest, edges) in enumerate(all_output_edges.items()):
for edge in edges:
# do q format conversion first
Expand Down Expand Up @@ -784,7 +770,7 @@ def _generate_dsp_max_thread_ticks(resolved_pipeline):
"""


def _generate_dsp_init(resolved_pipeline, include_probes):
def _generate_dsp_init(resolved_pipeline):
"""Create the init function which initialised all modules and channels."""
chans = _determine_channels(resolved_pipeline)
adsp = f"adsp_{resolved_pipeline['identifier']}"
Expand Down Expand Up @@ -833,8 +819,6 @@ def _generate_dsp_init(resolved_pipeline, include_probes):
ret += f"\t{adsp}.n_link = {link_channels};\n"
ret += f"\t{adsp}.modules = {adsp}_modules;\n"
ret += f"\t{adsp}.n_modules = {num_modules};\n"
ret += f"\t{adsp}.probe = {int(include_probes)};\n"
ret += f"\t{adsp}.probe_id = {_probe_name("SS")};\n"

# initialise the modules
for thread in resolved_pipeline["threads"]:
Expand Down Expand Up @@ -981,7 +965,7 @@ def _generate_dsp_ctrl() -> str:
return ret


def generate_dsp_main(pipeline: Pipeline, out_dir="build/dsp_pipeline", include_probes=False):
def generate_dsp_main(pipeline: Pipeline, out_dir="build/dsp_pipeline"):
"""
Generate the source code for adsp_generated_<x>.c.

Expand Down Expand Up @@ -1010,7 +994,6 @@ def generate_dsp_main(pipeline: Pipeline, out_dir="build/dsp_pipeline", include_
#include <xcore/assert.h>
#include <xcore/hwtimer.h>
#include <xcore/thread.h>
#include <xscope.h>
#include <platform.h>
#include <print.h>
#include "cmds.h" // Autogenerated
Expand All @@ -1033,8 +1016,8 @@ def generate_dsp_main(pipeline: Pipeline, out_dir="build/dsp_pipeline", include_
)
if resolved_pipe["xscope"]:
dsp_main += _generate_dsp_ctrl()
dsp_main += _generate_dsp_threads(resolved_pipe, include_probes)
dsp_main += _generate_dsp_init(resolved_pipe, include_probes)
dsp_main += _generate_dsp_threads(resolved_pipe)
dsp_main += _generate_dsp_init(resolved_pipe)
dsp_main += _generate_dsp_max_thread_ticks(resolved_pipe)

dsp_main += (
Expand Down
4 changes: 2 additions & 2 deletions test/pipeline/app_synched_source_sink/config.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"FS": [96000],
"N_CHANS": [1],
"N_THREADS": [1, 3],
"N_CHANS": [1, 16],
"N_THREADS": [1, 3, 5],
"FRAME_SIZE": [1, 16]
}

3 changes: 1 addition & 2 deletions test/pipeline/app_synched_source_sink/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,8 @@ void test(adsp_pipeline_t* dsp) {
if(0 == frame_count) {
frame_count = FRAME_SIZE;

adsp_pipeline_source(dsp, source);
adsp_pipeline_sink(dsp, sink);
adsp_pipeline_clear_probe(dsp);
adsp_pipeline_source(dsp, source);
}
frame_count -= 1;
}
Expand Down
7 changes: 0 additions & 7 deletions test/pipeline/python/run_pipeline_xcoreai.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,13 +113,6 @@ def run(xe, input_file, output_file, num_out_channels, pipeline_stages=1, return
stdout = ff.readlines()
return stdout

def run_simple(xe, xscope_file=""):
with FileLock("run_pipeline.lock"):
arg = ["--xscope-file", xscope_file] if xscope_file else ["--xscope"]
subprocess.run(["xrun", *arg, "--adapter-id", get_adapter_id(), xe], check=True)



if __name__ == "__main__":
args = parse_arguments()
assert args.xe is not None, "Specify vaild .xe file"
Expand Down
7 changes: 4 additions & 3 deletions test/pipeline/test_synched_source_sink.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,11 @@ def test_synched_source_sync(fs, frame_size, n_chans, threads):
BUILD_DIR.mkdir(exist_ok=True)
VCD_DIR.mkdir(exist_ok=True)
with FileLock(build_utils.SYNCHED_SOURCE_SINK_BUILD_LOCK):
generate_dsp_main(p, out_dir = BUILD_DIR / "dsp_pipeline_default", include_probes=True)
generate_dsp_main(p, out_dir = BUILD_DIR / "dsp_pipeline_default")
build_utils.build(APP_DIR, BUILD_DIR, f"app_synched_source_sink_{config}")
vcd_file = VCD_DIR / f"{config}"
run_pipeline_xcoreai.run_simple(APP_DIR / "bin" / config / f"{APP_NAME}_{config}.xe", vcd_file)
vcd_file = VCD_DIR / f"{config}.vcd"
app = APP_DIR / "bin" / config / f"{APP_NAME}_{config}.xe"
subprocess.run(["xsim", app, "--vcd-tracing", f"-o {vcd_file} -tile tile[0] -cores -instructions"], check=True)