I spent some time this week with Claude Code (most...
# methylseq
a
I spent some time this week with Claude Code (mostly) and Codex porting Bismark to Rust and making drop-in replacements for all of the sub-tools. https://github.com/alanhoyle/Bismark/tree/rust-port/rust I don't think it's ready for prime time yet, but testing looks good so far on small datasets. Maintaining it might be beyond me. if you have a test dataset you can try it against the nf-core methylseq workflow by dumping the following into a "rust.config" file and running adding "`-c rust.config`" to your
nextflow run nf-core/methylseq
process {
withName: /BISMARK.*/ {
container = '<http://quay.io/aphoid/bismark-ru:latest|quay.io/aphoid/bismark-ru:latest>'
}
}
f
That’s very interesting, as I am pretty much also about to do this myself (even in the same order of tackling the individual downstream scripts first, and dealing with the aligner last - as I’ve got a few ideas to change things around at the same time…). Are you also working on that by any chance?
I won’t have time to look at your implementation this weekend, but will definitely take a look
p
Nice! Yes Felix and I have already been discussing this a bit, about approaches to architecture and so on..
a
I'm giving the aligner a shot. I'm calling it "bistromark" but I haven't put that out in public yet. One oddness that I have in confirming results is that the perl
bismark-summary
seems to output the samples in file-system-glob order, not lexicograpic order. The charts in the HTML and the text lines are basically random. Running the text summaries through
sort
aligns them. Again, at least on the small toy dataset I've been using in testing...
p
The aligner seems tricky to replicate, as there are multiple different aligner options for Bismark and they're all different - will you still call out to those different underlying tools?
Also what's your intention with the rewrite? To contribute it back upstream?
a
Make a faster and (hopefully) more memory efficient drop-in replacement for the suite. Bismark, when we use it, seems to be one of the slowest and most memory hungry processes of anything we've been using lately. I know that I'm not qualified to be the maintainer here: I only know enough to be dangerous, but I'm trying to be as careful as I can.
Most of my testing has been with the Bismark/test_files/* and I'm getting compatible output there.
Copy code
➜  rust git:(rust-port) ✗ tests/performance.sh --test-files --threads 4 --mem
Note: gtime not found; falling back to /usr/bin/time -l. Command stderr and timing output will be mixed in .timemem files. (Install: brew install gnu-time)
Preparing test_files inputs...
Preparing genome...
Aligning paired-end FASTQs with Perl Bismark...
Running 3 benchmark run(s) with 4 thread(s) where supported with RAM tracking (/usr/bin/time -l)...

Run 1/3

Run 2/3

Run 3/3

Performance + memory summary (wall-clock seconds; peak RSS averaged across runs)
case                                        perl avg    rust avg     speedup      perl RAM      rust RAM  RAM ratio
----                                        --------    --------     -------      --------      --------  ---------
test_files/bismark2bedGraph                    5.300       0.387      13.68x      22.3 MiB       3.4 MiB      6.55x
test_files/bismark_aligner                     6.319       1.695       3.73x      32.3 MiB      31.7 MiB      1.02x
test_files/bismark_genome_preparation          6.182       0.101      61.35x       7.4 MiB       6.6 MiB      1.11x
test_files/bismark_methylation_extractor       5.430       0.101      53.62x      11.9 MiB      58.7 MiB      0.20x
test_files/coverage2cytosine                   7.543       0.160      47.25x      42.3 MiB      10.4 MiB      4.07x
test_files/deduplicate_bismark                 0.233       0.120       1.95x       9.5 MiB      15.3 MiB      0.62x

Raw results: /Users/alanh/src/Bismark/rust/tests/tmp/perf-20260522-152431.csv
RAM figures are mean peak RSS across 3 run(s).
Note: command stderr was merged with timing output (gtime not available).
➜  rust git:(rust-port) ✗ tests/performance.sh --test-files --threads 4
Preparing test_files inputs...
Preparing genome...
Aligning paired-end FASTQs with Perl Bismark...
Running 3 benchmark run(s) with 4 thread(s) where supported...

Run 1/3

Run 2/3

Run 3/3

Performance summary (wall-clock seconds; lower is better)
case                                        perl avg    rust avg     speedup    perl min    rust min
----                                        --------    --------     -------    --------    --------
test_files/bismark2bedGraph                    5.371       0.396      13.55x       5.291       0.364
test_files/bismark_aligner                     6.278       1.738       3.61x       6.215       1.672
test_files/bismark_genome_preparation          6.202       0.105      59.15x       6.196       0.096
test_files/bismark_methylation_extractor       5.436       0.085      63.77x       5.410       0.081
test_files/coverage2cytosine                   6.698       0.151      44.47x       6.586       0.145
test_files/deduplicate_bismark                 0.236       0.106       2.22x       0.213       0.095

Raw results: /Users/alanh/src/Bismark/rust/tests/tmp/perf-20260522-152651.csv
p
Nice! Yeah I wouldn't trust the performance numbers on such small files yet, but I definitely agree that there's a lot of potential in a Rust rewrite of Bismark
I'd encourage you not to go it alone as a replacement for Bismark though, rather collaborate with Felix on a rewrite for Bismark - a Bismark v2. The latter is going to happen anyway, so best to work together rather than duplicate effort and tooling..
👍 1
a
I mean, this thing did silly things like reimplement time/date code for the reports, which I think we can all agree is a terrible idea.
😅 1
p
Yup, welcome to the weeds 😅 Initial rewrite is always fast and promising in my experience, usually followed by disappointment and then the work of closing the gap on real data..
f
Hi both, thanks again Alan for making a start on this and making us aware. Just to reiterate what Phil and I said before - we are in the process of doing this anyway, and it would be great if we could find a way to work together on this rather than in separate or duplicated efforts that eventually results in fractionating the project. I have maintained and supported Bismark for over 16 years now, and I have no intention of stopping either effort just yet. In that sense I would very much appreciate if we could work on a new version together, rather than writing a new and different version version altogether. What I have learned during the rewrite of Trim Galore is that while the initial rewrite appeared to produce some promising results that looked bit-identical at first glance after only a day or so. However, it took me close to 5 weeks to get it polished, tested and optimised for a public release that was up to the standard I would expect. I have also supported Trim Galore for over 15 years, have pretty much all test and real life data readily available, and understand what I would like it to look like - and it still took this long. Since the Bismark codebase is a lot bigger, contains a myriad of options and combinations thereof, I would expect the process to take substantially longer, and require a lot of domain expertise and testing to get it just right. I have all the aforementioned, as well as the willingness to support the tool and its users long-term. In my mind this puts me in a good position of leading a bismark2rust transition myself, or at least be part of it. I would welcome help of course as it saves me time, and tokens
I have just completed a cursory run through a 10M test data set in default mode, where some modules appeared to do alright with some minor things, but especially the methylation extractor has fundamental structural issues that do not seem to work as intended. Interestingly it appeared to be slower than the Perl version. Going forward, and as recommended by Phil, I would like to switch out samtools with noodles to avoid the dependency of external processes as much as possible. I would want to proceed very carefully with this project, providing appropriate test cases for each tool and all their potential combination of options separately, and specific for directional, PBAT, non-directional, RRBS, scNMT or NOMe-seq data, with all different contexts or combinations of filters applied.
Please let me know what you see as a good path forward. Cheers, Felix
a
I'd be happy to help out in small ways. At worst, I would hope that this lets it be known that an accelerated port would be nice! I'm definitely not trying to fork/take over here.
f
That’s good to hear. I have started a framework for this as a staggered project with 3 planned phases (2+3 to appear once I am starting to close off phase 1). I will make sure to look at your and work and fold in anything that’s already in a great working order. But first things first, it’s a bank holiday weekend with 32C! Thanks and speak soon