Errors on Genetic Aligmnent Tutorials

33 views
Skip to first unread message

TS12

unread,
Jan 18, 2021, 1:12:31 PM1/18/21
to Spatial Users
Hi,

I've been wanting to test the SW example, but I'm continuously finding an error I cannot solve.

I've tried other examples, and everything is working fine. I'm getting the error with both, the code available on the tutorials and the github repo. I've also tried the SW algorithm with multiple targets, and all of them give the same result. This makes me think that there is some kind of error on the source code, that I can't solve.

The compilation with bin/spatial works well. Afterwards, when using make on the gen folder I got the following error:
[error] /mnt/spatial-quickstart/gen/SW_spatial/scala/x1201_inr_Foreach_kernel.scala:127:58: value | is not a member of Struct2
[error]             ).collect{case (sel, d) if sel => d}.reduce{_|_}
[error] /mnt/spatial-quickstart/gen/SW_spatial/scala/x1106_inr_Foreach_kernel.scala:127:58: value | is not a member of Struct2
[error]             ).collect{case (sel, d) if sel => d}.reduce{_|_}
afterwards, the compilation fails


From my own debugging, it seems to come from the line:
if ((c == length.value | r == length.value) && possible_entry_point.score < update.score) possible_entry_point := entry_tuple(r, c, update.score)
If I delete this line from the code the error is gone, but I don't understand why, or how to solve it.

Any help would be appreciated!
Thanks

Matt Feldman

unread,
Jan 26, 2021, 5:06:28 PM1/26/21
to Spatial Users
Hi,

Sorry for the delay and the strange error.  The quick fix for this problem is to change the app from:

```
val update = if (r == 0) (sw_tuple(0, 0)) else if (c == 0) (sw_tuple(0, 1)) else {
  val match_score = mux(seqa_sram_raw(c-1) == seqb_sram_raw(r-1), MATCH_SCORE.to[Int16], MISMATCH_SCORE.to[Int16])
  val from_top = score_matrix(r-1, c).score + GAP_SCORE
  val from_left = previous_result.score + GAP_SCORE
  val from_diag = score_matrix(r-1, c-1).score + match_score
  mux(from_left >= from_top && from_left >= from_diag, sw_tuple(from_left, SKIPB), mux(from_top >= from_diag, sw_tuple(from_top,SKIPA), sw_tuple(from_diag, ALIGN)))
}
```

to:

```
val tmp = if (r == 0) (sw_tuple(0, 0)) else (sw_tuple(0, 1))
val update = if (c == 0 || r == 0) (tmp) else {
  val match_score = mux(seqa_sram_raw(c-1) == seqb_sram_raw(r-1), MATCH_SCORE.to[Int16], MISMATCH_SCORE.to[Int16])
  val from_top = score_matrix(r-1, c).score + GAP_SCORE
  val from_left = previous_result.score + GAP_SCORE
  val from_diag = score_matrix(r-1, c-1).score + match_score
  mux(from_left >= from_top && from_left >= from_diag, sw_tuple(from_left, SKIPB), mux(from_top >= from_diag, sw_tuple(from_top,SKIPA), sw_tuple(from_diag, ALIGN)))
}
```


It looks people have only built this app for fpga and not simulation.  The problem is that the `if (a) x else if (b) y else z` pattern turns into a one hot mux, which is generated by producing all 3 results and or-ing them together.  In this case, x, y, and z are struct type.  In the fpga backend, we just treat the structs as concatenated ints and perform | bitwise.  In the scala backend, we treat structs a little differently (as case classes) and | isn't defined.  I will fix this in the next Spatial update, but for now you can just change the above to get moving.  It just turns the 3-input one hot mux into a cascade of two 2-input muxes, which codegen properly for structs in the scala backend.  Thanks for pointing this out!

Message has been deleted

TS12

unread,
Jan 27, 2021, 7:36:48 AM1/27/21
to Spatial Users
Thanks for taking the time to look into this. It's all working fine now for --sim target and Xilinx ZCU synth.
Thanks for the explanation, its very useful and makes sense now for me.
Reply all
Reply to author
Forward
0 new messages