1 package kmer; 2 3 import java.util.Arrays; 4 5 import shared.Primes; 6 import shared.Shared; 7 import shared.Tools; 8 import structures.IntList; 9 10 public class ScheduleMaker { 11 ScheduleMaker(int ways_, int bytesPerKmer_, boolean prealloc_, double memRatio_)12 public ScheduleMaker(int ways_, int bytesPerKmer_, boolean prealloc_, double memRatio_){ 13 this(ways_, bytesPerKmer_, prealloc_, memRatio_, 0, 0, 0, 0); 14 } 15 ScheduleMaker(int ways_, int bytesPerKmer_, boolean prealloc_, double memRatio_, int initialSize_)16 public ScheduleMaker(int ways_, int bytesPerKmer_, boolean prealloc_, double memRatio_, int initialSize_){ 17 this(ways_, bytesPerKmer_, prealloc_, memRatio_, initialSize_, 0, 0, 0); 18 } 19 ScheduleMaker(int ways_, int bytesPerKmer_, boolean prealloc_, double memRatio_, int initialSize_, int prepasses_, double prefilterFraction_, long filterMemoryOverride_)20 public ScheduleMaker(int ways_, int bytesPerKmer_, boolean prealloc_, double memRatio_, int initialSize_, 21 int prepasses_, double prefilterFraction_, long filterMemoryOverride_){ 22 bytesPerKmer=bytesPerKmer_; 23 prealloc=prealloc_; 24 memRatio=(float)(memRatio_<=0 ? 1 : memRatio_); 25 prepasses=prepasses_; 26 prefilter=(prepasses>0); 27 prefilterFraction=prefilter ? prefilterFraction_ : 0; 28 assert(prefilter==prefilterFraction>0) : prefilter+", "+prefilterFraction_+", "+prefilterFraction; 29 // assert(false && prefilter==prefilterFraction>0) : prefilter+", "+prefilterFraction_+", "+prefilterFraction; 30 if(prepasses<1){ 31 filterMemory0=filterMemory1=0; 32 }else if(filterMemoryOverride>0){ 33 filterMemory0=filterMemory1=filterMemoryOverride; 34 }else{ 35 double low=Tools.min(prefilterFraction, 1-prefilterFraction); 36 double high=1-low; 37 if(prepasses<0 || (prepasses&1)==1){//odd passes 38 filterMemory0=(long)(usableMemory*low); 39 filterMemory1=(long)(usableMemory*high); 40 }else{//even passes 41 filterMemory0=(long)(usableMemory*high); 42 filterMemory1=(long)(usableMemory*low); 43 } 44 } 45 tableMemory=(long)(usableMemory*.95-Tools.min(filterMemory0, filterMemory1)); 46 47 if(ways_<1){ 48 long maxKmers=(2*tableMemory)/bytesPerKmer; 49 long minWays=Tools.min(10000, maxKmers/Integer.MAX_VALUE); 50 ways_=(int)Tools.max(31, (int)(Shared.threads()*2.5), minWays); 51 ways_=(int)Primes.primeAtLeast(ways_); 52 assert(ways_>0); 53 // System.err.println("ways="+ways_); 54 } 55 ways=ways_; 56 57 final double maxSize0=(tableMemory*0.95*memRatio)/(bytesPerKmer*ways); 58 assert(maxPrime>1 && maxSize0>2) : 59 "\nmaxPrime="+maxPrime+", maxSize0="+maxSize0+", tableMemory="+tableMemory+", usableMemory="+usableMemory+ 60 ", \nprepasses="+prepasses+", filterMemory0="+filterMemory0+", filterMemory1="+filterMemory1+", prefilterFraction="+prefilterFraction+ 61 ", \nmemRatio="+memRatio+", bytesPerKmer="+bytesPerKmer+", ways="+ways+ 62 ", \ninitialSize="+initialSize_+", initialSizeDefault="+initialSizeDefault+", prealloc="+prealloc; 63 64 lastSizeFraction=prealloc ? 1.0 : resizeMult/(1.0+resizeMult); 65 maxSize=Primes.primeAtMost((int)Tools.min(maxPrime, maxSize0*lastSizeFraction)); 66 initialSize=(prealloc ? maxSize : Primes.primeAtMost(initialSize_>0 ? initialSize_ : initialSizeDefault)); 67 68 estimatedKmerCapacity=(long)(maxSize*HashArray.maxLoadFactorFinal*0.97*ways); 69 70 // System.err.println(Arrays.toString(makeSchedule())); 71 72 // System.err.println("ways="+ways+", maxSize="+maxSize+", estimatedKmerCapacity="+estimatedKmerCapacity+", "+Arrays.toString(makeSchedule())); 73 // 74 // assert(false) : 75 // "\nmaxPrime="+maxPrime+", maxSize0="+maxSize0+", tableMemory="+tableMemory+", usableMemory="+usableMemory+ 76 // ", \nprepasses="+prepasses+", filterMemory0="+filterMemory0+", filterMemory1="+filterMemory1+", prefilterFraction="+prefilterFraction+ 77 // ", \nmemRatio="+memRatio+", bytesPerKmer="+bytesPerKmer+", ways="+ways+ 78 // ", \ninitialSize="+initialSize_+", initialSizeDefault="+initialSizeDefault+", prealloc="+prealloc+ 79 // ", \nmaxSize="+maxSize+", initialSize="+initialSize+", estimatedKmerCapacity="+estimatedKmerCapacity+ 80 // ", \n"+Arrays.toString(makeSchedule()); 81 // assert(false) : Arrays.toString(makeSchedule()); 82 } 83 makeSchedule()84 public int[] makeSchedule(){ 85 if(prealloc || maxSize<2L*initialSize){return new int[] {maxSize};} 86 IntList list=new IntList(10); 87 list.add(maxSize); 88 for(double x=maxSize*invResizeMult; x>=initialSize; x=x*invResizeMult2){ 89 list.add((int)x); 90 } 91 if(list.size()>1 && list.lastElement()>=2*initialSize){ 92 list.add(initialSize); 93 } 94 list.reverse(); 95 // if(list.lastElement()*2L<maxPrime){list.add(2*maxSize);}//This ensures that the program will crash rather than garbage-collecting for a long time 96 int[] array=list.toArray(); 97 // if(initialSize>2 && array.length>2 && array[0]>initialSize){array[0]=initialSize;} 98 assert(Tools.isSorted(array)) : Arrays.toString(array); 99 for(int i=0; i<array.length; i++){ 100 array[i]=array[i]==1 ? 1 : (int)Tools.min(maxPrime, Primes.primeAtLeast(array[i])); 101 } 102 return array; 103 } 104 105 // public static int[] makeScheduleStatic(int initialSize, int maxSize, boolean autoResize){ 106 // if(!autoResize || initialSize>=maxSize){return null;} 107 // IntList list=new IntList(10); 108 // list.add((int)(maxSize*0.8)); 109 // for(long x=maxSize; x>=initialSize; x=x/5){ 110 // list.add((int)x); 111 // } 112 // if(list.size()>1 && list.lastElement()>=2*initialSize){ 113 // list.add(initialSize); 114 // } 115 // list.reverse(); 116 // int[] array=list.toArray(); 117 // for(int i=0; i<array.length; i++){ 118 // array[i]=array[i]==1 ? 1 : (int)Tools.min(maxPrime, Primes.primeAtLeast(array[i])); 119 // } 120 // return array; 121 // } 122 123 final double resizeMult=5.0; 124 final double resizeMult2=3.0; 125 final double invResizeMult=1/resizeMult; 126 final double invResizeMult2=1/resizeMult2; 127 final double lastSizeFraction; 128 129 final long memory=Runtime.getRuntime().maxMemory(); 130 final double xmsRatio=Shared.xmsRatio(); 131 132 //TODO: Add term for JDK (Oracle/Open) and version. 133 final long usableMemory=(long)Tools.max(((memory-96000000)* 134 (xmsRatio>0.97 ? 0.82 : 0.72)), memory*0.45); 135 136 final long filterMemoryOverride=0; 137 138 final long filterMemory0, filterMemory1; 139 final long tableMemory; 140 final double prefilterFraction; 141 final int prepasses; 142 final boolean prefilter; 143 final int bytesPerKmer; 144 public final long estimatedKmerCapacity; 145 146 public final int ways; 147 148 final int initialSize; 149 final int maxSize; 150 151 final boolean prealloc; 152 final float memRatio; 153 154 static final int initialSizeDefault=128000; 155 static final int maxPrime=(int)Primes.primeAtMost(Integer.MAX_VALUE-100-20); 156 157 } 158