Suggested Documentation Changes to "DSLX Tutorial: Intro to procs"
- Dominant language
- C++
- Stars
- 1.9k
- Forks
- 283
- Avg merge
- 2d 10h
- Merged PRs (30d)
- 135
Description
[doc link](https://google.github.io/xls/tutorials/intro_to_procs/)
* It might be worthwhile to explain why procceses are needed in the first place (e.g. give a good motivating example)
* There is no documentation in the [language reference](https://google.github.io/xls/dslx_reference/) for processes
* The example proc definition is incorrect:
```^ ParseError: Procs must define "init", "config" and "next" functions.```
I looked at a few other examples, and tried:
```
init {
float32::zero(u1:0)
}
```
and that seems to work, although it's not clear what this is supposed to do
* The `config` function parameter names shadow the names of proc member variables, which can be a bit confusing. For clarity, maybe consider:
```
config(inc_a: chan in, inc_b: chan in, outp: chan out) {
(inc_a, inc_b, outp)
}
```
* The `next` method is incorrect:
```
0026: | }
|___^ XlsTypeError: (APFloat { sign: uN[1], bexp: uN[8], fraction: uN[23] }) vs struct 'APFloat' structure: APFloat { sign: uN[1], bexp: uN[8], fraction: uN[23] }: 'next' input and output state types differ.
```
I changed the evaluation from `(result,)` to `result` and that seems to work
* The `state` parameter isn't used in this example; it may make more sense to choose a different motivating example to show how state recurrence is expected to work
* The `Spawner` proc definition is incorrect, it uses `name = chan ...` instead of `name: chan...`
* `Spawner` is missing `init` and `next` methods, I added
```
init { () }
next (tok: token, state: ()) { () }
```
* `Spawner` uses `fmac` for the proc but it's defined as `Fmac` in the previous code block; they need to be consistent
* The spawn syntax is unclear:
```
0041: spawn Fmac(fmac_1_a_c, fmac_1_b_c, fmac_1_output_p)(float32::zero(false));
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
ParseError: Expected '}', got '('
```
I'm guessing at least part of this was that I added a dummy `init` method to `fmac` (see above) that doesn't match the expected invocation, but the error message is unclear. I removed the `(float32::zero(false))` part and it seems to work (at least the interpreter seems to think it's syntactically correct) but it leads to a validation error:
```
0202 14:03:49.037756 2903354 verifier.cc:1714] INTERNAL: XLS_RET_CHECK failure (xls/ir/verifier.cc:1714) send_nodes.contains(channel) Channel 'Spawner_chandecl_procs_x_38_36_38_44' (id 0) has no associated send node
0x55597f9fe210: xabsl::StatusBuilder::CreateStatusAndConditionallyLog()
0x55597f8c66b8: xls::VerifyPackage()
0x55597f63b1bf: xls::dslx::(anonymous namespace)::ConvertCallGraph()
0x55597f638a12: xls::dslx::ConvertModuleIntoPackage()
0x55597f63b8ef: xls::dslx::ConvertModuleToPackage()
0x55597f62e39d: xls::dslx::ParseAndTest()
0x55597dd52cea: main
0x7fd0a20446ca: [unknown]
E0202 14:03:49.038005 2903354 command_line_utils.cc:45] Could not extract a textual position from error message: INTERNAL: XLS_RET_CHECK failure (xls/ir/verifier.cc:1714) send_nodes.contains(channel) Channel 'Spawner_chandecl_procs_x_38_36_38_44' (id 0) has no associated send node: INVALID_ARGUMENT: Provided status is not in recognized error form: INTERNAL: XLS_RET_CHECK failure (xls/ir/verifier.cc:1714) send_nodes.contains(channel) Channel 'Spawner_chandecl_procs_x_38_36_38_44' (id 0) has no associated send node
Error: INTERNAL: XLS_RET_CHECK failure (xls/ir/verifier.cc:1714) send_nodes.contains(channel) Channel 'Spawner_chandecl_procs_x_38_36_38_44' (id 0) has no associated send node
```
It wasn't too hard to demangle the channel names to recover the file/line number where they are defined, but it may make it easier to debug problems like this if the interpreter preserved the original variable names (does the `Could not extract a textual position from error message:` part of the error message have anything to do with this?)
The error appears to be coming from the statement
`let (fmac_1_a_p, fmac_1_a_c) = chan;`
but it's not clear what the actual error is; contextually, it looks like `fmac_1_a_p` is supposed to send and `fmac_1_a_c` is supposed to receive, but the validator doesn't seem to agree. This may be related to the other changes I made; the file I'm trying to use, including my changes, looks like this:
```
import float32;
type F32 = float32::F32;
proc Fmac {
input_a_consumer: chan in;
input_b_consumer: chan in;
output_producer: chan out;
init {
float32::zero(u1:0)
}
config(inc_a: chan in, inc_b: chan in,
outp: chan out) {
(inc_a, inc_b, outp)
}
next(tok: token, state: F32) {
let (tok_a, input_a) = recv(tok, input_a_consumer);
let (tok_b, input_b) = recv(tok, input_b_consumer);
let result = float32::fma(input_a, input_b, state);
let tok = join(tok_a, tok_b);
let tok = send(tok, output_producer, result);
result
}
}
proc Spawner {
fmac_1_a_producer: chan out;
fmac_1_b_producer: chan out;
fmac_1_output_consumer: chan in;
fmac_2_a_producer: chan out;
fmac_2_b_producer: chan out;
fmac_2_output_consumer: chan in;
config() {
let (fmac_1_a_p, fmac_1_a_c) = chan;
let (fmac_1_b_p, fmac_1_b_c) = chan;
let (fmac_1_output_p, fmac_1_output_c) = chan;
spawn Fmac(fmac_1_a_c, fmac_1_b_c, fmac_1_output_p)();
let (fmac_2_a_p, fmac_2_a_c) = chan;
let (fmac_2_b_p, fmac_2_b_c) = chan;
let (fmac_2_output_p, fmac_2_output_c) = chan;
spawn Fmac(fmac_2_a_c, fmac_2_b_c, fmac_2_output_p)();
(fmac_1_a_p, fmac_1_b_p, fmac_1_output_c,
fmac_2_a_p, fmac_2_b_p, fmac_2_output_c)
}
init { () }
next (tok: token, state: ()) { () }
}
```
Contributor guide
Assessment
This issue has not been assessed yet.