The Computer Language
23.01 Benchmarks Game

reverse-complement Chapel #4 program

source code

/* The Computer Language Benchmarks Game
   https://salsa.debian.org/benchmarksgame-team/benchmarksgame/

   contributed by Brad Chamberlain
   based on the Chapel #3 version with some inspiration taken from the
   C gcc #6 version by Jeremy Zerfas
*/

use IO;

param eol = '\n'.toByte(),  // end-of-line, as an integer
      cols = 61,            // # of characters per full row (including '\n')

      // a 'bytes' value that stores the complement of each base at its index
      cmpl = b"          \n                                                  "
           + b"    TVGH  CD  M KN   YSAABW R       TVGH  CD  M KN   YSAABW R";
             //    ↑↑↑↑  ↑↑  ↑ ↑↑   ↑↑↑↑↑↑ ↑       ↑↑↑↑  ↑↑  ↑ ↑↑   ↑↑↑↑↑↑ ↑
             //    ABCDEFGHIJKLMNOPQRSTUVWXYZ      abcdefghijklmnopqrstuvwxyz


proc main(args: [] string) {
  var stdinBin  = openfd(0).reader(iokind.native, locking=false,
                                   hints=QIO_CH_ALWAYS_UNBUFFERED),
      stdoutBin = openfd(1).writer(iokind.native, locking=false,
                                   hints=QIO_CH_ALWAYS_UNBUFFERED),
      bufLen = 8 * 1024,
      bufDom = {0..<bufLen},
      buf: [bufDom] uint(8),
      end = 0;

  // read in the data using an incrementally growing buffer
  while stdinBin.read(buf[end..]) {
    end = bufLen;
    bufLen += min(1024**2, bufLen);
    bufDom = {0..<bufLen};
  }
  end = stdinBin.offset()-1;

  // process the buffer a sequence at a time, working from the end
  var hi = end;
  while (hi >= 0) {
    // search for the '>' that marks the start of a sequence
    var lo = hi;
    while buf[lo] != '>'.toByte() do
      lo -= 1;

    // skip past header line
    var seqlo = lo;
    while buf[seqlo] != eol {
      seqlo += 1;
    }

    // reverse and complement the sequence
    revcomp(buf, seqlo+1, hi);

    hi = lo - 1;
  }

  // write out the transformed buffer
  stdoutBin.write(buf[..end]);
}


proc revcomp(buf, lo, hi) {
  // shift all of the linefeeds into the right places
  const len = hi - lo + 1,
        off = (len - 1) % cols,
        shift = cols - off - 1;

  if off {
    forall m in lo+off..<hi by cols {
      for i in m..#shift by -1 do
        buf[i+1] = buf[i];
      buf[m] = eol;
    }
  }

  // walk from both ends of the sequence, complementing and swapping
  forall (i,j) in zip(lo..#(len/2), ..<hi by -1) do
    (buf[i], buf[j]) = (cmpl[buf[j]], cmpl[buf[i]]);
}
    

notes, command-line, and program output

NOTES:
64-bit Ubuntu quad core
chpl version 1.29.0
built with LLVM version 14.0.0
Copyright 2020-2022
Hewlett Packard
Enterprise Development LP
Copyright 2004-2019 Cray Inc.


Wed, 25 Jan 2023 22:05:19 GMT

MAKE:
mv revcomp.chapel-4.chapel revcomp.chapel-4.chpl
/opt/src/chapel-1.29.0/bin/chpl --fast revcomp.chapel-4.chpl -o revcomp.chapel-4.chapel_run
revcomp.chapel-4.chpl:21: In function 'main':
revcomp.chapel-4.chpl:22: error: unresolved call 'file.reader(iokind, locking=0, hints=int(32))'
$CHPL_HOME/modules/standard/IO.chpl:3138: note: this candidate did not match: file.reader(param kind = iokind.dynamic, param locking = true, region: range(?) = 0.., hints = ioHintSet.empty)
revcomp.chapel-4.chpl:22: note: because actual argument #3 with type 'int(32)'
$CHPL_HOME/modules/standard/IO.chpl:3139: note: is passed to formal 'hints: ioHintSet'
revcomp.chapel-4.chpl:22: note: other candidates are:
$CHPL_HOME/modules/standard/IO.chpl:3146: note:   file.reader(param kind = iokind.dynamic, param locking = true, region: range(?) = 0.., hints = ioHintSet.empty)
$CHPL_HOME/modules/standard/IO.chpl:3082: note:   file.reader(param kind = iokind.dynamic, param locking = true, start: int(64) = 0, end: int(64) = max(int(64)), hints = ioHintSet.empty, style: iostyle)
make: [/home/dunham/all-benchmarksgame/2000-benchmarksgame/nanobench/makefiles/u64q.programs.Makefile:461: revcomp.chapel-4.chapel_run] Error 1 (ignored)
rm revcomp.chapel-4.chpl

5.31s to complete and log all make actions

COMMAND LINE:
./revcomp.chapel-4.chapel_run --n=0 < revcomp-input250000.txt

MAKE ERROR