diff seqrequester/scripts/search.pl @ 1:1085e094cf5f draft

planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/microsatbed commit 7ceb6658309a7ababe622b5d92e729e5470e22f0-dirty
author fubar
date Sat, 13 Jul 2024 12:39:06 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/seqrequester/scripts/search.pl	Sat Jul 13 12:39:06 2024 +0000
@@ -0,0 +1,215 @@
+#!/usr/bin/env perl
+
+use strict;
+use Time::HiRes qw(usleep nanosleep);
+
+my $order  = 0;
+my $weight = 0;
+
+while (scalar(@ARGV) > 0) {
+    my $arg = shift @ARGV;
+
+    if ($arg eq "-order") {
+        $order = shift @ARGV;
+    }
+
+    if ($arg eq "-weight") {
+        $weight = shift @ARGV;
+    }
+}
+if ($order == 0) {
+    die "usage: $0 -order <order>\n";
+}
+
+#  This scales at 4^k * 4^k -- (state vectors) * (cycle length)
+#
+#    time seqrequester shift -search -fast -tapmin 300000000000 -tapmax 300033333333 -order 12 -report 0.9
+#
+#  The SV MUST NOT start with 0 or 1.  We generate the new SR state as
+#
+#    out = rightmost 2 bits of SR
+#    mul = SV * out (* in GF4, operating on 2-bit tuples)
+#    SR  = (SR >> 2) ^ mul
+#
+#  When the SV starts with 0, the resulting SR will always start with zero -
+#  it is like we simply reduce the order by one.  The longest cycle in order
+#  12 here is 4194304, exactly 1/4 the maximum expected, and exactly the
+#  length of the cycle for order 11.
+#
+#  When the SV starts with 1, we car simply moving the output symbol to the
+#  input - we turn the shift register into a cyclic shift register.  The longest
+#  cycle in order 12 here is 'exactly' 1/3 the maximum - 5592406 out of 16777216.
+#  I do not know why.
+#
+#  3's and 2's seem interchangable; swapping all 3's and 2's in a vector
+#  seems to generate the same cycles length.  This probably just 'reverses'
+#  the sequence.  NOT RIGOROUSLY TESTED.
+#
+#  
+#
+#    valgrind --tool=callgrind --dump-instr=yes --simulate-cache=yes --collect-jumps=yes \
+#      seqrequester shift -search -fast -tapmin 300000000000 -tapmax 300003333333 -order 12 -report 0.9
+#    callgrind_control -h
+#
+#  Hardcoded job splits.
+#    order <= 10 -  0 digits -       1 job
+#    order == 11 -  1 digit  -       4 jobs
+#    order == 12 -  2 digits -      16 jobs
+#    order == 13 -  4 digits -     256 jobs
+#    order == 14 -  6 digits -    4096 jobs
+#    order == 15 -  8 digits -   65536 jobs
+#    order == 16 - 11 digits - 4194304 jobs
+#
+#  Times are on Ryzen 7 3700X unless noted.
+#  Times are signifcantly worse if multiple jobs run.
+#
+#    order == 12 - with prefix  5 took   1.43 minutes for 30000........  (actual)     -     1024 prefixes ->      24 CPU hours
+#    order == 12 - with prefix  5 took   0.93 minutes for 30000........  (actual)     -     1024 prefixes -> no detect version
+#    order == 12 - with prefix  4 took   5.75 minutes for 3000.........  (actual)     -      256 prefixes ->      24 CPU hours
+#    order == 12 - with prefix  4 took  14.03 minutes for 3000.........  (actual)     -      256 prefixes ->      60 CPU hours (on d)
+#    order == 12 - with prefix  4 took  14.03 minutes for 3000.........  (actual)     -      256 prefixes -> but 90 minutes/job is all 24 cores are used!
+#    order == 12 - with prefix  3 took        minutes for 300..........  (estimated)  -       64 prefixes -> 
+#    order == 12 - with prefix  2 took        minutes for 30...........  (estimated)  -       16 prefixes -> 
+#
+#    order == 13 - with prefix  6 took   9    minutes for 300000.......  (actual)     -     4096 prefixes ->     614 CPU hours
+#    order == 13 - with prefix  5 took  36    minutes for 30000........  (estimated)  -     1024 prefixes -> 
+#    order == 13 - with prefix  4 took 144    minutes for 3000.........  (estimated)  -      256 prefixes -> 
+#
+#    order == 14 - with prefix  9 took   8    minutes for 300000000.....  (actual)    -   262144 prefixes -> 
+#    order == 14 - with prefix  8 took  32    minutes for 30000000......  (actual)    -    65536 prefixes ->  35,000 CPU hours
+#    order == 14 - with prefix  7 took 128    minutes for 3000000.......  (estimated) -    16384 prefixes -> 
+#
+#    order == 15 - with prefix 12 took   2.96 minutes for 300000000000... (actual)    - 16777216 prefixes -> 827,675 CPU hours
+#    order == 15 - with prefix 12 took   0.28 minutes for 300000000000... (actual)    - 16777216 prefixes -> no detect version
+#    order == 15 - with prefix 11 took   9.13 minutes for 30000000000.... (actual)    -  4194304 prefixes -> 638,233 CPU hours
+#    order == 15 - with prefix 10 took  39.38 minutes for 3000000000..... (actual)    -  1048576 prefixes -> 688,273 CPU hours (78.6 years)
+#    order == 15 - with prefix 10 took   3.76 minutes for 3000000000..... (actual)    -  1048576 prefixes -> no detect version -- 
+#    order == 15 - with prefix 10 took   4.11 minutes for 3000000000..... (actual)    -  1048576 prefixes -> no detect version -- with 16 copies running
+#    order == 15 - with prefix  9 took        minutes for 300000000...... (estimated) -   262144 prefixes -> 
+#
+#  CL time
+#
+#  BD time
+#    time seqrequester shift -search -fast -order 21 -report 0.0 -tapmin 300000000000000000000 -tapmax 300000000000000003333 -weight 3
+#    66069.844u 0.283s 18:21:14.56 99.9%     177+817k 0+0io 7pf+0w
+#
+#  order =    0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19  20  21  22
+my @plen = (  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  2,  3,  4,  5,  9, 11, 13, 15, 17, 19,  0 );
+
+#  prefix 5 for 15 is way too big.  this resulted in 256 jobs (1024 prefixes,
+#  but only the ones starting with 3 are computed).  each job is taking a bit
+#  more than 100 hours.
+#    wallclock 415000s (115 hours x 256 jobs = 29440 cpu hours)
+#    user      381110s (remarkably constant)
+#
+#  job scaling should be x4 for each search, and there are x4 more vectors to try.
+#  so for constant job time, we need to increase the prefix length by 2 for each.
+
+#  prefix 9 for 16 resulted in the last job 12550u 3:30 on bv (x 65536 jobs = 229376 cpu hours).
+
+
+print STDERR "Building job names with $plen[$order] components.\n";
+
+my @alljobs = ( "0", "1", "2", "3" );
+my @subjobs;
+
+for (my $p=1; $p < $plen[$order]; $p++) {
+    my @tmpjobs = @alljobs;
+    undef @alljobs;
+
+    foreach my $e (@tmpjobs) {
+        push @alljobs, "0$e";
+        push @alljobs, "1$e";
+        push @alljobs, "2$e";
+        push @alljobs, "3$e";
+    }
+}
+
+print STDERR "Filtering job names.\n";
+
+foreach my $pp (@alljobs) {
+    push @subjobs, $pp   if (($pp =~ m/^0/) && ($order < 14));   #  Ignore 0, no complete cycles in here.
+    push @subjobs, $pp   if (($pp =~ m/^1/) && ($order < 14));   #  Ignore 1, no complete cycles in here.
+    push @subjobs, $pp   if (($pp =~ m/^2/) && ($order < 14));   #  Ignore 2, seems to be just a dual of 3.
+    push @subjobs, $pp   if (($pp =~ m/^3/) && ($order < 22));   #  Always use 3.
+}
+
+@subjobs = sort { $b cmp $a } @subjobs;
+
+my $tJobs = scalar(@alljobs);
+my $sJobs = scalar(@subjobs);
+
+print STDERR "Created    $tJobs jobs.\n";
+print STDERR "Submitting $sJobs jobs.\n";
+
+
+my $bgn = "0" x ($order - $plen[$order]);
+my $end = "3" x ($order - $plen[$order]);
+
+open(F, "> o${order}w${weight}.dat");
+
+foreach my $pp (@subjobs) {
+    print F "$pp\n";
+}
+
+close(F);
+
+
+
+open(F, "> o${order}w${weight}.sh");
+print F "#!/bin/sh\n";
+print F "\n";
+print F "\n";
+print F "if [ x\$SGE_TASK_ID = x -o x\$SGE_TASK_ID = xundefined -o x\$SGE_TASK_ID = x0 ]; then\n";
+print F "  j=\$1\n";
+print F "else\n";
+print F "  j=\$SGE_TASK_ID\n";
+print F "fi\n";
+print F "if [ x\$j = x ]; then\n";
+print F "  echo Error: I need SGE_TASK_ID set, or a job index on the command line.\n";
+print F "  exit\n";
+print F "fi\n";
+print F "\n";
+print F "\n";
+print F "p=`head -n \$j o${order}w${weight}.dat | tail -n 1`";
+print F "\n";
+print F "\n";
+print F "if [ -e \"o${order}w${weight}-out/o${order}w${weight}p\$p.out\" ]; then\n";
+print F "  echo \"o${order}w${weight}p\$p.out exists, it's done!\"\n";
+print F "  exit 0\n";
+print F "fi\n";
+print F "\n";
+print F "if [ ! -d \"o${order}w${weight}-out\" ]; then\n";
+print F "  mkdir -p o${order}w${weight}-out\n";
+print F "fi\n";
+print F "\n";
+print F "/work/seqrequester/FreeBSD-amd64/bin/seqrequester \\\n";
+print F "  shift -search -fast \\\n";
+print F "    -order  $order \\\n";
+print F "    -weight $weight \\\n";
+print F "    -report 0.0 \\\n";
+print F "    -tapmin \${p}$bgn \\\n";
+print F "    -tapmax \${p}$end \\\n";
+print F "> o${order}w${weight}-out/o${order}w${weight}p\$p.out.WORKING \\\n";
+print F "&& \\\n";
+print F "mv o${order}w${weight}-out/o${order}w${weight}p\$p.out.WORKING o${order}w${weight}-out/o${order}w${weight}p\$p.out\n";
+print F "\n";
+print F "\n";
+print F "#\n";
+print F "#  qsub -h -cwd -j y -o o${order}w${weight}-err/o${order}w${weight}-\\\$TASK_ID.err -l memory=1g -t 1-$sJobs -N o${order}w${weight} ./o${order}w${weight}.sh\n";
+print F "#\n";
+print F "\n";
+print F "exit 0\n";
+print F "\n";
+
+close(F);
+
+chmod(0755, "o${order}w${weight}.sh");
+
+system("mkdir o${order}w${weight}-err");
+system("mkdir o${order}w${weight}-out");
+
+print  "qsub -h -cwd -j y -o o${order}w${weight}-err/o${order}w${weight}-\\\$TASK_ID.err -l memory=1g -t 1-$sJobs -N o${order}w${weight} ./o${order}w${weight}.sh\n";
+system("qsub -h -cwd -j y -o o${order}w${weight}-err/o${order}w${weight}-\\\$TASK_ID.err -l memory=1g -t 1-$sJobs -N o${order}w${weight} ./o${order}w${weight}.sh")    if (1);
+
+exit;