
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <zlib.h>

int hNumberOfReads = 0;                 // holds number of reads that are processed
int hReadsWritten = 0;                  // number of reads written to output file
char input_filename[400]="/home/linux/cuda-workspace/PreprocessReads/test.txt"; // input file name
char output_filename[400]="/mnt/sdc/Sequences/out.txt";                         // output file name
char GZIP_PIPE[410] = "gzip -> ";       // option -gz will fallback to uncompressed if error on pipe opening
char PIGZ_PIPE[410] = "pigz -> ";       // option -pigz for multithreaded compression will fallback to gz and then to uncompressed
gzFile inputFile;
gzFile templateFile;						// holds a second pointer in input read file for templating output with read name sequence and quality
FILE *outputFile;
bool overwrite_outputfile = false;      // if set true the output file will be overwritten (cmd line option -f)
bool write_gz_output = false;           // specify .gz file compressed output (cmd line option -gz)
bool write_pigz_output = false;         // specify pigz multithreaded compression for output (-pigz option)

bool AdaptorTrimming = true;			// algorithm selectors
bool QualityTrimming = true;
bool gRNATrimming = false;
int gRNA_start;							// holds gRNA position relative to adaptor
int gRNA_length;
bool verbose = false;					// if true print details of processing to screen
bool FastQ_WARNING = false;				// set to true is a FastQ file warning has been issued

short MAX_READ_LENGTH = 203;            // maximal length of reads in input file
short MIN_OUT_READ_LEN = 26;            // minimum length of reads after trimming to write to output file

short MIN_BASE_QUAL = 20;				// parameter for minimum quality for good base
short MIN_QUAL_AFTER_BAD = 25;			// parameter for average base quality after bad base
short PHRED = 33;			        	// subtract from qualities for numerical value of solexa
bool auto_phred_detect = false;         // if true try to detect PHRED format in FastQ input file

int MAX_READS_ON_GPU = 10000000;        // maximum number of reads that fit simultaneously on GPU

#define MAX_ADAPTOR_LENGTH 100          // maximum length of adaptor sequence for trimming, can contain N for any base
#define MAX_FASTQ_BUF_LINE 500          // structure of buffer for read from FastQ file

char Adaptor[MAX_ADAPTOR_LENGTH] = "ATCTCGTATGCCGTCTTCTGCTT"; // adaptor on CPU side from parsing command line
short mismatches = 2;					// holds maximum number of mismatches on cpu side

int numGPUs = 0;                        // holds number of CUDA devices in the system [1 TITAN to max 2 TITAN Z]
#define MAX_GPU_NUM 4
int device[MAX_GPU_NUM];                // device numbers to use
cudaStream_t upload_stream[MAX_GPU_NUM];    // cuda streams per device for overlapped asynchronous operation
cudaStream_t compute_stream[MAX_GPU_NUM];
cudaStream_t download_stream[MAX_GPU_NUM];

char *dSequenceArray[MAX_GPU_NUM];	    // device pointer to data array, will hold hReadSequence and hQualstr
char *dQualArray[MAX_GPU_NUM];			// device pointer to data array, will hold hReadSequence and hQualstr
short *dIntArray[MAX_GPU_NUM][2];       // two device pointers to integer array, will hold hReadLen
cudaEvent_t QUAL_COPY_DONE[MAX_GPU_NUM];   // events for device host synchronization
cudaEvent_t SEQ_COPY_DONE[MAX_GPU_NUM];
cudaEvent_t TrimmQ_DONE[MAX_GPU_NUM];
cudaEvent_t TrimmA_DONE[MAX_GPU_NUM];
cudaEvent_t DTH_COPY_DONE[MAX_GPU_NUM];

short *hReadLen[MAX_GPU_NUM][2];        // two buffer to hold read length on host
char *hReadSequence[MAX_GPU_NUM][2];       // buffer holding sequences of reads on host
char *hReadQualstr[MAX_GPU_NUM];     // two buffer holding qualities of reads on host

struct read
{
    char name[MAX_FASTQ_BUF_LINE];
    char sequence[MAX_FASTQ_BUF_LINE];
    char descr[MAX_FASTQ_BUF_LINE];
    char qualstr[MAX_FASTQ_BUF_LINE];
} Read;                                 // buffer one read from FastQ file i 4 lines



// macro checks return value of the CUDA runtime call and exits the application if the call failed.

#define CUDA_CHECK_RETURN(value) {											\
	cudaError_t _m_cudaStat = value;										\
	if (_m_cudaStat != cudaSuccess) {										\
		fprintf(stderr, "Error %s at line %d in file %s\n",					\
				cudaGetErrorString(_m_cudaStat), __LINE__, __FILE__);		\
		exit(1);															\
	} }


// For trimming adaptor sequences store adaptor and length as well as quality cutoffs in device constant memory

__constant__ __device__ char ADAPTOR[MAX_ADAPTOR_LENGTH];     // adaptor sequence can contain N for any match
__constant__ __device__ short ADAPTOR_LEN;                    // length of adaptor sequence in bases
__constant__ __device__ short MAX_MM=2;                       // maximum mismatches allowed not including Ns
__constant__ __device__ short QUAL_PADDING=33;				  // hold PHRED base for qualities
__constant__ __device__ short MIN_QUAL=20;					  // hold minimal quality that is considered good base
__constant__ __device__ short MIN_AVERAGE_QUAL_AFTER_BAD=25;  // minimum quality average of remaining read after bad base

void SetAdaptorSequence(const char *AdaptorSequence, const short mismatches, const short PHRED, const short MIN_BASE_QUAL, const short MIN_QUAL_AFTER_BAD)
{																// define the adaptor, mismatches and quality parameters before trimming
	short AdLen = strnlen(AdaptorSequence, MAX_ADAPTOR_LENGTH); // get length of adaptor sequence

	for(int dev=0; dev < numGPUs; dev++)
	{
		cudaSetDevice(device[dev]);
		if(verbose) printf("[%d] Setting Adaptor sequence %s, length %d on GPU \n", dev, AdaptorSequence, AdLen);
		CUDA_CHECK_RETURN(cudaMemcpyToSymbol(ADAPTOR, AdaptorSequence, AdLen));           // copy to device
		CUDA_CHECK_RETURN(cudaMemcpyToSymbol(ADAPTOR_LEN, &AdLen, sizeof(short)));        // constant memory
		if(verbose) printf("[%d] Setting mismatches %d, PHRED+%d on GPU \n", dev, mismatches, PHRED);
		CUDA_CHECK_RETURN(cudaMemcpyToSymbol(MAX_MM, &mismatches, sizeof(short)));
		CUDA_CHECK_RETURN(cudaMemcpyToSymbol(QUAL_PADDING, &PHRED, sizeof(short)));
		if(verbose) printf("[%d] Setting minimum base quality %d, average read quality after bad %d on GPU \n", dev, MIN_BASE_QUAL, MIN_QUAL_AFTER_BAD);
		CUDA_CHECK_RETURN(cudaMemcpyToSymbol(MIN_QUAL, &MIN_BASE_QUAL, sizeof(short)));
		CUDA_CHECK_RETURN(cudaMemcpyToSymbol(MIN_AVERAGE_QUAL_AFTER_BAD, &MIN_QUAL_AFTER_BAD, sizeof(short)));
	}
}


__global__ void Find_gRNA(char *dDataArray, short *read_length, int reads, short MAX_READ_LENGTH)
{
  for(long idx = blockIdx.x * blockDim.x + threadIdx.x; idx < reads; idx += blockDim.x * gridDim.x)
  {
      if (idx < reads)
      {
          char *sequence = &dDataArray[idx*MAX_READ_LENGTH];
          short rl=read_length[idx];
          short n;
          short p=0;
          short mm=0;
          read_length[idx]=0;
          while (p <= rl-ADAPTOR_LEN)
          {
              mm=0;
              for (n=0; n<ADAPTOR_LEN; n++)
              {
                  if (ADAPTOR[n]!='N' && sequence[p+n]!=ADAPTOR[n])
                  {
                     mm++;
                     if (mm > MAX_MM) break;
                  }
              }
              if (mm <= MAX_MM)
              {
                  read_length[idx]=p;
                  break;
              }
              p++;
          }
          if (mm <= MAX_MM ) continue;
          p=rl-ADAPTOR_LEN+1;
          if (rl >= ADAPTOR_LEN-1)
          {
              mm=0;
              for (n=0; n<ADAPTOR_LEN-1; n++)
              {
                  if (ADAPTOR[n]!='N' && sequence[p+n]!=ADAPTOR[n])
                  {
                     mm++;
                     if (mm >= MAX_MM) break;
                  }
              }
              if (mm < MAX_MM)
              {
                  read_length[idx]=p;
                  continue;
              }
          }
          p++;
          if (rl >= ADAPTOR_LEN-2)
          {
              mm=0;
              for (n=0; n<ADAPTOR_LEN-2; n++)
              {
                  if (ADAPTOR[n]!='N' && sequence[p+n]!=ADAPTOR[n])
                  {
                     mm++;
                     break;
                  }
              }
              if (MAX_MM > (mm+1))
              {
                  read_length[idx]=p;
              }
          }
      }
  }
}

__global__ void TrimmAdaptors(char *dDataArray, short *read_length, int reads, short MAX_READ_LENGTH)
{
  for(long idx = blockIdx.x * blockDim.x + threadIdx.x; idx < reads; idx += blockDim.x * gridDim.x)
  {
      if (idx < reads)
      {
          char *sequence = &dDataArray[idx*MAX_READ_LENGTH];
          short rl=read_length[idx];
          short n;
          short p=0;
          short mm=0;
          while (p <= rl-ADAPTOR_LEN)
          {
              mm=0;
              for (n=0; n<ADAPTOR_LEN; n++)
              {
                  if (ADAPTOR[n]!='N' && sequence[p+n]!=ADAPTOR[n])
                  {
                     mm++;
                     if (mm > MAX_MM) break;
                  }
              }
              if (mm <= MAX_MM)
              {
                  read_length[idx]=p;
                  break;
              }
              p++;
          }
          if (mm <= MAX_MM ) continue;
          p=rl-ADAPTOR_LEN+1;
          if (rl >= ADAPTOR_LEN-1)
          {
              mm=0;
              for (n=0; n<ADAPTOR_LEN-1; n++)
              {
                  if (ADAPTOR[n]!='N' && sequence[p+n]!=ADAPTOR[n])
                  {
                     mm++;
                     if (mm >= MAX_MM) break;
                  }
              }
              if (mm < MAX_MM)
              {
                  read_length[idx]=p;
                  continue;
              }
          }
          p++;
          if (rl >= ADAPTOR_LEN-2)
          {
              mm=0;
              for (n=0; n<ADAPTOR_LEN-2; n++)
              {
                  if (ADAPTOR[n]!='N' && sequence[p+n]!=ADAPTOR[n])
                  {
                     mm++;
                     break;
                  }
              }
              if (MAX_MM > (mm+1))
              {
                  read_length[idx]=p;
              }
          }
      }
  }
}

__global__ void TrimmQuals(char *quals, short *read_length, int reads, short MAX_READ_LENGTH)
{
  for(long idx = blockIdx.x * blockDim.x + threadIdx.x; idx < reads; idx += blockDim.x * gridDim.x)
  {
      if (idx < reads)
      {
          char *q = &quals[idx*MAX_READ_LENGTH];
          short rl=read_length[idx];
          short i;
          for(i=0; i<rl; i++)
          {
              if ((q[i]-QUAL_PADDING)<=MIN_QUAL)
              {
                 short s=0;
                 short r=i+1;
                 while (r<rl)
                 {
                    s=s+q[r]-QUAL_PADDING;
                    r++;
                 }
                 if(s<(MIN_AVERAGE_QUAL_AFTER_BAD*(rl-i+1)))
                 {
                    read_length[idx]=i;
                    break;
                 }
              }
          }

      }
  }
}


void InitGPUs(void)
{
	if(verbose) printf("\n");
	for (int dev=0; dev<numGPUs; dev++)                         // initialize devices and allocate cuda resources
    {
    	if(verbose) printf("[%d] Initializing GPU\n", dev);
    	CUDA_CHECK_RETURN(cudaSetDevice(device[dev]));
    	CUDA_CHECK_RETURN(cudaMalloc((void **)&dSequenceArray[dev], MAX_READS_ON_GPU * MAX_READ_LENGTH * sizeof(char)));    // one data array
    	CUDA_CHECK_RETURN(cudaMalloc((void **)&dQualArray[dev], MAX_READS_ON_GPU * MAX_READ_LENGTH * sizeof(char)));    // one data array
    	CUDA_CHECK_RETURN(cudaMalloc((void **)&dIntArray[dev][0], MAX_READS_ON_GPU * sizeof(short)));  // two dIntArrays
    	CUDA_CHECK_RETURN(cudaMalloc((void **)&dIntArray[dev][1], MAX_READS_ON_GPU * sizeof(short)));

    	CUDA_CHECK_RETURN(cudaStreamCreate(&upload_stream[dev]));                                   // create streams on devices
    	CUDA_CHECK_RETURN(cudaStreamCreate(&compute_stream[dev]));
    	CUDA_CHECK_RETURN(cudaStreamCreate(&download_stream[dev]));

    	CUDA_CHECK_RETURN(cudaEventCreateWithFlags(&QUAL_COPY_DONE[dev], cudaEventDisableTiming || cudaEventBlockingSync));  // events for device host synchronization
    	CUDA_CHECK_RETURN(cudaEventCreateWithFlags(&SEQ_COPY_DONE[dev], cudaEventDisableTiming));
    	CUDA_CHECK_RETURN(cudaEventCreateWithFlags(&TrimmQ_DONE[dev], cudaEventDisableTiming));
    	CUDA_CHECK_RETURN(cudaEventCreateWithFlags(&TrimmA_DONE[dev], cudaEventDisableTiming));
    	CUDA_CHECK_RETURN(cudaEventCreateWithFlags(&DTH_COPY_DONE[dev], cudaEventDisableTiming || cudaEventBlockingSync));

        if(verbose) printf("[%d] Allocating pinned CPU memory for reads\n", dev);
        CUDA_CHECK_RETURN(cudaMallocHost((void **) &hReadLen[dev][0], MAX_READS_ON_GPU * sizeof(short)));   // allocate two buffers for reads length
        CUDA_CHECK_RETURN(cudaMallocHost((void **) &hReadLen[dev][1], MAX_READS_ON_GPU * sizeof(short)));

        CUDA_CHECK_RETURN(cudaMallocHost((void **) &hReadSequence[dev][0], MAX_READS_ON_GPU * MAX_READ_LENGTH * sizeof(char)));   // two buffers for reads sequence
        CUDA_CHECK_RETURN(cudaMallocHost((void **) &hReadSequence[dev][1], MAX_READS_ON_GPU * MAX_READ_LENGTH * sizeof(char)));

        CUDA_CHECK_RETURN(cudaMallocHost((void **) &hReadQualstr[dev], MAX_READS_ON_GPU * MAX_READ_LENGTH * sizeof(char))); // one buffer for qualities

    }
}

void FreeGPUs(void)
{
    for (int dev=0; dev<numGPUs; dev++)                         // release cuda resources from all devices
    {
    	CUDA_CHECK_RETURN(cudaSetDevice(device[dev]));

    	CUDA_CHECK_RETURN(cudaEventDestroy(QUAL_COPY_DONE[dev]));
    	CUDA_CHECK_RETURN(cudaEventDestroy(SEQ_COPY_DONE[dev]));
    	CUDA_CHECK_RETURN(cudaEventDestroy(TrimmQ_DONE[dev]));
    	CUDA_CHECK_RETURN(cudaEventDestroy(TrimmA_DONE[dev]));
    	CUDA_CHECK_RETURN(cudaEventDestroy(DTH_COPY_DONE[dev]));
    	CUDA_CHECK_RETURN(cudaStreamDestroy(upload_stream[dev]));
    	CUDA_CHECK_RETURN(cudaStreamDestroy(compute_stream[dev]));
    	CUDA_CHECK_RETURN(cudaStreamDestroy(download_stream[dev]));

    	CUDA_CHECK_RETURN(cudaFree(dIntArray[dev][0]));
    	CUDA_CHECK_RETURN(cudaFree(dIntArray[dev][1]));
    	CUDA_CHECK_RETURN(cudaFree(dSequenceArray[dev]));
    	CUDA_CHECK_RETURN(cudaFree(dQualArray[dev]));

        cudaFreeHost(hReadLen[dev][0]);                        // free all page locked host memory
        cudaFreeHost(hReadLen[dev][1]);
        cudaFreeHost(hReadSequence[dev][0]);
        cudaFreeHost(hReadSequence[dev][1]);
        cudaFreeHost(hReadQualstr[dev]);
    }

}

int FindGPUs(void)
{
    int deviceCount;
    numGPUs = 0;
    CUDA_CHECK_RETURN(cudaGetDeviceCount(&deviceCount)); // search cuda devices and identify compute 3.5 with 6 GB
    if (deviceCount == 0) return(0);

    for (int dev=0; dev<deviceCount; dev++)
    {
    	cudaSetDevice(dev);
    	cudaDeviceProp deviceProp;
    	cudaGetDeviceProperties(&deviceProp, dev);

    	int driverVersion, runtimeVersion;
    	cudaDriverGetVersion(&driverVersion);
    	cudaRuntimeGetVersion(&runtimeVersion);

        if(((deviceProp.major == 3 && deviceProp.minor >= 5) || (deviceProp.major > 3)) && deviceProp.totalGlobalMem > 6144000000)
        {
            if(verbose)
            {
            	printf("\nDevice %d: %s\n", dev, deviceProp.name);
        	    printf("  CUDA Driver / Runtime Version:     %d.%d / %d.%d\n", driverVersion/1000, (driverVersion%100)/10, runtimeVersion/1000, (runtimeVersion%100)/10);
        	    printf("  CUDA Compute Capability:           %d.%d\n", deviceProp.major, deviceProp.minor);
                    printf("  PCI bus ID:                        %d:%d\n", deviceProp.pciBusID, deviceProp.pciDeviceID);
        	    printf("  Total amount of global memory:     %.0f MBytes (%llu bytes)\n", (float)deviceProp.totalGlobalMem/1048576.0f, (unsigned long long) deviceProp.totalGlobalMem);
        	    printf("  Number of Multiprocessors:         %d\n", deviceProp.multiProcessorCount);
            }
        	device[numGPUs] = dev;
        	numGPUs++;
        	if (numGPUs >= MAX_GPU_NUM) break;
        }
    }
    return(numGPUs);
}

void OpenFiles()
{
    // handle compression using zlib gzFile functions for input and pipe gzip for output

    if(!overwrite_outputfile)       // test if output file exists if option -f is not specified
    {
        outputFile = fopen(output_filename, "r");
    	if(outputFile!=NULL)
    	{
    		printf("ERROR output file exists already. To overwrite run with option -f\n");
    		exit(255);
    	}  // do not attempt close file as we would have already exited if opening was successful !
    }
	inputFile = gzopen(input_filename, "r");
    if(inputFile == NULL)
    {
    	printf("ERROR opening input file: %s\n", input_filename);
    	exit(255);
    }
	templateFile = gzopen(input_filename, "r");  // holds a second access to input read file for rereading positions for output
    if(templateFile == NULL)
    {
    	printf("ERROR opening second handle to input file.\n");
    	exit(255);
    }
    if(write_pigz_output)
    {
    	outputFile = popen(strcat(PIGZ_PIPE, output_filename), "w");
        if(outputFile == NULL)
        {
        	printf("Option -pigz: could not open pipe ... falling back on libz.\n\tMake sure pigz is installed with: sudo apt-get install pigz\n");
        	write_gz_output = true;
        	write_pigz_output = false;
        }
    }
	if(write_gz_output && !write_pigz_output)
	{
		outputFile = popen(strcat(GZIP_PIPE, output_filename), "w");
        if(outputFile == NULL)
        {
        	printf("Option -gz: could not open pipe ... falling back to uncompressed output.\n");
        	write_gz_output = false;
        }
	}
	if(!write_gz_output && !write_pigz_output) outputFile = fopen(output_filename, "w");
    if(outputFile == NULL)
    {
    	printf("ERROR opening output file: %s\n", output_filename);
    	exit(255);
    }
}

int ReadBlockOfReads(int max_num_to_read, short *hReadLen, char* hReadSequence, char *hReadQualstr)
{
	int n = 0;                                                                    // returns the number of reads read
	short length;

    while(gzgets(inputFile, Read.name, MAX_FASTQ_BUF_LINE) != NULL)
    {
    	if(Read.name[0] == 13) break;				// end if CR <13> or LF <10> are encountered
    	if(Read.name[0] == 10) break;
    	if(gzgets(inputFile, Read.sequence, MAX_FASTQ_BUF_LINE)==NULL)
        {
            printf("ERROR parsing input!\n");
            exit(255);
        }
        if(gzgets(inputFile, Read.descr, MAX_FASTQ_BUF_LINE)==NULL)
        {
            printf("ERROR parsing input!\n");
            exit(255);
        }
        if(gzgets(inputFile, Read.qualstr, MAX_FASTQ_BUF_LINE)==NULL)
        {
            printf("ERROR parsing input!\n");
            exit(255);
        }

        if(!FastQ_WARNING)                         // write warning if FastQ file contains non-standard lines
        {
            if(Read.name[0]!='@' || Read.descr[0]!='+')
            {
            	printf("Warning: Encountered unusual line identifiers in FastQ file format.\n");
            	FastQ_WARNING = true;
            }
        }
        length = strlen(Read.sequence)-1;
        if(length > MAX_READ_LENGTH) length = MAX_READ_LENGTH;

//        printf("%d, ", length);

        memcpy(&hReadSequence[n*MAX_READ_LENGTH], Read.sequence, length);
        memcpy(&hReadQualstr[n*MAX_READ_LENGTH], Read.qualstr, length);
        hReadLen[n] = length;

        n++;
        if(n == max_num_to_read) break;

    }
    hNumberOfReads = hNumberOfReads + n;                           // update global variable to total number of reads
    return(n);
}

int WriteBlockOfReads(int num_of_reads_to_write, const short *hReadLen, short min_out_read_length)
{
    int n=0;
    int w=0;
    short length;
    char str_buffer[MAX_FASTQ_BUF_LINE];

    if(num_of_reads_to_write == 0) return(0);
    if(verbose) printf("I/O > num_of_reads_to_write = %d\n", num_of_reads_to_write);
    while(gzgets(templateFile, Read.name, MAX_FASTQ_BUF_LINE) != NULL)
    {
        if(gzgets(templateFile, Read.sequence, MAX_FASTQ_BUF_LINE)==NULL)
        {
            printf("ERROR parsing input file for writing trimmed output!\n");
            exit(255);
        }
        if(gzgets(templateFile, Read.descr, MAX_FASTQ_BUF_LINE)==NULL)
        {
            printf("ERROR parsing input file for writing trimmed output!\n");
            exit(255);
        }
        if(gzgets(templateFile, Read.qualstr, MAX_FASTQ_BUF_LINE)==NULL)
        {
            printf("ERROR parsing input file for writing trimmed output!\n");
            exit(255);
        }

        length = hReadLen[n];

        if(gRNATrimming)                         // isolate the gRNA from adaptor match
        {
        	if(length>0)
        	{
        		strncpy(str_buffer, &Read.sequence[length+gRNA_start], gRNA_length);
        		strncpy(&Read.sequence[0], str_buffer, gRNA_length);
        		Read.sequence[gRNA_length]=10;
        		Read.sequence[gRNA_length+1]=0;
        		strncpy(str_buffer, &Read.qualstr[length+gRNA_start], gRNA_length);
        		strncpy(&Read.qualstr[0], str_buffer, gRNA_length);
        		Read.qualstr[gRNA_length]=10;
        		Read.qualstr[gRNA_length+1]=0;

                fprintf(outputFile,"%s", Read.name);
                fprintf(outputFile,"%s", Read.sequence);
                fprintf(outputFile,"%s", Read.descr);
                fprintf(outputFile,"%s", Read.qualstr);

                w++;
        	}
        }
        else                                     // normal quality and adaptor trimming
        {
            if(length >= min_out_read_length)
            {
                Read.sequence[length]=10;        // write only reads that are longer than minimum to output file
                Read.sequence[length+1]=0;
                Read.qualstr[length]=10;
                Read.qualstr[length+1]=0;

                fprintf(outputFile,"%s", Read.name);
                fprintf(outputFile,"%s", Read.sequence);
                fprintf(outputFile,"%s", Read.descr);
                fprintf(outputFile,"%s", Read.qualstr);

                w++;
             }
        }

        n++;
        if(n == num_of_reads_to_write) break;
    }
    hReadsWritten = hReadsWritten + w;
    return(n);
}

void CloseFiles(void)
{
    gzclose(inputFile);
    gzclose(templateFile);
    if(write_gz_output || write_pigz_output) pclose(outputFile); else fclose(outputFile);
}

bool Detect_FastQ_Format_PHRED(void)
{
	int n = 0;                                                                    // returns the number of reads read
	short length;
	uint min_qual = 65;
	uint max_qual = 65;
	bool deciphered = false;

	inputFile = gzopen(input_filename, "r");
    if(inputFile == NULL)
    {
    	printf("ERROR opening input file %s\n", input_filename);
    	exit(255);
    }

    while(gzgets(inputFile, Read.name, MAX_FASTQ_BUF_LINE) != NULL)
    {
    	if(Read.name[0] == 13) break;				// end if CR <13> or LF <10> are encountered
    	if(Read.name[0] == 10) break;
    	if(gzgets(inputFile, Read.sequence, MAX_FASTQ_BUF_LINE)==NULL)
        {
            printf("ERROR parsing input!\n");
            exit(255);
        }
        if(gzgets(inputFile, Read.descr, MAX_FASTQ_BUF_LINE)==NULL)
        {
            printf("ERROR parsing input!\n");
            exit(255);
        }
        if(gzgets(inputFile, Read.qualstr, MAX_FASTQ_BUF_LINE)==NULL)
        {
            printf("ERROR parsing input!\n");
            exit(255);
        }

        if(!FastQ_WARNING)                         // write warning if FastQ file contains non-standard lines
        {
            if(Read.name[0]!='@' || Read.descr[0]!='+')
            {
            	printf("Warning: Encountered unusual line identifiers in FastQ file format.");
            	FastQ_WARNING = true;
            }
        }
        length = strlen(Read.sequence)-1;

        for(n=0; n<length;n++)
        {
        	if(min_qual > (uint)Read.qualstr[n])
        	{
        		min_qual = (uint) Read.qualstr[n];
        	}
        	else
        	{
            	if(max_qual < (uint)Read.qualstr[n]) max_qual = (uint) Read.qualstr[n];

        	}
        }
        if(min_qual < 59)
        {
        	PHRED = 33;                                    // FastQ Sanger and Illumina 1.8+ format
        	deciphered = true;
        	break;
        }
        if(max_qual > 80)
        {
        	PHRED = 64;                                    // FastQ Illumina 1.3+ format
        	deciphered = true;
        	break;
        }
    }

    gzclose(inputFile);
    return(deciphered);
}

int PreprocessReadsOnGPU(void)
{
	bool DONE = false;
	bool ALL_DONE = false;

	int ReadsProcessed = 0;
    int ReadsToProcess[MAX_GPU_NUM];
    int ReadsSentToGPU[MAX_GPU_NUM];
    int dev_side = 0;                             // left or right side of device memories [0] or [1]
    int dev_next_side = 1;
    int side_flip;

    if(verbose) printf("\nPreprocessing reads on GPU\n");


    for(int dev=0; dev<numGPUs; dev++)                         // copy data and run kernels initial round to fill CUDA queue and not waste time !
    {
    	ReadsToProcess[dev] = 0;
    	ReadsSentToGPU[dev] = 0;
    	if(!DONE)
        {
        	ReadsToProcess[dev] = ReadBlockOfReads(MAX_READS_ON_GPU, hReadLen[dev][dev_side], hReadSequence[dev][dev_side], hReadQualstr[dev]);

            if(ReadsToProcess[dev] < MAX_READS_ON_GPU)
            {
            	DONE = true;
            }
            if(ReadsToProcess[dev] == 0) continue;

    	    CUDA_CHECK_RETURN(cudaSetDevice(device[dev]));

    	    if(QualityTrimming) CUDA_CHECK_RETURN(cudaMemcpyAsync(dQualArray[dev], hReadQualstr[dev], ReadsToProcess[dev] * MAX_READ_LENGTH * sizeof(char), cudaMemcpyHostToDevice, upload_stream[dev]));
    	    CUDA_CHECK_RETURN(cudaMemcpyAsync(dIntArray[dev][dev_side], hReadLen[dev][dev_side], ReadsToProcess[dev] * sizeof(short), cudaMemcpyHostToDevice, upload_stream[dev]));
    	    CUDA_CHECK_RETURN(cudaEventRecord(QUAL_COPY_DONE[dev], upload_stream[dev]));

    	    CUDA_CHECK_RETURN(cudaStreamWaitEvent(compute_stream[dev], QUAL_COPY_DONE[dev], 0));
    	    if(QualityTrimming)
    	    {
    	    	if(verbose) printf("[%d] TrimmQuals\n", device[dev]);
    	    	TrimmQuals<<<4096, 256, 0, compute_stream[dev]>>>(dQualArray[dev], dIntArray[dev][dev_side], ReadsToProcess[dev], MAX_READ_LENGTH);
    	    	CUDA_CHECK_RETURN(cudaGetLastError());
    	    }
    	    CUDA_CHECK_RETURN(cudaEventRecord(TrimmQ_DONE[dev], compute_stream[dev]));

    	    if(AdaptorTrimming || gRNATrimming) CUDA_CHECK_RETURN(cudaMemcpyAsync(dSequenceArray[dev], hReadSequence[dev][dev_side], ReadsToProcess[dev] * MAX_READ_LENGTH * sizeof(char), cudaMemcpyHostToDevice, upload_stream[dev]));
    	    CUDA_CHECK_RETURN(cudaEventRecord(SEQ_COPY_DONE[dev], upload_stream[dev]));

    	    CUDA_CHECK_RETURN(cudaStreamWaitEvent(compute_stream[dev], SEQ_COPY_DONE[dev], 0));
    	    if(gRNATrimming)
    	    {
    	    	if(verbose) printf("[%d] Find_gRNA\n", device[dev]);
    	        Find_gRNA<<<4096, 256, 0, compute_stream[dev]>>>(dSequenceArray[dev], dIntArray[dev][dev_side], ReadsToProcess[dev], MAX_READ_LENGTH);
    	        CUDA_CHECK_RETURN(cudaGetLastError());
    	    }
    	    else
    	    {
    	    	if(AdaptorTrimming)
    	    	{
    	    		if(verbose) printf("[%d] TrimmAdaptors\n", device[dev]);
    	    		TrimmAdaptors<<<4096, 256, 0, compute_stream[dev]>>>(dSequenceArray[dev], dIntArray[dev][dev_side], ReadsToProcess[dev], MAX_READ_LENGTH);
    	    		CUDA_CHECK_RETURN(cudaGetLastError());
    	    	}
    	    }
    	    CUDA_CHECK_RETURN(cudaEventRecord(TrimmA_DONE[dev], compute_stream[dev]));

    	    CUDA_CHECK_RETURN(cudaStreamWaitEvent(download_stream[dev], TrimmA_DONE[dev], 0));
    	    CUDA_CHECK_RETURN(cudaMemcpyAsync(hReadLen[dev][dev_side], dIntArray[dev][dev_side], ReadsToProcess[dev] * sizeof(short), cudaMemcpyDeviceToHost, download_stream[dev]));
    	    CUDA_CHECK_RETURN(cudaEventRecord(DTH_COPY_DONE[dev], download_stream[dev]));
    	    if(verbose) printf("[%d] Memcpy DtoH %d reads\n", device[dev], ReadsToProcess[dev]);

    	    ReadsSentToGPU[dev] = ReadsToProcess[dev];
    	    ReadsToProcess[dev] = 0;
       }
    }

    while(!ALL_DONE)
    {
    	ALL_DONE = true;                                            // setup for test if should stop if there is no more data on the GPU

    	if(!DONE)
        {
            for(int dev=0; dev<numGPUs; dev++)                         // read a block of data, copy QUALS to GPU and run QUAL kernel
        	{
            	ReadsToProcess[dev] = 0;

        	    CUDA_CHECK_RETURN(cudaSetDevice(device[dev]));

            	if(ReadsSentToGPU[dev]>0)
            	{
            		CUDA_CHECK_RETURN(cudaEventSynchronize(TrimmQ_DONE[dev]));
            	}

            	ReadsToProcess[dev] = ReadBlockOfReads(MAX_READS_ON_GPU, hReadLen[dev][dev_next_side], hReadSequence[dev][dev_next_side], hReadQualstr[dev]);
                if(ReadsToProcess[dev] < MAX_READS_ON_GPU)
                {
                	DONE = true;
                }
                if(ReadsToProcess[dev] == 0) break;

                ALL_DONE = false;                                      // there is more work on the GPUs that requires further processing

                if(QualityTrimming) CUDA_CHECK_RETURN(cudaMemcpyAsync(dQualArray[dev], hReadQualstr[dev], ReadsToProcess[dev] * MAX_READ_LENGTH * sizeof(char), cudaMemcpyHostToDevice, upload_stream[dev]));
        	    CUDA_CHECK_RETURN(cudaMemcpyAsync(dIntArray[dev][dev_next_side], hReadLen[dev][dev_next_side], ReadsToProcess[dev] * sizeof(short), cudaMemcpyHostToDevice, upload_stream[dev]));
        	    CUDA_CHECK_RETURN(cudaEventRecord(QUAL_COPY_DONE[dev], upload_stream[dev]));

        	    CUDA_CHECK_RETURN(cudaStreamWaitEvent(compute_stream[dev], QUAL_COPY_DONE[dev], 0));
        	    if(QualityTrimming)
        	    {
        	    	if(verbose) printf("[%d] TrimmQuals\n", device[dev]);
        	    	TrimmQuals<<<4096, 256, 0, compute_stream[dev]>>>(dQualArray[dev], dIntArray[dev][dev_next_side], ReadsToProcess[dev], MAX_READ_LENGTH);
        	    	CUDA_CHECK_RETURN(cudaGetLastError());
        	    }
        	}
        }

        for(int dev=0; dev<numGPUs; dev++)                         // copy sequence and run Adaptor trim kernel
    	{
        	if(ReadsToProcess[dev]>0)
        	{
        	    CUDA_CHECK_RETURN(cudaSetDevice(device[dev]));

        	    if(ReadsSentToGPU[dev]>0)
        	    {
            	    CUDA_CHECK_RETURN(cudaEventSynchronize(TrimmA_DONE[dev]));
        	    }

        	    if(AdaptorTrimming || gRNATrimming) CUDA_CHECK_RETURN(cudaMemcpyAsync(dSequenceArray[dev], hReadSequence[dev][dev_next_side], ReadsToProcess[dev] * MAX_READ_LENGTH * sizeof(char), cudaMemcpyHostToDevice, upload_stream[dev]));
        	    CUDA_CHECK_RETURN(cudaEventRecord(SEQ_COPY_DONE[dev], upload_stream[dev]));

        	    CUDA_CHECK_RETURN(cudaStreamWaitEvent(compute_stream[dev], SEQ_COPY_DONE[dev], 0));
        	    if(gRNATrimming)
        	    {
        	    	if(verbose) printf("[%d] Find_gRNA\n", device[dev]);
        	    	Find_gRNA<<<4096, 256, 0, compute_stream[dev]>>>(dSequenceArray[dev], dIntArray[dev][dev_next_side], ReadsToProcess[dev], MAX_READ_LENGTH);
        	    	CUDA_CHECK_RETURN(cudaGetLastError());
        	    }
        	    else
        	    {
        	    	if(AdaptorTrimming)
        	    	{
        	    		if(verbose) printf("[%d] TrimmAdaptors\n", device[dev]);
        	    		TrimmAdaptors<<<4096, 256, 0, compute_stream[dev]>>>(dSequenceArray[dev], dIntArray[dev][dev_next_side], ReadsToProcess[dev], MAX_READ_LENGTH);
        	    		CUDA_CHECK_RETURN(cudaGetLastError());
        	    	}
        	    }
        	    CUDA_CHECK_RETURN(cudaEventRecord(TrimmA_DONE[dev], compute_stream[dev]));
        	}
    	}

        for(int dev=0; dev<numGPUs; dev++)                          // copy data from devices and write output file
    	{
            if(verbose) printf("[%d] > ReadsSentToGPU = %d\n", dev, ReadsSentToGPU[dev]);

        	if(ReadsSentToGPU[dev]>0)
        	{
        	    CUDA_CHECK_RETURN(cudaSetDevice(device[dev]));
        		CUDA_CHECK_RETURN(cudaEventSynchronize(DTH_COPY_DONE[dev]));
        		if(verbose) printf("[%d] Writing hReadLen[%d][%d]\n", device[dev], dev, dev_side);
        	    WriteBlockOfReads(ReadsSentToGPU[dev], hReadLen[dev][dev_side], MIN_OUT_READ_LEN);    // write output block
        	    ReadsProcessed += ReadsSentToGPU[dev];             // count how many reads were considered for writing - actual output has minimal length requirement
        	}

        	if(ReadsToProcess[dev]>0)
        	{
        	    CUDA_CHECK_RETURN(cudaStreamWaitEvent(download_stream[dev], TrimmA_DONE[dev], 0));
        	    CUDA_CHECK_RETURN(cudaMemcpyAsync(hReadLen[dev][dev_next_side], dIntArray[dev][dev_next_side], ReadsToProcess[dev] * sizeof(short), cudaMemcpyDeviceToHost, download_stream[dev]));
        	    CUDA_CHECK_RETURN(cudaEventRecord(DTH_COPY_DONE[dev], download_stream[dev]));
        	    if(verbose) printf("[%d] Memcpy DtoH %d reads\n", device[dev], ReadsToProcess[dev]);
        	}
    	    ReadsSentToGPU[dev] = ReadsToProcess[dev];
    	    ReadsToProcess[dev] = 0;
    	}
        side_flip = dev_side;                                      // dev_side alternate between 0 and 1 to use memory efficiently
        dev_side = dev_next_side;
        dev_next_side = side_flip;
    }
    return(ReadsProcessed);
}

void usage_help(void)
{
	printf("\nPreprocessReads multi-GPU version\n");
	printf("\tsupports up to 4 NVIDIA GPUs with compute capability greater than 3.5 and at least 6 GB memory.\n");
	printf("\tcompiled for minimum CUDA API 6.5 (build 20210107).\n");
	printf("\nProgram Options:\n\n");
	printf("\t-i, -I ....... specify the path for the input file [required]\n");
	printf("\t-o, -O ....... specify the path for the output file [required]\n");
	printf("\t-len, -Len ... specify the minimum length for reads written to the output file\n");
	printf("\t-f ........... over write output file if it exists\n");
	printf("\t-gz .......... write output to file in compressed format (.gz)\n");
	printf("\t-pigz ........ write output to file in compressed format (.gz) using multithreaded compression\n");
	printf("\t-v, -V ....... verbose, prints details on processing to screen\n");
	printf("\t-a, -A ....... adaptor sequence, can contain Ns that will match any base in the read\n");
	printf("\t-mm, -MM ..... number of mismatches allowed in adaptor search (not including Ns)\n");
	printf("\t-Phred ....... sets the base of the qualities PHRED values [default 33], use AUTO for autodetection\n");
	printf("\t-Qmin ........ sets the minimum acceptable quality score for a good base [default 20]\n");
	printf("\t-Qualab ...... sets the minimum average base quality score for remainder of the read after a bad base [default 25]\n");
	printf("\t-dev, -Dev ... specify CUDA device to use (can be used repeatedly for selecting multiple GPUs,\n");
	printf("\t               if not specified an automatic search for GPUs with compute capability 3.5 and 6 GB memory is performed)\n");
	printf("\nAlgorithm selection:\n\n");
	printf("\t/TA .......... select adaptor trimming only (can be also used before option /gRNA to avoid quality trimming)\n");
	printf("\t/TQ .......... select quality trimming only\n");
	printf("\t/TAQ ......... select quality and adaptor trimming [default]\n");
	printf("\t/gRNA ........ select gRNA recovery, followed by start relative to start of adaptor sequence and length of gRNA to be retrieved\n");
	printf("\t               ( /gRNA 12 20 will retrieve 20 nucleotide read sequence starting 12 positions after the 5' end match of adaptor)\n");
	printf("\nProgrammer options variables:\n");
	printf("\t-G ........... set MAX_READS_ON_GPU variable\n");
	printf("\t-R ........... set MAX_READ_LENGTH variable\n");
	printf("\nexample usage:\n");
	printf("\tPreprocessReads -dev 0 -dev 1 -i infile.fastq -o outfilename.fastq -len 26 -a ATTAGATCGATGCTA -mm 2\n\n");
	exit(3);
}

void invalid_command_line_option(const char *errorstr)
{
	printf("\nERROR %s\n", errorstr);
	printf("\nUsage ----------------------------------------------\n");
	usage_help();
}

void parseCommandLineArguments(int argc, char *argv[])
{
	bool inputfile_set = false;
	bool outputfile_set = false;
	bool adaptor_set = false;
	bool mismatch_set = false;
	bool outlen_set = false;
	for(int n=1; n<argc; n++)
	{
		if(argv[n][0] == '-')
		{
			char a = argv[n][1];
			switch (a)
			{
				case 'I':
				case 'i':
					if(inputfile_set) invalid_command_line_option("option -i: input file name already specified.");
					if(++n<argc)
					{
						if(strlen(argv[n])>400) invalid_command_line_option("option -i: input file path length exceeds limit.");
						strcpy(input_filename, argv[n]);
						inputfile_set=true;
						break;
					}
					else invalid_command_line_option("option -i: INPUT file name missing.");
					break;
				case 'O':
				case 'o':
					if(outputfile_set) invalid_command_line_option("option -o: output file name already specified.");
					if(++n<argc)
					{
						if(strlen(argv[n])>400) invalid_command_line_option("option -o: output file path length exceeds limit.");
						strcpy(output_filename, argv[n]);
						outputfile_set=true;
						break;
					}
					else invalid_command_line_option("option -o: OUTPUT file name missing.");
					break;
				case 'l':
				case 'L':
					if(argv[n][2]!='e' || argv[n][3]!='n') invalid_command_line_option("invalid command line option encountered.");
					if(outlen_set) invalid_command_line_option("option -len: minimum read length to include in output file is already specified.");
					if(++n<argc)
					{
						int ol=atoi(argv[n]);
						if(ol<0 || ol>MAX_READ_LENGTH) invalid_command_line_option("option -len: encountered invalid minimum read length to include in output file.");
						MIN_OUT_READ_LEN = (short) ol;
						outlen_set=true;
						break;
					}
					else invalid_command_line_option("option -len: expected minimum output read length not found.");
					break;

				case 'A':
				case 'a':
					if(adaptor_set) invalid_command_line_option("option -a: adaptor sequence already specified.");
					if(++n<argc)
					{
						if(strlen(argv[n])>MAX_ADAPTOR_LENGTH) invalid_command_line_option("option -a: adaptor sequence length exceeds limit.");
						if(strlen(argv[n])<3) invalid_command_line_option("option -a: adaptor sequence length too short.");
						strcpy(Adaptor, argv[n]);
						adaptor_set=true;
						break;
					}
					else invalid_command_line_option("option -a: expected adaptor sequence.");
					break;
				case 'M':
				case 'm':
					if(argv[n][2]!='m' && argv[n][2]!='M') invalid_command_line_option("invalid command line option encountered.");
					if(mismatch_set) invalid_command_line_option("option -mm: number of mismatches is already specified.");
					if(++n<argc)
					{
						int mm=atoi(argv[n]);
						if(mm>20) invalid_command_line_option("option -mm: number of mismatches exceeds limit.");
						mismatches = (short) mm;
						mismatch_set=true;
						break;
					}
					else invalid_command_line_option("option -mm: expected number of mismatches not found.");
					break;
				case 'd':
				case 'D':
					if(argv[n][2]!='e' || argv[n][3]!='v') invalid_command_line_option("invalid command line option encountered.");
					if(numGPUs>=MAX_GPU_NUM) invalid_command_line_option("option -dev: number of CUDA devices exceeds maximum.");
					if(++n<argc)
					{
						int d=atoi(argv[n]);
						if(d<0 || d>20) invalid_command_line_option("option -dev: invalid device number.");
						device[numGPUs] = d;
						numGPUs++;
						break;
					}
					else invalid_command_line_option("option -dev: expected CUDA device number not found.");
					break;
				case 'f':
					overwrite_outputfile = true;                                        // -f
					break;
				case 'g':                                                               // -gz
					if((argv[n][2]=='z') && (strlen(argv[n])==3))
					{
						write_gz_output = true;
						break;
					}
					else invalid_command_line_option("invalid command line option encountered.");
					break;
				case 'p':
				case 'P':
					if((strcmp(argv[n], "-Pigz")==0) || (strcmp(argv[n], "-pigz")==0))  // -pigz
					{
						write_pigz_output = true;
						break;
					}
					else                                                                // -phred
					{
						if(argv[n][2]!='h' || argv[n][3]!='r' || argv[n][4]!='e' || argv[n][5]!='d') invalid_command_line_option("invalid command line option encountered.");
						if(++n<argc)
						{
							if((strcmp(argv[n], "AUTO")==0) || (strcmp(argv[n], "auto")==0))
							{
								auto_phred_detect = true;
								break;
							}
							else
							{
								int d=atoi(argv[n]);
								if(d<0 || d>100) invalid_command_line_option("option -Phred: invalid phred base.");
								PHRED = d;
								break;
							}
						}
						else invalid_command_line_option("option -phred: expected number or AUTO not found.");
					}
					break;
				case 'Q':
				case 'q':
					if((strcmp(argv[n], "-Qmin")==0) || (strcmp(argv[n], "-qmin")==0))
					{
						if(++n<argc)
						{
							int qm=atoi(argv[n]);
							if(qm<10 || qm>64) invalid_command_line_option("option -qmin: outside 10 to 64 limit.");
							MIN_BASE_QUAL = (short) qm;
							break;
						}
						else invalid_command_line_option("option -qmin: expected number not found.");
					}
					else
					{
						if((strcmp(argv[n], "-Qualab")==0) || (strcmp(argv[n], "-qualab")==0))
						{
							if(++n<argc)
							{
								int qm=atoi(argv[n]);
								if(qm<10 || qm>64) invalid_command_line_option("option -qualab: outside 10 to 64 limit.");
								MIN_QUAL_AFTER_BAD = (short) qm;
								break;
							}
							else invalid_command_line_option("option -qmin: expected number not found.");
						}
					}
					break;
				case 'v':
				case 'V':
					verbose = true;
					break;
				case 'H':
				case 'h':
				case '?':
					printf("\nHELP ----------------------------------------------\n");
					usage_help();
					break;
				case 'G':                                                           // programmer option to set MAX_NUM_READS_ON_GPU parameter
					if(++n<argc)
					{
						int mrg=atoi(argv[n]);
						if(mrg<=0) invalid_command_line_option("invalid command line option encountered.");
						MAX_READS_ON_GPU = mrg;
						break;
					}
					else invalid_command_line_option("invalid command line option encountered.");
					break;
				case 'R':                                                           // programmer option to set MAX_READ_LENGTH parameter
					if(++n<argc)
					{
						int mrl=atoi(argv[n]);
						if(mrl<=0 || mrl>10000) invalid_command_line_option("invalid command line option encountered.");
						MAX_READ_LENGTH = (short) mrl;
						break;
					}
					else invalid_command_line_option("invalid command line option encountered.");
					break;

				default:
					invalid_command_line_option("invalid command line option encountered.");
			}
		}
		else
		{
			if(argv[n][0] == '/')
			{
				char a = argv[n][1];
				switch (a)
				{
					case 'T':
						AdaptorTrimming = false;
						QualityTrimming = false;
						gRNATrimming = false;
						if(strlen(argv[n]) == 3)
						{
							if(argv[n][2]=='A')
							{
								AdaptorTrimming = true;
								break;
							}
							else
							{
								if(argv[n][2]=='Q')
								{
									QualityTrimming = true;
									break;
								}
								else invalid_command_line_option("option /T: algorithm selection is invalid.");
							}
						}
						else
						{
							if(strlen(argv[n])==3 && argv[n][2]=='A' && argv[n][3]=='Q')
							{
								AdaptorTrimming = true;
								QualityTrimming = true;
								break;
							}
							else invalid_command_line_option("option /T: algorithm selection is invalid.");
						}
						break;
					case 'g':
						if(strlen(argv[n]) == 5 && argv[n][2]=='R' && argv[n][3]=='N' && argv[n][4]=='A')
						{
							gRNATrimming = true;
							if(++n < argc)
							{
								gRNA_start = atoi(argv[n]);
							}
							else invalid_command_line_option("option /gRNA: expected start position relative to adaptor 5' not found.");
							if(++n < argc)
							{
								gRNA_length = atoi(argv[n]);
							}
							else invalid_command_line_option("option /gRNA: expected gRNA length not found.");
							break;
						}
						else invalid_command_line_option("option /g: algorithm selection is invalid.");
						break;
				}
			}
			else invalid_command_line_option("parsing command line options.");
		}
	}
	if(!inputfile_set || !outputfile_set || ((AdaptorTrimming || gRNATrimming) && !adaptor_set)) invalid_command_line_option("missing required command line options.");
	if(strcmp(input_filename, output_filename)==0)
	{
		printf("ERROR: encountered identical input and output file paths!\n");         // input file cannot be identical to output file
		exit(253);
	}
	printf("Setting parameters:\n");
	printf("\tInput file name  : %s\n", input_filename);
	printf("\tOutput file name : %s\n", output_filename);
	if(AdaptorTrimming || gRNATrimming) printf("\tAdaptor sequence : %s\n", Adaptor);
	if(verbose)
	{
		if(AdaptorTrimming || gRNATrimming) printf("\tMismatches = %d\n", mismatches);
		printf("\tTrimming: ");
		if(QualityTrimming) printf("Quality ");
		if(AdaptorTrimming) printf("Adaptors ");
		if(gRNATrimming) printf("Find gRNA");
		printf("\n");
		if(QualityTrimming)
		{
			printf("\tMinimum accepted base quality = %d; average quality of read after bad base = %d\n", MIN_BASE_QUAL, MIN_QUAL_AFTER_BAD);
		}
		printf("\tFastQ Quality Encoding: ");
		if(!auto_phred_detect) printf("PHRED+%d\n", PHRED); else printf("<AUTO DETECTION>\n");
		printf("\tMAX_READ_LENGTH  : %d\n", MAX_READ_LENGTH);
		printf("\tMinimum read length for output = %d\n", MIN_OUT_READ_LEN);
		if(overwrite_outputfile) printf("\tForce overwrite output file if it exists.\n");
	}
	if(numGPUs>0)
	{
		printf("\nUsing CUDA devices: ");
		for(int n=0; n<numGPUs; n++) printf("[%d]", device[n]);
		printf("\n");
	}
}

int main(int argc, char *argv[])
{
	time_t start_t = time(NULL);                        // for timing the process
	time_t end_t;
    int reads_processed = 0;

    parseCommandLineArguments(argc, argv);                        // get parameters from the command line
    if(numGPUs == 0)
    {
        if(FindGPUs() == 0)                             // check for GPUs
        {
            printf("\nERROR: No suitable CUDA devices found ... exiting\n");
            exit(1);
        }
        else
        {
            if(numGPUs == 1)
            	printf("\nOne CUDA device with at least compute capability 3.5 and 6 GB memory found.\n");
            else
                printf("\n%d CUDA devices with at least compute capability 3.5 and 6 GB memory found.\n", numGPUs);
        }
    }

    if(auto_phred_detect)
    {
    	if(Detect_FastQ_Format_PHRED())
    	{
    		if(verbose) printf("<AUTO DETECTION> FastQ Quality Encoding: PHRED+%d\n", PHRED);
    	}
    	else
    	{
    		printf("\nERROR: Unable to detect FastQ format version.\n");
    		exit(32);
    	}
    }

    OpenFiles();                                    // access files
    InitGPUs();
    SetAdaptorSequence(Adaptor, mismatches, PHRED, MIN_BASE_QUAL, MIN_QUAL_AFTER_BAD);

    reads_processed = PreprocessReadsOnGPU();

    printf("\nReads processed: %d\n", reads_processed);
    printf("Reads in input file %s : %d\n",input_filename, hNumberOfReads);
    printf("Reads written to output file %s : %d\n", output_filename, hReadsWritten);
    if(FastQ_WARNING) printf("Encountered potential issues with the FastQ file format in %s\n", input_filename);

    CloseFiles();
    FreeGPUs();

    end_t = time(NULL);
    printf("\nTotal time elapsed: %.0lf seconds\n", difftime(end_t, start_t));
//    printf("\n<Press RTN key to exit>\n");
//    getchar();

    return(0);
}

	.file	"tmpxft_00312a07_00000000-6_PreprocessReads.cudafe1.cpp"
	.text
#APP

#NO_APP
	.type	_ZL26__cudaUnregisterBinaryUtilv, @function
_ZL26__cudaUnregisterBinaryUtilv:
.LFB2056:
	.cfi_startproc
	endbr64
	movq	_ZL20__cudaFatCubinHandle(%rip), %rdi
	jmp	__cudaUnregisterFatBinary@PLT
	.cfi_endproc
.LFE2056:
	.size	_ZL26__cudaUnregisterBinaryUtilv, .-_ZL26__cudaUnregisterBinaryUtilv
	.section	.rodata.str1.1,"aMS",@progbits,1
.LC0:
	.string	"I/O > num_of_reads_to_write = %d\n"
.LC1:
	.string	"ERROR parsing input file for writing trimmed output!\n"
.LC2:
	.string	"%s"
	.text
	.type	_Z17WriteBlockOfReadsiPKss.part.0, @function
_Z17WriteBlockOfReadsiPKss.part.0:
.LFB2204:
	.cfi_startproc
	pushq	%r15
	.cfi_def_cfa_offset 16
	.cfi_offset 15, -16
	movq	%rsi, %r15
	pushq	%r14
	.cfi_def_cfa_offset 24
	.cfi_offset 14, -24
	pushq	%r13
	.cfi_def_cfa_offset 32
	.cfi_offset 13, -32
	pushq	%r12
	.cfi_def_cfa_offset 40
	.cfi_offset 12, -40
	movslq	%edi, %r12
	pushq	%rbp
	.cfi_def_cfa_offset 48
	.cfi_offset 6, -48
	pushq	%rbx
	.cfi_def_cfa_offset 56
	.cfi_offset 3, -56
	subq	$552, %rsp
	.cfi_def_cfa_offset 608
	movw	%dx, 14(%rsp)
	movq	%fs:40, %rax
	movq	%rax, 536(%rsp)
	xorl	%eax, %eax
	cmpb	$0, verbose(%rip)
	je	.L3
	movl	%r12d, %edx
	leaq	.LC0(%rip), %rsi
	movl	$2, %edi
	call	__printf_chk@PLT
.L3:
	xorl	%ebp, %ebp
	xorl	%r14d, %r14d
	leaq	Read(%rip), %rbx
.L4:
	movq	templateFile(%rip), %rdi
	movl	$500, %edx
	movq	%rbx, %rsi
	movl	%ebp, 8(%rsp)
	call	gzgets@PLT
	testq	%rax, %rax
	je	.L22
	movq	templateFile(%rip), %rdi
	movl	$500, %edx
	leaq	500+Read(%rip), %rsi
	call	gzgets@PLT
	testq	%rax, %rax
	jne	.L5
.L6:
	movl	$2, %edi
	leaq	.LC1(%rip), %rsi
	xorl	%eax, %eax
	call	__printf_chk@PLT
	movl	$255, %edi
	call	exit@PLT
.L5:
	movq	templateFile(%rip), %rdi
	movl	$500, %edx
	leaq	1000+Read(%rip), %rsi
	call	gzgets@PLT
	testq	%rax, %rax
	je	.L6
	movq	templateFile(%rip), %rdi
	movl	$500, %edx
	leaq	1500+Read(%rip), %rsi
	call	gzgets@PLT
	testq	%rax, %rax
	je	.L6
	cmpb	$0, gRNATrimming(%rip)
	movswq	(%r15,%rbp,2), %rax
	je	.L7
	testw	%ax, %ax
	jle	.L8
	movslq	gRNA_length(%rip), %r13
	addl	gRNA_start(%rip), %eax
	movl	$500, %ecx
	movslq	%eax, %r8
	leaq	36(%rsp), %rax
	leaq	500(%rbx,%r8), %rsi
	movq	%r13, %rdx
	movq	%rax, %rdi
	movq	%r8, 24(%rsp)
	movl	%r13d, 16(%rsp)
	movq	%rax, (%rsp)
	call	__strncpy_chk@PLT
	movq	(%rsp), %rsi
	movq	%r13, %rdx
	movl	$500, %ecx
	leaq	500+Read(%rip), %rdi
	call	__strncpy_chk@PLT
	movl	16(%rsp), %r9d
	movq	24(%rsp), %r8
	movq	%r13, %rdx
	movq	(%rsp), %rdi
	movl	$500, %ecx
	movb	$10, 500(%rbx,%r13)
	incl	%r9d
	leaq	1500(%rbx,%r8), %rsi
	movslq	%r9d, %r9
	movb	$0, 500(%rbx,%r9)
	movq	%r9, 16(%rsp)
	call	__strncpy_chk@PLT
	movq	(%rsp), %rsi
	movq	%r13, %rdx
	movl	$500, %ecx
	leaq	1500+Read(%rip), %rdi
	call	__strncpy_chk@PLT
	movq	16(%rsp), %r9
	movb	$10, 1500(%rbx,%r13)
	movb	$0, 1500(%rbx,%r9)
	jmp	.L20
.L7:
	cmpw	14(%rsp), %ax
	jl	.L8
	movswl	%ax, %edx
	movb	$10, 500(%rbx,%rax)
	incl	%edx
	movb	$10, 1500(%rbx,%rax)
	movslq	%edx, %rdx
	movb	$0, 500(%rbx,%rdx)
	movb	$0, 1500(%rbx,%rdx)
.L20:
	leaq	.LC2(%rip), %r13
	movq	%rbx, %rcx
	xorl	%eax, %eax
	incl	%r14d
	movq	outputFile(%rip), %rdi
	movq	%r13, %rdx
	movl	$2, %esi
	call	__fprintf_chk@PLT
	movq	%r13, %rdx
	movl	$2, %esi
	xorl	%eax, %eax
	movq	outputFile(%rip), %rdi
	leaq	500+Read(%rip), %rcx
	call	__fprintf_chk@PLT
	movq	%r13, %rdx
	movl	$2, %esi
	xorl	%eax, %eax
	movq	outputFile(%rip), %rdi
	leaq	1000+Read(%rip), %rcx
	call	__fprintf_chk@PLT
	movq	%r13, %rdx
	movl	$2, %esi
	xorl	%eax, %eax
	movq	outputFile(%rip), %rdi
	leaq	1500+Read(%rip), %rcx
	call	__fprintf_chk@PLT
.L8:
	incq	%rbp
	cmpq	%r12, %rbp
	jne	.L4
	movl	8(%rsp), %eax
	incl	%eax
	jmp	.L9
.L22:
	movl	%ebp, %eax
.L9:
	addl	%r14d, hReadsWritten(%rip)
	movq	536(%rsp), %rdx
	subq	%fs:40, %rdx
	je	.L11
	call	__stack_chk_fail@PLT
.L11:
	addq	$552, %rsp
	.cfi_def_cfa_offset 56
	popq	%rbx
	.cfi_def_cfa_offset 48
	popq	%rbp
	.cfi_def_cfa_offset 40
	popq	%r12
	.cfi_def_cfa_offset 32
	popq	%r13
	.cfi_def_cfa_offset 24
	popq	%r14
	.cfi_def_cfa_offset 16
	popq	%r15
	.cfi_def_cfa_offset 8
	ret
	.cfi_endproc
.LFE2204:
	.size	_Z17WriteBlockOfReadsiPKss.part.0, .-_Z17WriteBlockOfReadsiPKss.part.0
	.section	.rodata.str1.1
.LC3:
	.string	"[%d] Setting Adaptor sequence %s, length %d on GPU \n"
.LC4:
	.string	"/home/ubuntu/Datasets/stackv2/train-structured/zanton123/PreprocessReads/master/PreprocessReads.cu"
.LC5:
	.string	"Error %s at line %d in file %s\n"
.LC6:
	.string	"[%d] Setting mismatches %d, PHRED+%d on GPU \n"
.LC7:
	.string	"[%d] Setting minimum base quality %d, average read quality after bad %d on GPU \n"
	.text
	.globl	_Z18SetAdaptorSequencePKcssss
	.type	_Z18SetAdaptorSequencePKcssss, @function
_Z18SetAdaptorSequencePKcssss:
.LFB2040:
	.cfi_startproc
	endbr64
	pushq	%r13
	.cfi_def_cfa_offset 16
	.cfi_offset 13, -16
	pushq	%r12
	.cfi_def_cfa_offset 24
	.cfi_offset 12, -24
	leaq	device(%rip), %r12
	pushq	%rbp
	.cfi_def_cfa_offset 32
	.cfi_offset 6, -32
	movq	%rdi, %rbp
	pushq	%rbx
	.cfi_def_cfa_offset 40
	.cfi_offset 3, -40
	xorl	%ebx, %ebx
	subq	$40, %rsp
	.cfi_def_cfa_offset 80
	movw	%si, 12(%rsp)
	movl	$100, %esi
	movw	%dx, 8(%rsp)
	movw	%cx, 4(%rsp)
	movw	%r8w, (%rsp)
	movq	%fs:40, %rax
	movq	%rax, 24(%rsp)
	xorl	%eax, %eax
	call	strnlen@PLT
	movw	%ax, 22(%rsp)
.L24:
	cmpl	%ebx, numGPUs(%rip)
	movl	%ebx, %r13d
	jle	.L39
	movl	(%r12,%rbx,4), %edi
	call	cudaSetDevice@PLT
	cmpb	$0, verbose(%rip)
	je	.L25
	movswl	22(%rsp), %r8d
	movq	%rbp, %rcx
	movl	%r13d, %edx
	xorl	%eax, %eax
	leaq	.LC3(%rip), %rsi
	movl	$2, %edi
	call	__printf_chk@PLT
.L25:
	movswq	22(%rsp), %rdx
	leaq	_ZL7ADAPTOR(%rip), %rdi
	xorl	%ecx, %ecx
	movq	%rbp, %rsi
	movl	$1, %r8d
	call	cudaMemcpyToSymbol@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L26
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$103, %r8d
	movq	%rax, %rcx
	jmp	.L38
.L26:
	leaq	_ZL11ADAPTOR_LEN(%rip), %rdi
	leaq	22(%rsp), %rsi
	movl	$1, %r8d
	xorl	%ecx, %ecx
	movl	$2, %edx
	call	cudaMemcpyToSymbol@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L27
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$104, %r8d
	movq	%rax, %rcx
.L38:
	movq	stderr(%rip), %rdi
	leaq	.LC5(%rip), %rdx
	movl	$2, %esi
	xorl	%eax, %eax
	call	__fprintf_chk@PLT
	movl	$1, %edi
	call	exit@PLT
.L27:
	cmpb	$0, verbose(%rip)
	je	.L28
	movswl	12(%rsp), %ecx
	movswl	8(%rsp), %r8d
	movl	%r13d, %edx
	xorl	%eax, %eax
	leaq	.LC6(%rip), %rsi
	movl	$2, %edi
	call	__printf_chk@PLT
.L28:
	leaq	_ZL6MAX_MM(%rip), %rdi
	leaq	12(%rsp), %rsi
	movl	$1, %r8d
	xorl	%ecx, %ecx
	movl	$2, %edx
	call	cudaMemcpyToSymbol@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L29
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$106, %r8d
	movq	%rax, %rcx
	jmp	.L38
.L29:
	leaq	_ZL12QUAL_PADDING(%rip), %rdi
	leaq	8(%rsp), %rsi
	movl	$1, %r8d
	xorl	%ecx, %ecx
	movl	$2, %edx
	call	cudaMemcpyToSymbol@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L30
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$107, %r8d
	movq	%rax, %rcx
	jmp	.L38
.L30:
	cmpb	$0, verbose(%rip)
	je	.L31
	movswl	4(%rsp), %ecx
	movswl	(%rsp), %r8d
	movl	%r13d, %edx
	xorl	%eax, %eax
	leaq	.LC7(%rip), %rsi
	movl	$2, %edi
	call	__printf_chk@PLT
.L31:
	leaq	_ZL8MIN_QUAL(%rip), %rdi
	leaq	4(%rsp), %rsi
	movl	$1, %r8d
	xorl	%ecx, %ecx
	movl	$2, %edx
	call	cudaMemcpyToSymbol@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L32
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$109, %r8d
	movq	%rax, %rcx
	jmp	.L38
.L32:
	leaq	_ZL26MIN_AVERAGE_QUAL_AFTER_BAD(%rip), %rdi
	movq	%rsp, %rsi
	xorl	%ecx, %ecx
	incq	%rbx
	movl	$1, %r8d
	movl	$2, %edx
	call	cudaMemcpyToSymbol@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L24
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$110, %r8d
	movq	%rax, %rcx
	jmp	.L38
.L39:
	movq	24(%rsp), %rax
	subq	%fs:40, %rax
	je	.L34
	call	__stack_chk_fail@PLT
.L34:
	addq	$40, %rsp
	.cfi_def_cfa_offset 40
	popq	%rbx
	.cfi_def_cfa_offset 32
	popq	%rbp
	.cfi_def_cfa_offset 24
	popq	%r12
	.cfi_def_cfa_offset 16
	popq	%r13
	.cfi_def_cfa_offset 8
	ret
	.cfi_endproc
.LFE2040:
	.size	_Z18SetAdaptorSequencePKcssss, .-_Z18SetAdaptorSequencePKcssss
	.section	.rodata.str1.1
.LC8:
	.string	"\n"
.LC9:
	.string	"[%d] Initializing GPU\n"
.LC10:
	.string	"[%d] Allocating pinned CPU memory for reads\n"
	.text
	.globl	_Z8InitGPUsv
	.type	_Z8InitGPUsv, @function
_Z8InitGPUsv:
.LFB2041:
	.cfi_startproc
	endbr64
	pushq	%r15
	.cfi_def_cfa_offset 16
	.cfi_offset 15, -16
	pushq	%r14
	.cfi_def_cfa_offset 24
	.cfi_offset 14, -24
	pushq	%r13
	.cfi_def_cfa_offset 32
	.cfi_offset 13, -32
	pushq	%r12
	.cfi_def_cfa_offset 40
	.cfi_offset 12, -40
	pushq	%rbp
	.cfi_def_cfa_offset 48
	.cfi_offset 6, -48
	pushq	%rbx
	.cfi_def_cfa_offset 56
	.cfi_offset 3, -56
	subq	$24, %rsp
	.cfi_def_cfa_offset 80
	cmpb	$0, verbose(%rip)
	je	.L41
	leaq	.LC8(%rip), %rsi
	movl	$2, %edi
	xorl	%eax, %eax
	call	__printf_chk@PLT
.L41:
	leaq	hReadSequence(%rip), %r12
	leaq	hReadLen(%rip), %r13
	xorl	%ebx, %ebx
	xorl	%ebp, %ebp
	leaq	dIntArray(%rip), %r14
	leaq	.LC9(%rip), %r15
.L42:
	cmpl	%ebp, numGPUs(%rip)
	movl	%ebp, 12(%rsp)
	jle	.L67
	cmpb	$0, verbose(%rip)
	je	.L43
	movl	12(%rsp), %edx
	movq	%r15, %rsi
	movl	$2, %edi
	xorl	%eax, %eax
	call	__printf_chk@PLT
.L43:
	leaq	device(%rip), %rax
	movl	(%rax,%rbp,4), %edi
	call	cudaSetDevice@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L44
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$293, %r8d
	movq	%rax, %rcx
	jmp	.L66
.L44:
	movswl	MAX_READ_LENGTH(%rip), %esi
	imull	MAX_READS_ON_GPU(%rip), %esi
	leaq	dSequenceArray(%rip), %rdi
	addq	%rbx, %rdi
	movslq	%esi, %rsi
	call	cudaMalloc@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L45
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$294, %r8d
	movq	%rax, %rcx
.L66:
	movq	stderr(%rip), %rdi
	leaq	.LC5(%rip), %rdx
	movl	$2, %esi
	xorl	%eax, %eax
	call	__fprintf_chk@PLT
	movl	$1, %edi
	call	exit@PLT
.L45:
	movswl	MAX_READ_LENGTH(%rip), %esi
	imull	MAX_READS_ON_GPU(%rip), %esi
	leaq	dQualArray(%rip), %rdi
	addq	%rbx, %rdi
	movslq	%esi, %rsi
	call	cudaMalloc@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L46
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$295, %r8d
	movq	%rax, %rcx
	jmp	.L66
.L46:
	movslq	MAX_READS_ON_GPU(%rip), %rsi
	movq	%r14, %rdi
	addq	%rsi, %rsi
	call	cudaMalloc@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L47
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$296, %r8d
	movq	%rax, %rcx
	jmp	.L66
.L47:
	movslq	MAX_READS_ON_GPU(%rip), %rsi
	leaq	8(%r14), %rdi
	addq	%rsi, %rsi
	call	cudaMalloc@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L48
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$297, %r8d
	movq	%rax, %rcx
	jmp	.L66
.L48:
	leaq	upload_stream(%rip), %rdi
	addq	%rbx, %rdi
	call	cudaStreamCreate@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L49
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$299, %r8d
	movq	%rax, %rcx
	jmp	.L66
.L49:
	leaq	compute_stream(%rip), %rdi
	addq	%rbx, %rdi
	call	cudaStreamCreate@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L50
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$300, %r8d
	movq	%rax, %rcx
	jmp	.L66
.L50:
	leaq	download_stream(%rip), %rdi
	addq	%rbx, %rdi
	call	cudaStreamCreate@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L51
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$301, %r8d
	movq	%rax, %rcx
	jmp	.L66
.L51:
	leaq	QUAL_COPY_DONE(%rip), %rdi
	movl	$1, %esi
	addq	%rbx, %rdi
	call	cudaEventCreateWithFlags@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L52
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$303, %r8d
	movq	%rax, %rcx
	jmp	.L66
.L52:
	leaq	SEQ_COPY_DONE(%rip), %rdi
	movl	$2, %esi
	addq	%rbx, %rdi
	call	cudaEventCreateWithFlags@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L53
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$304, %r8d
	movq	%rax, %rcx
	jmp	.L66
.L53:
	leaq	TrimmQ_DONE(%rip), %rdi
	movl	$2, %esi
	addq	%rbx, %rdi
	call	cudaEventCreateWithFlags@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L54
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$305, %r8d
	movq	%rax, %rcx
	jmp	.L66
.L54:
	leaq	TrimmA_DONE(%rip), %rdi
	movl	$2, %esi
	addq	%rbx, %rdi
	call	cudaEventCreateWithFlags@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L55
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$306, %r8d
	movq	%rax, %rcx
	jmp	.L66
.L55:
	leaq	DTH_COPY_DONE(%rip), %rdi
	movl	$1, %esi
	addq	%rbx, %rdi
	call	cudaEventCreateWithFlags@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L56
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$307, %r8d
	movq	%rax, %rcx
	jmp	.L66
.L56:
	cmpb	$0, verbose(%rip)
	je	.L57
	movl	12(%rsp), %edx
	leaq	.LC10(%rip), %rsi
	movl	$2, %edi
	xorl	%eax, %eax
	call	__printf_chk@PLT
.L57:
	movslq	MAX_READS_ON_GPU(%rip), %rsi
	movq	%r13, %rdi
	addq	%rsi, %rsi
	call	cudaMallocHost@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L58
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$310, %r8d
	movq	%rax, %rcx
	jmp	.L66
.L58:
	movslq	MAX_READS_ON_GPU(%rip), %rsi
	leaq	8(%r13), %rdi
	addq	%rsi, %rsi
	call	cudaMallocHost@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L59
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$311, %r8d
	movq	%rax, %rcx
	jmp	.L66
.L59:
	movswl	MAX_READ_LENGTH(%rip), %esi
	imull	MAX_READS_ON_GPU(%rip), %esi
	movq	%r12, %rdi
	movslq	%esi, %rsi
	call	cudaMallocHost@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L60
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$313, %r8d
	movq	%rax, %rcx
	jmp	.L66
.L60:
	movswl	MAX_READ_LENGTH(%rip), %esi
	imull	MAX_READS_ON_GPU(%rip), %esi
	leaq	8(%r12), %rdi
	movslq	%esi, %rsi
	call	cudaMallocHost@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L61
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$314, %r8d
	movq	%rax, %rcx
	jmp	.L66
.L61:
	incq	%rbp
	addq	$16, %r12
	addq	$16, %r13
	addq	$16, %r14
	movswl	MAX_READ_LENGTH(%rip), %esi
	imull	MAX_READS_ON_GPU(%rip), %esi
	leaq	hReadQualstr(%rip), %rdi
	addq	%rbx, %rdi
	addq	$8, %rbx
	movslq	%esi, %rsi
	call	cudaMallocHost@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L42
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$316, %r8d
	movq	%rax, %rcx
	jmp	.L66
.L67:
	addq	$24, %rsp
	.cfi_def_cfa_offset 56
	popq	%rbx
	.cfi_def_cfa_offset 48
	popq	%rbp
	.cfi_def_cfa_offset 40
	popq	%r12
	.cfi_def_cfa_offset 32
	popq	%r13
	.cfi_def_cfa_offset 24
	popq	%r14
	.cfi_def_cfa_offset 16
	popq	%r15
	.cfi_def_cfa_offset 8
	ret
	.cfi_endproc
.LFE2041:
	.size	_Z8InitGPUsv, .-_Z8InitGPUsv
	.globl	_Z8FreeGPUsv
	.type	_Z8FreeGPUsv, @function
_Z8FreeGPUsv:
.LFB2042:
	.cfi_startproc
	endbr64
	pushq	%r14
	.cfi_def_cfa_offset 16
	.cfi_offset 14, -16
	leaq	device(%rip), %r14
	pushq	%r13
	.cfi_def_cfa_offset 24
	.cfi_offset 13, -24
	leaq	dIntArray(%rip), %r13
	pushq	%r12
	.cfi_def_cfa_offset 32
	.cfi_offset 12, -32
	leaq	hReadSequence(%rip), %r12
	pushq	%rbp
	.cfi_def_cfa_offset 40
	.cfi_offset 6, -40
	leaq	hReadLen(%rip), %rbp
	pushq	%rbx
	.cfi_def_cfa_offset 48
	.cfi_offset 3, -48
	xorl	%ebx, %ebx
.L69:
	cmpl	%ebx, numGPUs(%rip)
	jle	.L86
	movl	(%r14,%rbx,4), %edi
	call	cudaSetDevice@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L70
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$325, %r8d
	movq	%rax, %rcx
	jmp	.L85
.L70:
	leaq	QUAL_COPY_DONE(%rip), %rax
	movq	(%rax,%rbx,8), %rdi
	call	cudaEventDestroy@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L71
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$327, %r8d
	movq	%rax, %rcx
.L85:
	movq	stderr(%rip), %rdi
	leaq	.LC5(%rip), %rdx
	movl	$2, %esi
	xorl	%eax, %eax
	call	__fprintf_chk@PLT
	movl	$1, %edi
	call	exit@PLT
.L71:
	leaq	SEQ_COPY_DONE(%rip), %rax
	movq	(%rax,%rbx,8), %rdi
	call	cudaEventDestroy@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L72
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$328, %r8d
	movq	%rax, %rcx
	jmp	.L85
.L72:
	leaq	TrimmQ_DONE(%rip), %rax
	movq	(%rax,%rbx,8), %rdi
	call	cudaEventDestroy@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L73
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$329, %r8d
	movq	%rax, %rcx
	jmp	.L85
.L73:
	leaq	TrimmA_DONE(%rip), %rax
	movq	(%rax,%rbx,8), %rdi
	call	cudaEventDestroy@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L74
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$330, %r8d
	movq	%rax, %rcx
	jmp	.L85
.L74:
	leaq	DTH_COPY_DONE(%rip), %rax
	movq	(%rax,%rbx,8), %rdi
	call	cudaEventDestroy@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L75
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$331, %r8d
	movq	%rax, %rcx
	jmp	.L85
.L75:
	leaq	upload_stream(%rip), %rax
	movq	(%rax,%rbx,8), %rdi
	call	cudaStreamDestroy@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L76
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$332, %r8d
	movq	%rax, %rcx
	jmp	.L85
.L76:
	leaq	compute_stream(%rip), %rax
	movq	(%rax,%rbx,8), %rdi
	call	cudaStreamDestroy@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L77
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$333, %r8d
	movq	%rax, %rcx
	jmp	.L85
.L77:
	leaq	download_stream(%rip), %rax
	movq	(%rax,%rbx,8), %rdi
	call	cudaStreamDestroy@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L78
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$334, %r8d
	movq	%rax, %rcx
	jmp	.L85
.L78:
	movq	0(%r13), %rdi
	call	cudaFree@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L79
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$336, %r8d
	movq	%rax, %rcx
	jmp	.L85
.L79:
	movq	8(%r13), %rdi
	call	cudaFree@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L80
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$337, %r8d
	movq	%rax, %rcx
	jmp	.L85
.L80:
	leaq	dSequenceArray(%rip), %rax
	movq	(%rax,%rbx,8), %rdi
	call	cudaFree@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L81
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$338, %r8d
	movq	%rax, %rcx
	jmp	.L85
.L81:
	leaq	dQualArray(%rip), %rax
	addq	$16, %r13
	movq	(%rax,%rbx,8), %rdi
	call	cudaFree@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L82
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$339, %r8d
	movq	%rax, %rcx
	jmp	.L85
.L82:
	movq	0(%rbp), %rdi
	addq	$16, %r12
	addq	$16, %rbp
	call	cudaFreeHost@PLT
	movq	-8(%rbp), %rdi
	call	cudaFreeHost@PLT
	movq	-16(%r12), %rdi
	call	cudaFreeHost@PLT
	movq	-8(%r12), %rdi
	call	cudaFreeHost@PLT
	leaq	hReadQualstr(%rip), %rax
	movq	(%rax,%rbx,8), %rdi
	incq	%rbx
	call	cudaFreeHost@PLT
	jmp	.L69
.L86:
	popq	%rbx
	.cfi_def_cfa_offset 40
	popq	%rbp
	.cfi_def_cfa_offset 32
	popq	%r12
	.cfi_def_cfa_offset 24
	popq	%r13
	.cfi_def_cfa_offset 16
	popq	%r14
	.cfi_def_cfa_offset 8
	ret
	.cfi_endproc
.LFE2042:
	.size	_Z8FreeGPUsv, .-_Z8FreeGPUsv
	.section	.rodata.str1.1
.LC11:
	.string	"\nDevice %d: %s\n"
.LC12:
	.string	"  CUDA Driver / Runtime Version:     %d.%d / %d.%d\n"
.LC13:
	.string	"  CUDA Compute Capability:           %d.%d\n"
.LC14:
	.string	"  PCI bus ID:                        %d:%d\n"
.LC16:
	.string	"  Total amount of global memory:     %.0f MBytes (%llu bytes)\n"
.LC17:
	.string	"  Number of Multiprocessors:         %d\n"
	.text
	.globl	_Z8FindGPUsv
	.type	_Z8FindGPUsv, @function
_Z8FindGPUsv:
.LFB2043:
	.cfi_startproc
	endbr64
	pushq	%r12
	.cfi_def_cfa_offset 16
	.cfi_offset 12, -16
	pushq	%rbp
	.cfi_def_cfa_offset 24
	.cfi_offset 6, -24
	pushq	%rbx
	.cfi_def_cfa_offset 32
	.cfi_offset 3, -32
	subq	$1056, %rsp
	.cfi_def_cfa_offset 1088
	movq	%fs:40, %rax
	movq	%rax, 1048(%rsp)
	xorl	%eax, %eax
	leaq	4(%rsp), %rdi
	xorl	%eax, %eax
	movl	%eax, numGPUs(%rip)
	call	cudaGetDeviceCount@PLT
	testl	%eax, %eax
	je	.L88
	movl	%eax, %edi
	call	cudaGetErrorString@PLT
	movl	$354, %r8d
	movq	stderr(%rip), %rdi
	leaq	.LC4(%rip), %r9
	movq	%rax, %rcx
	leaq	.LC5(%rip), %rdx
	movl	$2, %esi
	xorl	%eax, %eax
	call	__fprintf_chk@PLT
	movl	$1, %edi
	call	exit@PLT
.L88:
	movl	4(%rsp), %eax
	testl	%eax, %eax
	je	.L87
	movl	$46875, %ebp
	xorl	%ebx, %ebx
	salq	$17, %rbp
.L90:
	cmpl	%ebx, 4(%rsp)
	jle	.L97
	movl	%ebx, %edi
	leaq	16(%rsp), %r12
	call	cudaSetDevice@PLT
	movl	%ebx, %esi
	movq	%r12, %rdi
	call	cudaGetDeviceProperties_v2@PLT
	leaq	8(%rsp), %rdi
	call	cudaDriverGetVersion@PLT
	leaq	12(%rsp), %rdi
	call	cudaRuntimeGetVersion@PLT
	cmpl	$3, 376(%rsp)
	jne	.L104
	cmpl	$4, 380(%rsp)
.L104:
	jg	.L92
.L93:
	incl	%ebx
	jmp	.L90
.L92:
	cmpq	304(%rsp), %rbp
	jnb	.L93
	cmpb	$0, verbose(%rip)
	je	.L94
	movq	%r12, %rcx
	movl	%ebx, %edx
	leaq	.LC11(%rip), %rsi
	xorl	%eax, %eax
	movl	$2, %edi
	call	__printf_chk@PLT
	movl	12(%rsp), %eax
	movl	$100, %r10d
	movl	$10, %edi
	movl	$1000, %esi
	cltd
	idivl	%r10d
	movl	%edx, %eax
	cltd
	idivl	%edi
	movl	%eax, %r9d
	movl	12(%rsp), %eax
	cltd
	idivl	%esi
	movl	%eax, %r8d
	movl	8(%rsp), %eax
	cltd
	idivl	%r10d
	movl	%edx, %eax
	cltd
	idivl	%edi
	movl	$2, %edi
	movl	%eax, %ecx
	movl	8(%rsp), %eax
	cltd
	idivl	%esi
	leaq	.LC12(%rip), %rsi
	movl	%eax, %edx
	xorl	%eax, %eax
	call	__printf_chk@PLT
	movl	380(%rsp), %ecx
	movl	$2, %edi
	xorl	%eax, %eax
	movl	376(%rsp), %edx
	leaq	.LC13(%rip), %rsi
	call	__printf_chk@PLT
	movl	600(%rsp), %edx
	movl	$2, %edi
	xorl	%eax, %eax
	movl	604(%rsp), %ecx
	leaq	.LC14(%rip), %rsi
	call	__printf_chk@PLT
	movq	304(%rsp), %rdx
	testq	%rdx, %rdx
	js	.L95
	cvtsi2ssq	%rdx, %xmm0
	jmp	.L96
.L95:
	movq	%rdx, %rax
	movq	%rdx, %rcx
	shrq	%rax
	andl	$1, %ecx
	orq	%rcx, %rax
	cvtsi2ssq	%rax, %xmm0
	addss	%xmm0, %xmm0
.L96:
	mulss	.LC15(%rip), %xmm0
	leaq	.LC16(%rip), %rsi
	movl	$2, %edi
	movb	$1, %al
	cvtss2sd	%xmm0, %xmm0
	call	__printf_chk@PLT
	movl	$2, %edi
	xorl	%eax, %eax
	movl	404(%rsp), %edx
	leaq	.LC17(%rip), %rsi
	call	__printf_chk@PLT
.L94:
	movslq	numGPUs(%rip), %rcx
	leaq	device(%rip), %rdx
	movq	%rcx, %rax
	movl	%ebx, (%rdx,%rcx,4)
	incl	%eax
	movl	%eax, numGPUs(%rip)
	cmpl	$3, %eax
	jle	.L93
.L97:
	movl	numGPUs(%rip), %eax
.L87:
	movq	1048(%rsp), %rdx
	subq	%fs:40, %rdx
	je	.L99
	call	__stack_chk_fail@PLT
.L99:
	addq	$1056, %rsp
	.cfi_def_cfa_offset 32
	popq	%rbx
	.cfi_def_cfa_offset 24
	popq	%rbp
	.cfi_def_cfa_offset 16
	popq	%r12
	.cfi_def_cfa_offset 8
	ret
	.cfi_endproc
.LFE2043:
	.size	_Z8FindGPUsv, .-_Z8FindGPUsv
	.section	.rodata.str1.1
.LC18:
	.string	"r"
.LC19:
	.string	"ERROR output file exists already. To overwrite run with option -f\n"
.LC20:
	.string	"ERROR opening input file: %s\n"
.LC21:
	.string	"ERROR opening second handle to input file.\n"
.LC22:
	.string	"w"
.LC23:
	.string	"Option -pigz: could not open pipe ... falling back on libz.\n\tMake sure pigz is installed with: sudo apt-get install pigz\n"
.LC24:
	.string	"Option -gz: could not open pipe ... falling back to uncompressed output.\n"
.LC25:
	.string	"ERROR opening output file: %s\n"
	.text
	.globl	_Z9OpenFilesv
	.type	_Z9OpenFilesv, @function
_Z9OpenFilesv:
.LFB2044:
	.cfi_startproc
	endbr64
	pushq	%rbp
	.cfi_def_cfa_offset 16
	.cfi_offset 6, -16
	leaq	.LC18(%rip), %rbp
	pushq	%rbx
	.cfi_def_cfa_offset 24
	.cfi_offset 3, -24
	pushq	%rdx
	.cfi_def_cfa_offset 32
	cmpb	$0, overwrite_outputfile(%rip)
	jne	.L106
	movq	%rbp, %rsi
	leaq	output_filename(%rip), %rdi
	call	fopen@PLT
	movq	%rax, outputFile(%rip)
	testq	%rax, %rax
	je	.L106
	leaq	.LC19(%rip), %rsi
	movl	$2, %edi
	xorl	%eax, %eax
	jmp	.L124
.L106:
	leaq	input_filename(%rip), %rbx
	movq	%rbp, %rsi
	movq	%rbx, %rdi
	call	gzopen@PLT
	movq	%rax, inputFile(%rip)
	testq	%rax, %rax
	jne	.L107
	movq	%rbx, %rdx
	leaq	.LC20(%rip), %rsi
	movl	$2, %edi
.L123:
	call	__printf_chk@PLT
.L122:
	movl	$255, %edi
	call	exit@PLT
.L107:
	movq	%rbp, %rsi
	movq	%rbx, %rdi
	call	gzopen@PLT
	movq	%rax, templateFile(%rip)
	testq	%rax, %rax
	jne	.L108
	leaq	.LC21(%rip), %rsi
	movl	$2, %edi
.L124:
	call	__printf_chk@PLT
	jmp	.L122
.L108:
	cmpb	$0, write_pigz_output(%rip)
	je	.L109
	movl	$410, %edx
	leaq	output_filename(%rip), %rsi
	leaq	PIGZ_PIPE(%rip), %rdi
	call	__strcat_chk@PLT
	leaq	.LC22(%rip), %rsi
	movq	%rax, %rdi
	call	popen@PLT
	movq	%rax, outputFile(%rip)
	testq	%rax, %rax
	jne	.L109
	leaq	.LC23(%rip), %rsi
	movl	$2, %edi
	call	__printf_chk@PLT
	movb	$1, write_gz_output(%rip)
	movb	$0, write_pigz_output(%rip)
	jmp	.L110
.L109:
	cmpb	$0, write_gz_output(%rip)
	je	.L111
	cmpb	$0, write_pigz_output(%rip)
	jne	.L112
.L110:
	movl	$410, %edx
	leaq	output_filename(%rip), %rsi
	leaq	GZIP_PIPE(%rip), %rdi
	call	__strcat_chk@PLT
	leaq	.LC22(%rip), %rsi
	movq	%rax, %rdi
	call	popen@PLT
	movq	%rax, outputFile(%rip)
	testq	%rax, %rax
	jne	.L113
	leaq	.LC24(%rip), %rsi
	movl	$2, %edi
	call	__printf_chk@PLT
	movb	$0, write_gz_output(%rip)
	jmp	.L111
.L113:
	cmpb	$0, write_gz_output(%rip)
	jne	.L105
.L111:
	cmpb	$0, write_pigz_output(%rip)
	jne	.L112
	leaq	.LC22(%rip), %rsi
	leaq	output_filename(%rip), %rdi
	call	fopen@PLT
	movq	%rax, outputFile(%rip)
.L112:
	cmpq	$0, outputFile(%rip)
	jne	.L105
	leaq	output_filename(%rip), %rdx
	leaq	.LC25(%rip), %rsi
	movl	$2, %edi
	xorl	%eax, %eax
	jmp	.L123
.L105:
	popq	%rax
	.cfi_def_cfa_offset 24
	popq	%rbx
	.cfi_def_cfa_offset 16
	popq	%rbp
	.cfi_def_cfa_offset 8
	ret
	.cfi_endproc
.LFE2044:
	.size	_Z9OpenFilesv, .-_Z9OpenFilesv
	.section	.rodata.str1.1
.LC26:
	.string	"ERROR parsing input!\n"
.LC27:
	.string	"Warning: Encountered unusual line identifiers in FastQ file format.\n"
	.text
	.globl	_Z16ReadBlockOfReadsiPsPcS0_
	.type	_Z16ReadBlockOfReadsiPsPcS0_, @function
_Z16ReadBlockOfReadsiPsPcS0_:
.LFB2045:
	.cfi_startproc
	endbr64
	pushq	%r15
	.cfi_def_cfa_offset 16
	.cfi_offset 15, -16
	movslq	%edi, %rax
	movq	%rcx, %r15
	pushq	%r14
	.cfi_def_cfa_offset 24
	.cfi_offset 14, -24
	movq	%rdx, %r14
	pushq	%r13
	.cfi_def_cfa_offset 32
	.cfi_offset 13, -32
	movq	%rsi, %r13
	pushq	%r12
	.cfi_def_cfa_offset 40
	.cfi_offset 12, -40
	leaq	Read(%rip), %r12
	pushq	%rbp
	.cfi_def_cfa_offset 48
	.cfi_offset 6, -48
	xorl	%ebp, %ebp
	pushq	%rbx
	.cfi_def_cfa_offset 56
	.cfi_offset 3, -56
	subq	$40, %rsp
	.cfi_def_cfa_offset 96
	movl	%edi, 12(%rsp)
	movq	%rax, 16(%rsp)
.L126:
	movq	inputFile(%rip), %rdi
	movl	$500, %edx
	movq	%r12, %rsi
	movl	%ebp, %ebx
	call	gzgets@PLT
	testq	%rax, %rax
	je	.L127
	movb	(%r12), %al
	cmpb	$10, %al
	je	.L127
	cmpb	$13, %al
	je	.L127
	movq	inputFile(%rip), %rdi
	movl	$500, %edx
	leaq	500+Read(%rip), %rsi
	call	gzgets@PLT
	testq	%rax, %rax
	jne	.L128
.L129:
	movl	$2, %edi
	leaq	.LC26(%rip), %rsi
	xorl	%eax, %eax
	call	__printf_chk@PLT
	movl	$255, %edi
	call	exit@PLT
.L128:
	movq	inputFile(%rip), %rdi
	movl	$500, %edx
	leaq	1000+Read(%rip), %rsi
	call	gzgets@PLT
	testq	%rax, %rax
	je	.L129
	movq	inputFile(%rip), %rdi
	movl	$500, %edx
	leaq	1500+Read(%rip), %rsi
	call	gzgets@PLT
	testq	%rax, %rax
	leaq	1500+Read(%rip), %rax
	movq	%rax, 24(%rsp)
	je	.L129
	cmpb	$0, FastQ_WARNING(%rip)
	jne	.L130
	cmpb	$64, (%r12)
	jne	.L131
	cmpb	$43, 1000+Read(%rip)
	je	.L130
.L131:
	leaq	.LC27(%rip), %rsi
	movl	$2, %edi
	xorl	%eax, %eax
	call	__printf_chk@PLT
	movb	$1, FastQ_WARNING(%rip)
.L130:
	leaq	500+Read(%rip), %rdi
	call	strlen@PLT
	movswl	MAX_READ_LENGTH(%rip), %edx
	leaq	500+Read(%rip), %rsi
	decl	%eax
	cmpw	%dx, %ax
	cmovg	%edx, %eax
	imull	%ebx, %edx
	movswq	%ax, %r8
	movslq	%edx, %rdx
	movq	%r8, %rcx
	addq	%r14, %rdx
	movq	%rdx, %rdi
	rep movsb
	leaq	1500+Read(%rip), %rsi
	movq	%r8, %rcx
	movswl	MAX_READ_LENGTH(%rip), %edx
	imull	%ebx, %edx
	movslq	%edx, %rdx
	addq	%r15, %rdx
	movq	%rdx, %rdi
	rep movsb
	movw	%ax, 0(%r13,%rbp,2)
	incq	%rbp
	cmpq	%rbp, 16(%rsp)
	jne	.L126
	movl	12(%rsp), %ebx
.L127:
	addl	%ebx, hNumberOfReads(%rip)
	addq	$40, %rsp
	.cfi_def_cfa_offset 56
	movl	%ebx, %eax
	popq	%rbx
	.cfi_def_cfa_offset 48
	popq	%rbp
	.cfi_def_cfa_offset 40
	popq	%r12
	.cfi_def_cfa_offset 32
	popq	%r13
	.cfi_def_cfa_offset 24
	popq	%r14
	.cfi_def_cfa_offset 16
	popq	%r15
	.cfi_def_cfa_offset 8
	ret
	.cfi_endproc
.LFE2045:
	.size	_Z16ReadBlockOfReadsiPsPcS0_, .-_Z16ReadBlockOfReadsiPsPcS0_
	.globl	_Z17WriteBlockOfReadsiPKss
	.type	_Z17WriteBlockOfReadsiPKss, @function
_Z17WriteBlockOfReadsiPKss:
.LFB2046:
	.cfi_startproc
	endbr64
	testl	%edi, %edi
	je	.L142
	movswl	%dx, %edx
	jmp	_Z17WriteBlockOfReadsiPKss.part.0
.L142:
	xorl	%eax, %eax
	ret
	.cfi_endproc
.LFE2046:
	.size	_Z17WriteBlockOfReadsiPKss, .-_Z17WriteBlockOfReadsiPKss
	.globl	_Z10CloseFilesv
	.type	_Z10CloseFilesv, @function
_Z10CloseFilesv:
.LFB2047:
	.cfi_startproc
	endbr64
	pushq	%rcx
	.cfi_def_cfa_offset 16
	movq	inputFile(%rip), %rdi
	call	gzclose@PLT
	movq	templateFile(%rip), %rdi
	call	gzclose@PLT
	cmpb	$0, write_gz_output(%rip)
	movq	outputFile(%rip), %rdi
	jne	.L144
	cmpb	$0, write_pigz_output(%rip)
	je	.L145
.L144:
	popq	%rdx
	.cfi_remember_state
	.cfi_def_cfa_offset 8
	jmp	pclose@PLT
.L145:
	.cfi_restore_state
	popq	%rax
	.cfi_def_cfa_offset 8
	jmp	fclose@PLT
	.cfi_endproc
.LFE2047:
	.size	_Z10CloseFilesv, .-_Z10CloseFilesv
	.section	.rodata.str1.1
.LC28:
	.string	"ERROR opening input file %s\n"
.LC29:
	.string	"Warning: Encountered unusual line identifiers in FastQ file format."
	.text
	.globl	_Z25Detect_FastQ_Format_PHREDv
	.type	_Z25Detect_FastQ_Format_PHREDv, @function
_Z25Detect_FastQ_Format_PHREDv:
.LFB2048:
	.cfi_startproc
	endbr64
	pushq	%r14
	.cfi_def_cfa_offset 16
	.cfi_offset 14, -16
	leaq	.LC18(%rip), %rsi
	pushq	%r13
	.cfi_def_cfa_offset 24
	.cfi_offset 13, -24
	leaq	input_filename(%rip), %r13
	pushq	%r12
	.cfi_def_cfa_offset 32
	.cfi_offset 12, -32
	movq	%r13, %rdi
	pushq	%rbp
	.cfi_def_cfa_offset 40
	.cfi_offset 6, -40
	pushq	%rbx
	.cfi_def_cfa_offset 48
	.cfi_offset 3, -48
	call	gzopen@PLT
	movq	%rax, inputFile(%rip)
	testq	%rax, %rax
	jne	.L170
	movq	%r13, %rdx
	leaq	.LC28(%rip), %rsi
	movl	$2, %edi
	call	__printf_chk@PLT
	jmp	.L172
.L170:
	movl	$65, %ebp
	movl	$65, %ebx
	leaq	Read(%rip), %r12
.L148:
	movq	inputFile(%rip), %rdi
	movl	$500, %edx
	movq	%r12, %rsi
	call	gzgets@PLT
	testq	%rax, %rax
	je	.L161
	movb	(%r12), %al
	movq	inputFile(%rip), %rdi
	cmpb	$10, %al
	je	.L161
	cmpb	$13, %al
	je	.L161
	leaq	500+Read(%rip), %r14
	movl	$500, %edx
	movq	%r14, %rsi
	call	gzgets@PLT
	testq	%rax, %rax
	jne	.L150
.L151:
	leaq	.LC26(%rip), %rsi
	movl	$2, %edi
	xorl	%eax, %eax
	call	__printf_chk@PLT
.L172:
	movl	$255, %edi
	call	exit@PLT
.L150:
	movq	inputFile(%rip), %rdi
	movl	$500, %edx
	leaq	1000+Read(%rip), %rsi
	call	gzgets@PLT
	testq	%rax, %rax
	je	.L151
	leaq	1500+Read(%rip), %r13
	movq	inputFile(%rip), %rdi
	movl	$500, %edx
	movq	%r13, %rsi
	call	gzgets@PLT
	testq	%rax, %rax
	je	.L151
	cmpb	$0, FastQ_WARNING(%rip)
	jne	.L152
	cmpb	$64, (%r12)
	jne	.L153
	cmpb	$43, 1000+Read(%rip)
	je	.L152
.L153:
	leaq	.LC29(%rip), %rsi
	movl	$2, %edi
	xorl	%eax, %eax
	call	__printf_chk@PLT
	movb	$1, FastQ_WARNING(%rip)
.L152:
	movq	%r14, %rdi
	call	strlen@PLT
	xorl	%ecx, %ecx
	decl	%eax
	cwtl
.L154:
	cmpl	%ecx, %eax
	jle	.L173
	movsbl	0(%r13,%rcx), %edx
	cmpl	%ebx, %edx
	jb	.L155
	cmpl	%edx, %ebp
	cmovb	%edx, %ebp
	movl	%ebx, %edx
.L155:
	incq	%rcx
	movl	%edx, %ebx
	jmp	.L154
.L173:
	cmpl	$58, %ebx
	ja	.L157
	movl	$33, %eax
	jmp	.L158
.L157:
	cmpl	$80, %ebp
	jbe	.L148
	movl	$64, %eax
.L158:
	movw	%ax, PHRED(%rip)
	movb	$1, %bl
	jmp	.L149
.L161:
	xorl	%ebx, %ebx
.L149:
	movq	inputFile(%rip), %rdi
	call	gzclose@PLT
	movl	%ebx, %eax
	popq	%rbx
	.cfi_def_cfa_offset 40
	popq	%rbp
	.cfi_def_cfa_offset 32
	popq	%r12
	.cfi_def_cfa_offset 24
	popq	%r13
	.cfi_def_cfa_offset 16
	popq	%r14
	.cfi_def_cfa_offset 8
	ret
	.cfi_endproc
.LFE2048:
	.size	_Z25Detect_FastQ_Format_PHREDv, .-_Z25Detect_FastQ_Format_PHREDv
	.section	.rodata.str1.1
.LC30:
	.string	"\nPreprocessReads multi-GPU version\n"
.LC31:
	.string	"\tsupports up to 4 NVIDIA GPUs with compute capability greater than 3.5 and at least 6 GB memory.\n"
.LC32:
	.string	"\tcompiled for minimum CUDA API 6.5 (build 20210107).\n"
.LC33:
	.string	"\nProgram Options:\n\n"
.LC34:
	.string	"\t-i, -I ....... specify the path for the input file [required]\n"
.LC35:
	.string	"\t-o, -O ....... specify the path for the output file [required]\n"
.LC36:
	.string	"\t-len, -Len ... specify the minimum length for reads written to the output file\n"
.LC37:
	.string	"\t-f ........... over write output file if it exists\n"
.LC38:
	.string	"\t-gz .......... write output to file in compressed format (.gz)\n"
.LC39:
	.string	"\t-pigz ........ write output to file in compressed format (.gz) using multithreaded compression\n"
.LC40:
	.string	"\t-v, -V ....... verbose, prints details on processing to screen\n"
.LC41:
	.string	"\t-a, -A ....... adaptor sequence, can contain Ns that will match any base in the read\n"
.LC42:
	.string	"\t-mm, -MM ..... number of mismatches allowed in adaptor search (not including Ns)\n"
.LC43:
	.string	"\t-Phred ....... sets the base of the qualities PHRED values [default 33], use AUTO for autodetection\n"
.LC44:
	.string	"\t-Qmin ........ sets the minimum acceptable quality score for a good base [default 20]\n"
.LC45:
	.string	"\t-Qualab ...... sets the minimum average base quality score for remainder of the read after a bad base [default 25]\n"
.LC46:
	.string	"\t-dev, -Dev ... specify CUDA device to use (can be used repeatedly for selecting multiple GPUs,\n"
.LC47:
	.string	"\t               if not specified an automatic search for GPUs with compute capability 3.5 and 6 GB memory is performed)\n"
.LC48:
	.string	"\nAlgorithm selection:\n\n"
.LC49:
	.string	"\t/TA .......... select adaptor trimming only (can be also used before option /gRNA to avoid quality trimming)\n"
.LC50:
	.string	"\t/TQ .......... select quality trimming only\n"
.LC51:
	.string	"\t/TAQ ......... select quality and adaptor trimming [default]\n"
.LC52:
	.string	"\t/gRNA ........ select gRNA recovery, followed by start relative to start of adaptor sequence and length of gRNA to be retrieved\n"
.LC53:
	.string	"\t               ( /gRNA 12 20 will retrieve 20 nucleotide read sequence starting 12 positions after the 5' end match of adaptor)\n"
.LC54:
	.string	"\nProgrammer options variables:\n"
.LC55:
	.string	"\t-G ........... set MAX_READS_ON_GPU variable\n"
.LC56:
	.string	"\t-R ........... set MAX_READ_LENGTH variable\n"
.LC57:
	.string	"\nexample usage:\n"
.LC58:
	.string	"\tPreprocessReads -dev 0 -dev 1 -i infile.fastq -o outfilename.fastq -len 26 -a ATTAGATCGATGCTA -mm 2\n\n"
	.text
	.globl	_Z10usage_helpv
	.type	_Z10usage_helpv, @function
_Z10usage_helpv:
.LFB2050:
	.cfi_startproc
	endbr64
	pushq	%rax
	.cfi_def_cfa_offset 16
	popq	%rax
	.cfi_def_cfa_offset 8
	leaq	.LC30(%rip), %rsi
	movl	$2, %edi
	pushq	%rax
	.cfi_def_cfa_offset 16
	xorl	%eax, %eax
	call	__printf_chk@PLT
	leaq	.LC31(%rip), %rsi
	movl	$2, %edi
	xorl	%eax, %eax
	call	__printf_chk@PLT
	leaq	.LC32(%rip), %rsi
	movl	$2, %edi
	xorl	%eax, %eax
	call	__printf_chk@PLT
	leaq	.LC33(%rip), %rsi
	movl	$2, %edi
	xorl	%eax, %eax
	call	__printf_chk@PLT
	leaq	.LC34(%rip), %rsi
	movl	$2, %edi
	xorl	%eax, %eax
	call	__printf_chk@PLT
	leaq	.LC35(%rip), %rsi
	movl	$2, %edi
	xorl	%eax, %eax
	call	__printf_chk@PLT
	leaq	.LC36(%rip), %rsi
	movl	$2, %edi
	xorl	%eax, %eax
	call	__printf_chk@PLT
	leaq	.LC37(%rip), %rsi
	movl	$2, %edi
	xorl	%eax, %eax
	call	__printf_chk@PLT
	leaq	.LC38(%rip), %rsi
	movl	$2, %edi
	xorl	%eax, %eax
	call	__printf_chk@PLT
	leaq	.LC39(%rip), %rsi
	movl	$2, %edi
	xorl	%eax, %eax
	call	__printf_chk@PLT
	leaq	.LC40(%rip), %rsi
	movl	$2, %edi
	xorl	%eax, %eax
	call	__printf_chk@PLT
	leaq	.LC41(%rip), %rsi
	movl	$2, %edi
	xorl	%eax, %eax
	call	__printf_chk@PLT
	leaq	.LC42(%rip), %rsi
	movl	$2, %edi
	xorl	%eax, %eax
	call	__printf_chk@PLT
	leaq	.LC43(%rip), %rsi
	movl	$2, %edi
	xorl	%eax, %eax
	call	__printf_chk@PLT
	leaq	.LC44(%rip), %rsi
	movl	$2, %edi
	xorl	%eax, %eax
	call	__printf_chk@PLT
	leaq	.LC45(%rip), %rsi
	movl	$2, %edi
	xorl	%eax, %eax
	call	__printf_chk@PLT
	xorl	%eax, %eax
	movl	$2, %edi
	leaq	.LC46(%rip), %rsi
	call	__printf_chk@PLT
	leaq	.LC47(%rip), %rsi
	movl	$2, %edi
	xorl	%eax, %eax
	call	__printf_chk@PLT
	leaq	.LC48(%rip), %rsi
	movl	$2, %edi
	xorl	%eax, %eax
	call	__printf_chk@PLT
	leaq	.LC49(%rip), %rsi
	movl	$2, %edi
	xorl	%eax, %eax
	call	__printf_chk@PLT
	leaq	.LC50(%rip), %rsi
	movl	$2, %edi
	xorl	%eax, %eax
	call	__printf_chk@PLT
	leaq	.LC51(%rip), %rsi
	movl	$2, %edi
	xorl	%eax, %eax
	call	__printf_chk@PLT
	leaq	.LC52(%rip), %rsi
	movl	$2, %edi
	xorl	%eax, %eax
	call	__printf_chk@PLT
	leaq	.LC53(%rip), %rsi
	movl	$2, %edi
	xorl	%eax, %eax
	call	__printf_chk@PLT
	leaq	.LC54(%rip), %rsi
	movl	$2, %edi
	xorl	%eax, %eax
	call	__printf_chk@PLT
	leaq	.LC55(%rip), %rsi
	movl	$2, %edi
	xorl	%eax, %eax
	call	__printf_chk@PLT
	leaq	.LC56(%rip), %rsi
	movl	$2, %edi
	xorl	%eax, %eax
	call	__printf_chk@PLT
	leaq	.LC57(%rip), %rsi
	movl	$2, %edi
	xorl	%eax, %eax
	call	__printf_chk@PLT
	movl	$2, %edi
	leaq	.LC58(%rip), %rsi
	xorl	%eax, %eax
	call	__printf_chk@PLT
	movl	$3, %edi
	call	exit@PLT
	.cfi_endproc
.LFE2050:
	.size	_Z10usage_helpv, .-_Z10usage_helpv
	.section	.rodata.str1.1
.LC59:
	.string	"\nERROR %s\n"
.LC60:
	.string	"\nUsage ----------------------------------------------\n"
	.text
	.globl	_Z27invalid_command_line_optionPKc
	.type	_Z27invalid_command_line_optionPKc, @function
_Z27invalid_command_line_optionPKc:
.LFB2051:
	.cfi_startproc
	endbr64
	pushq	%rax
	.cfi_def_cfa_offset 16
	popq	%rax
	.cfi_def_cfa_offset 8
	leaq	.LC59(%rip), %rsi
	pushq	%rax
	.cfi_def_cfa_offset 16
	movq	%rdi, %rdx
	xorl	%eax, %eax
	movl	$2, %edi
	call	__printf_chk@PLT
	leaq	.LC60(%rip), %rsi
	movl	$2, %edi
	xorl	%eax, %eax
	call	__printf_chk@PLT
	call	_Z10usage_helpv
	.cfi_endproc
.LFE2051:
	.size	_Z27invalid_command_line_optionPKc, .-_Z27invalid_command_line_optionPKc
	.section	.rodata.str1.1
.LC61:
	.string	"option -i: input file name already specified."
.LC62:
	.string	"option -i: input file path length exceeds limit."
.LC63:
	.string	"option -i: INPUT file name missing."
.LC64:
	.string	"option -o: output file name already specified."
.LC65:
	.string	"option -o: output file path length exceeds limit."
.LC66:
	.string	"option -o: OUTPUT file name missing."
.LC67:
	.string	"invalid command line option encountered."
.LC68:
	.string	"option -len: minimum read length to include in output file is already specified."
.LC69:
	.string	"option -len: encountered invalid minimum read length to include in output file."
.LC70:
	.string	"option -len: expected minimum output read length not found."
.LC71:
	.string	"option -a: adaptor sequence already specified."
.LC72:
	.string	"option -a: adaptor sequence length exceeds limit."
.LC73:
	.string	"option -a: adaptor sequence length too short."
.LC74:
	.string	"option -a: expected adaptor sequence."
.LC75:
	.string	"option -mm: number of mismatches is already specified."
.LC76:
	.string	"option -mm: number of mismatches exceeds limit."
.LC77:
	.string	"option -mm: expected number of mismatches not found."
.LC78:
	.string	"option -dev: number of CUDA devices exceeds maximum."
.LC79:
	.string	"option -dev: invalid device number."
.LC80:
	.string	"option -dev: expected CUDA device number not found."
.LC81:
	.string	"-Pigz"
.LC82:
	.string	"-pigz"
.LC83:
	.string	"AUTO"
.LC84:
	.string	"auto"
.LC85:
	.string	"option -Phred: invalid phred base."
.LC86:
	.string	"option -phred: expected number or AUTO not found."
.LC87:
	.string	"-Qmin"
.LC88:
	.string	"-qmin"
.LC89:
	.string	"option -qmin: outside 10 to 64 limit."
.LC90:
	.string	"option -qmin: expected number not found."
.LC91:
	.string	"-Qualab"
.LC92:
	.string	"-qualab"
.LC93:
	.string	"option -qualab: outside 10 to 64 limit."
.LC94:
	.string	"\nHELP ----------------------------------------------\n"
.LC95:
	.string	"option /T: algorithm selection is invalid."
.LC96:
	.string	"option /gRNA: expected start position relative to adaptor 5' not found."
.LC97:
	.string	"option /gRNA: expected gRNA length not found."
.LC98:
	.string	"option /g: algorithm selection is invalid."
.LC99:
	.string	"parsing command line options."
.LC100:
	.string	"missing required command line options."
.LC101:
	.string	"ERROR: encountered identical input and output file paths!\n"
.LC102:
	.string	"Setting parameters:\n"
.LC103:
	.string	"\tInput file name  : %s\n"
.LC104:
	.string	"\tOutput file name : %s\n"
.LC105:
	.string	"\tAdaptor sequence : %s\n"
.LC106:
	.string	"\tMismatches = %d\n"
.LC107:
	.string	"\tTrimming: "
.LC108:
	.string	"Quality "
.LC109:
	.string	"Adaptors "
.LC110:
	.string	"Find gRNA"
.LC111:
	.string	"\tMinimum accepted base quality = %d; average quality of read after bad base = %d\n"
.LC112:
	.string	"\tFastQ Quality Encoding: "
.LC113:
	.string	"PHRED+%d\n"
.LC114:
	.string	"<AUTO DETECTION>\n"
.LC115:
	.string	"\tMAX_READ_LENGTH  : %d\n"
.LC116:
	.string	"\tMinimum read length for output = %d\n"
.LC117:
	.string	"\tForce overwrite output file if it exists.\n"
.LC118:
	.string	"\nUsing CUDA devices: "
.LC119:
	.string	"[%d]"
	.text
	.globl	_Z25parseCommandLineArgumentsiPPc
	.type	_Z25parseCommandLineArgumentsiPPc, @function
_Z25parseCommandLineArgumentsiPPc:
.LFB2052:
	.cfi_startproc
	endbr64
	pushq	%r15
	.cfi_def_cfa_offset 16
	.cfi_offset 15, -16
	pushq	%r14
	.cfi_def_cfa_offset 24
	.cfi_offset 14, -24
	pushq	%r13
	.cfi_def_cfa_offset 32
	.cfi_offset 13, -32
	pushq	%r12
	.cfi_def_cfa_offset 40
	.cfi_offset 12, -40
	movq	%rsi, %r12
	pushq	%rbp
	.cfi_def_cfa_offset 48
	.cfi_offset 6, -48
	movl	%edi, %ebp
	pushq	%rbx
	.cfi_def_cfa_offset 56
	.cfi_offset 3, -56
	movl	$1, %ebx
	subq	$24, %rsp
	.cfi_def_cfa_offset 80
	movb	$0, 15(%rsp)
	movb	$0, 14(%rsp)
	movb	$0, 13(%rsp)
	movb	$0, 12(%rsp)
	movb	$0, 11(%rsp)
.L179:
	cmpl	%ebp, %ebx
	jge	.L286
	movslq	%ebx, %rax
	leal	1(%rbx), %r14d
	movq	(%r12,%rax,8), %r15
	leaq	0(,%rax,8), %r13
	movb	(%r15), %al
	cmpb	$45, %al
	jne	.L180
	movb	1(%r15), %al
	subl	$63, %eax
	cmpb	$55, %al
	ja	.L181
	leaq	.L183(%rip), %rcx
	movzbl	%al, %eax
	movslq	(%rcx,%rax,4), %rax
	addq	%rcx, %rax
	notrack jmp	*%rax
	.section	.rodata
	.align 4
	.align 4
.L183:
	.long	.L190-.L183
	.long	.L181-.L183
	.long	.L194-.L183
	.long	.L181-.L183
	.long	.L181-.L183
	.long	.L193-.L183
	.long	.L181-.L183
	.long	.L181-.L183
	.long	.L196-.L183
	.long	.L190-.L183
	.long	.L189-.L183
	.long	.L181-.L183
	.long	.L181-.L183
	.long	.L188-.L183
	.long	.L187-.L183
	.long	.L181-.L183
	.long	.L186-.L183
	.long	.L185-.L183
	.long	.L184-.L183
	.long	.L195-.L183
	.long	.L181-.L183
	.long	.L181-.L183
	.long	.L181-.L183
	.long	.L182-.L183
	.long	.L181-.L183
	.long	.L181-.L183
	.long	.L181-.L183
	.long	.L181-.L183
	.long	.L181-.L183
	.long	.L181-.L183
	.long	.L181-.L183
	.long	.L181-.L183
	.long	.L181-.L183
	.long	.L181-.L183
	.long	.L194-.L183
	.long	.L181-.L183
	.long	.L181-.L183
	.long	.L193-.L183
	.long	.L181-.L183
	.long	.L192-.L183
	.long	.L191-.L183
	.long	.L190-.L183
	.long	.L189-.L183
	.long	.L181-.L183
	.long	.L181-.L183
	.long	.L188-.L183
	.long	.L187-.L183
	.long	.L181-.L183
	.long	.L186-.L183
	.long	.L185-.L183
	.long	.L184-.L183
	.long	.L181-.L183
	.long	.L181-.L183
	.long	.L181-.L183
	.long	.L181-.L183
	.long	.L182-.L183
	.text
.L189:
	cmpb	$0, 11(%rsp)
	je	.L197
	leaq	.LC61(%rip), %rdi
	jmp	.L285
.L197:
	movl	%r14d, %ebx
	cmpl	%r14d, %ebp
	jle	.L198
	movq	8(%r12,%r13), %r13
	movq	%r13, %rdi
	call	strlen@PLT
	cmpq	$400, %rax
	jbe	.L199
	leaq	.LC62(%rip), %rdi
.L285:
	call	_Z27invalid_command_line_optionPKc
.L199:
	movl	$400, %edx
	movq	%r13, %rsi
	leaq	input_filename(%rip), %rdi
	call	__strcpy_chk@PLT
	movb	$1, 11(%rsp)
	jmp	.L200
.L198:
	leaq	.LC63(%rip), %rdi
	jmp	.L285
.L186:
	cmpb	$0, 12(%rsp)
	je	.L201
	leaq	.LC64(%rip), %rdi
	jmp	.L285
.L201:
	movl	%r14d, %ebx
	cmpl	%r14d, %ebp
	jle	.L202
	movq	8(%r12,%r13), %r13
	movq	%r13, %rdi
	call	strlen@PLT
	cmpq	$400, %rax
	jbe	.L203
	leaq	.LC65(%rip), %rdi
	jmp	.L285
.L203:
	movl	$400, %edx
	movq	%r13, %rsi
	leaq	output_filename(%rip), %rdi
	call	__strcpy_chk@PLT
	movb	$1, 12(%rsp)
	jmp	.L200
.L202:
	leaq	.LC66(%rip), %rdi
	jmp	.L285
.L188:
	cmpb	$101, 2(%r15)
	jne	.L181
	cmpb	$110, 3(%r15)
	jne	.L181
	cmpb	$0, 15(%rsp)
	je	.L206
	leaq	.LC68(%rip), %rdi
	jmp	.L285
.L206:
	movl	%r14d, %ebx
	cmpl	%r14d, %ebp
	jle	.L207
	movq	8(%r12,%r13), %rdi
	call	atoi@PLT
	testl	%eax, %eax
	jns	.L208
.L209:
	leaq	.LC69(%rip), %rdi
	jmp	.L285
.L208:
	movswl	MAX_READ_LENGTH(%rip), %edx
	cmpl	%eax, %edx
	jl	.L209
	movw	%ax, MIN_OUT_READ_LEN(%rip)
	movb	$1, 15(%rsp)
	jmp	.L200
.L207:
	leaq	.LC70(%rip), %rdi
	jmp	.L285
.L194:
	cmpb	$0, 13(%rsp)
	je	.L210
	leaq	.LC71(%rip), %rdi
	jmp	.L285
.L210:
	movl	%r14d, %ebx
	cmpl	%r14d, %ebp
	jle	.L211
	movq	8(%r12,%r13), %r13
	movq	%r13, %rdi
	call	strlen@PLT
	cmpq	$100, %rax
	jbe	.L212
	leaq	.LC72(%rip), %rdi
	jmp	.L285
.L212:
	cmpq	$2, %rax
	ja	.L213
	leaq	.LC73(%rip), %rdi
	jmp	.L285
.L213:
	movl	$100, %edx
	movq	%r13, %rsi
	leaq	Adaptor(%rip), %rdi
	call	__strcpy_chk@PLT
	movb	$1, 13(%rsp)
	jmp	.L200
.L211:
	leaq	.LC74(%rip), %rdi
	jmp	.L285
.L187:
	movb	2(%r15), %al
	andl	$-33, %eax
	cmpb	$77, %al
	jne	.L181
	cmpb	$0, 14(%rsp)
	je	.L214
	leaq	.LC75(%rip), %rdi
	jmp	.L285
.L214:
	movl	%r14d, %ebx
	cmpl	%r14d, %ebp
	jle	.L215
	movq	8(%r12,%r13), %rdi
	call	atoi@PLT
	cmpl	$20, %eax
	jle	.L216
	leaq	.LC76(%rip), %rdi
	jmp	.L285
.L216:
	movw	%ax, mismatches(%rip)
	movb	$1, 14(%rsp)
	jmp	.L200
.L215:
	leaq	.LC77(%rip), %rdi
	jmp	.L285
.L193:
	cmpb	$101, 2(%r15)
	jne	.L181
	cmpb	$118, 3(%r15)
	jne	.L181
	movl	numGPUs(%rip), %r15d
	cmpl	$3, %r15d
	jle	.L217
	leaq	.LC78(%rip), %rdi
	jmp	.L285
.L217:
	movl	%r14d, %ebx
	cmpl	%r14d, %ebp
	jle	.L218
	movq	8(%r12,%r13), %rdi
	call	atoi@PLT
	cmpl	$20, %eax
	jbe	.L219
	leaq	.LC79(%rip), %rdi
	jmp	.L285
.L219:
	movslq	%r15d, %rsi
	leaq	device(%rip), %rcx
	leal	1(%r15), %edx
	movl	%eax, (%rcx,%rsi,4)
	movl	%edx, numGPUs(%rip)
	jmp	.L200
.L218:
	leaq	.LC80(%rip), %rdi
	jmp	.L285
.L192:
	movb	$1, overwrite_outputfile(%rip)
	jmp	.L200
.L191:
	cmpb	$122, 2(%r15)
	jne	.L181
	movq	%r15, %rdi
	call	strlen@PLT
	cmpq	$3, %rax
	jne	.L181
	movb	$1, write_gz_output(%rip)
	jmp	.L200
.L185:
	leaq	.LC81(%rip), %rsi
	movq	%r15, %rdi
	call	strcmp@PLT
	testl	%eax, %eax
	je	.L221
	leaq	.LC82(%rip), %rsi
	movq	%r15, %rdi
	call	strcmp@PLT
	testl	%eax, %eax
	jne	.L222
.L221:
	movb	$1, write_pigz_output(%rip)
	jmp	.L200
.L222:
	cmpb	$104, 2(%r15)
	jne	.L181
	cmpb	$114, 3(%r15)
	jne	.L181
	cmpb	$101, 4(%r15)
	jne	.L181
	cmpb	$100, 5(%r15)
	jne	.L181
	movl	%r14d, %ebx
	cmpl	%r14d, %ebp
	jle	.L224
	movq	8(%r12,%r13), %r13
	leaq	.LC83(%rip), %rsi
	movq	%r13, %rdi
	call	strcmp@PLT
	testl	%eax, %eax
	je	.L225
	leaq	.LC84(%rip), %rsi
	movq	%r13, %rdi
	call	strcmp@PLT
	testl	%eax, %eax
	jne	.L226
.L225:
	movb	$1, auto_phred_detect(%rip)
	jmp	.L200
.L226:
	movq	%r13, %rdi
	call	atoi@PLT
	cmpl	$100, %eax
	jbe	.L227
	leaq	.LC85(%rip), %rdi
	jmp	.L285
.L227:
	movw	%ax, PHRED(%rip)
	jmp	.L200
.L224:
	leaq	.LC86(%rip), %rdi
	jmp	.L285
.L184:
	leaq	.LC87(%rip), %rsi
	movq	%r15, %rdi
	call	strcmp@PLT
	testl	%eax, %eax
	je	.L228
	leaq	.LC88(%rip), %rsi
	movq	%r15, %rdi
	call	strcmp@PLT
	testl	%eax, %eax
	jne	.L229
.L228:
	movl	%r14d, %ebx
	cmpl	%r14d, %ebp
	jle	.L230
	movq	8(%r12,%r13), %rdi
	call	atoi@PLT
	leal	-10(%rax), %edx
	cmpl	$54, %edx
	jbe	.L231
	leaq	.LC89(%rip), %rdi
	jmp	.L285
.L231:
	movw	%ax, MIN_BASE_QUAL(%rip)
	jmp	.L200
.L229:
	leaq	.LC91(%rip), %rsi
	movq	%r15, %rdi
	call	strcmp@PLT
	testl	%eax, %eax
	jne	.L287
.L232:
	movl	%r14d, %ebx
	cmpl	%r14d, %ebp
	jg	.L288
.L230:
	leaq	.LC90(%rip), %rdi
	jmp	.L285
.L287:
	leaq	.LC92(%rip), %rsi
	movq	%r15, %rdi
	call	strcmp@PLT
	testl	%eax, %eax
	jne	.L200
	jmp	.L232
.L288:
	movq	8(%r12,%r13), %rdi
	call	atoi@PLT
	leal	-10(%rax), %edx
	cmpl	$54, %edx
	jbe	.L233
	leaq	.LC93(%rip), %rdi
	jmp	.L285
.L233:
	movw	%ax, MIN_QUAL_AFTER_BAD(%rip)
	jmp	.L200
.L182:
	movb	$1, verbose(%rip)
	jmp	.L200
.L190:
	leaq	.LC94(%rip), %rsi
	movl	$2, %edi
	xorl	%eax, %eax
	call	__printf_chk@PLT
	call	_Z10usage_helpv
.L196:
	movl	%r14d, %ebx
	cmpl	%r14d, %ebp
	jle	.L181
	movq	8(%r12,%r13), %rdi
	call	atoi@PLT
	testl	%eax, %eax
	jle	.L181
	movl	%eax, MAX_READS_ON_GPU(%rip)
	jmp	.L200
.L195:
	movl	%r14d, %ebx
	cmpl	%r14d, %ebp
	jle	.L181
	movq	8(%r12,%r13), %rdi
	call	atoi@PLT
	leal	-1(%rax), %edx
	cmpl	$9999, %edx
	ja	.L181
	movw	%ax, MAX_READ_LENGTH(%rip)
	jmp	.L200
.L181:
	leaq	.LC67(%rip), %rdi
	jmp	.L285
.L180:
	cmpb	$47, %al
	jne	.L234
	movb	1(%r15), %al
	cmpb	$84, %al
	je	.L235
	cmpb	$103, %al
	je	.L236
	jmp	.L200
.L235:
	movq	%r15, %rdi
	movb	$0, AdaptorTrimming(%rip)
	movb	$0, QualityTrimming(%rip)
	movb	$0, gRNATrimming(%rip)
	call	strlen@PLT
	cmpq	$3, %rax
	jne	.L238
	movb	2(%r15), %al
	cmpb	$65, %al
	jne	.L239
	movb	$1, AdaptorTrimming(%rip)
	jmp	.L200
.L239:
	cmpb	$81, %al
	jne	.L238
	movb	$1, QualityTrimming(%rip)
	jmp	.L200
.L238:
	leaq	.LC95(%rip), %rdi
	jmp	.L285
.L236:
	movq	%r15, %rdi
	call	strlen@PLT
	cmpq	$5, %rax
	jne	.L240
	cmpb	$82, 2(%r15)
	jne	.L240
	cmpb	$78, 3(%r15)
	jne	.L240
	cmpb	$65, 4(%r15)
	jne	.L240
	movb	$1, gRNATrimming(%rip)
	cmpl	%r14d, %ebp
	jle	.L241
	movq	8(%r12,%r13), %rdi
	addl	$2, %ebx
	call	atoi@PLT
	movl	%eax, gRNA_start(%rip)
	cmpl	%ebx, %ebp
	jle	.L289
	movq	16(%r12,%r13), %rdi
	call	atoi@PLT
	movl	%eax, gRNA_length(%rip)
	jmp	.L200
.L241:
	leaq	.LC96(%rip), %rdi
	jmp	.L285
.L289:
	leaq	.LC97(%rip), %rdi
	jmp	.L285
.L240:
	leaq	.LC98(%rip), %rdi
	jmp	.L285
.L234:
	leaq	.LC99(%rip), %rdi
	jmp	.L285
.L200:
	incl	%ebx
	jmp	.L179
.L286:
	cmpb	$0, 11(%rsp)
	je	.L245
	cmpb	$0, 12(%rsp)
	je	.L245
	cmpb	$0, AdaptorTrimming(%rip)
	jne	.L246
	cmpb	$0, gRNATrimming(%rip)
	je	.L247
.L246:
	cmpb	$0, 13(%rsp)
	jne	.L247
.L245:
	leaq	.LC100(%rip), %rdi
	jmp	.L285
.L247:
	leaq	output_filename(%rip), %rbx
	leaq	input_filename(%rip), %rbp
	movq	%rbx, %rsi
	movq	%rbp, %rdi
	call	strcmp@PLT
	testl	%eax, %eax
	jne	.L248
	movl	$2, %edi
	leaq	.LC101(%rip), %rsi
	call	__printf_chk@PLT
	movl	$253, %edi
	call	exit@PLT
.L248:
	leaq	.LC102(%rip), %rsi
	movl	$2, %edi
	xorl	%eax, %eax
	call	__printf_chk@PLT
	movq	%rbp, %rdx
	movl	$2, %edi
	xorl	%eax, %eax
	leaq	.LC103(%rip), %rsi
	call	__printf_chk@PLT
	xorl	%eax, %eax
	movq	%rbx, %rdx
	movl	$2, %edi
	leaq	.LC104(%rip), %rsi
	call	__printf_chk@PLT
	cmpb	$0, AdaptorTrimming(%rip)
	jne	.L249
	cmpb	$0, gRNATrimming(%rip)
	je	.L250
.L249:
	leaq	Adaptor(%rip), %rdx
	leaq	.LC105(%rip), %rsi
	movl	$2, %edi
	xorl	%eax, %eax
	call	__printf_chk@PLT
.L250:
	cmpb	$0, verbose(%rip)
	je	.L252
	cmpb	$0, AdaptorTrimming(%rip)
	jne	.L253
	cmpb	$0, gRNATrimming(%rip)
	je	.L254
.L253:
	movswl	mismatches(%rip), %edx
	leaq	.LC106(%rip), %rsi
	movl	$2, %edi
	xorl	%eax, %eax
	call	__printf_chk@PLT
.L254:
	xorl	%eax, %eax
	leaq	.LC107(%rip), %rsi
	movl	$2, %edi
	call	__printf_chk@PLT
	cmpb	$0, QualityTrimming(%rip)
	je	.L255
	leaq	.LC108(%rip), %rsi
	movl	$2, %edi
	xorl	%eax, %eax
	call	__printf_chk@PLT
.L255:
	cmpb	$0, AdaptorTrimming(%rip)
	je	.L256
	leaq	.LC109(%rip), %rsi
	movl	$2, %edi
	xorl	%eax, %eax
	call	__printf_chk@PLT
.L256:
	cmpb	$0, gRNATrimming(%rip)
	je	.L257
	leaq	.LC110(%rip), %rsi
	movl	$2, %edi
	xorl	%eax, %eax
	call	__printf_chk@PLT
.L257:
	xorl	%eax, %eax
	leaq	.LC8(%rip), %rsi
	movl	$2, %edi
	call	__printf_chk@PLT
	cmpb	$0, QualityTrimming(%rip)
	je	.L258
	movswl	MIN_QUAL_AFTER_BAD(%rip), %ecx
	movswl	MIN_BASE_QUAL(%rip), %edx
	leaq	.LC111(%rip), %rsi
	xorl	%eax, %eax
	movl	$2, %edi
	call	__printf_chk@PLT
.L258:
	xorl	%eax, %eax
	leaq	.LC112(%rip), %rsi
	movl	$2, %edi
	call	__printf_chk@PLT
	cmpb	$0, auto_phred_detect(%rip)
	jne	.L259
	movswl	PHRED(%rip), %edx
	leaq	.LC113(%rip), %rsi
	movl	$2, %edi
	xorl	%eax, %eax
	call	__printf_chk@PLT
	jmp	.L260
.L259:
	leaq	.LC114(%rip), %rsi
	movl	$2, %edi
	xorl	%eax, %eax
	call	__printf_chk@PLT
.L260:
	movswl	MAX_READ_LENGTH(%rip), %edx
	leaq	.LC115(%rip), %rsi
	movl	$2, %edi
	xorl	%eax, %eax
	call	__printf_chk@PLT
	movswl	MIN_OUT_READ_LEN(%rip), %edx
	xorl	%eax, %eax
	leaq	.LC116(%rip), %rsi
	movl	$2, %edi
	call	__printf_chk@PLT
	cmpb	$0, overwrite_outputfile(%rip)
	je	.L252
	leaq	.LC117(%rip), %rsi
	movl	$2, %edi
	xorl	%eax, %eax
	call	__printf_chk@PLT
.L252:
	cmpl	$0, numGPUs(%rip)
	jle	.L178
	leaq	.LC118(%rip), %rsi
	movl	$2, %edi
	xorl	%eax, %eax
	xorl	%ebx, %ebx
	call	__printf_chk@PLT
	leaq	device(%rip), %rbp
.L263:
	cmpl	%ebx, numGPUs(%rip)
	jle	.L290
	movl	0(%rbp,%rbx,4), %edx
	leaq	.LC119(%rip), %rsi
	movl	$2, %edi
	xorl	%eax, %eax
	incq	%rbx
	call	__printf_chk@PLT
	jmp	.L263
.L290:
	addq	$24, %rsp
	.cfi_remember_state
	.cfi_def_cfa_offset 56
	leaq	.LC8(%rip), %rsi
	movl	$2, %edi
	xorl	%eax, %eax
	popq	%rbx
	.cfi_def_cfa_offset 48
	popq	%rbp
	.cfi_def_cfa_offset 40
	popq	%r12
	.cfi_def_cfa_offset 32
	popq	%r13
	.cfi_def_cfa_offset 24
	popq	%r14
	.cfi_def_cfa_offset 16
	popq	%r15
	.cfi_def_cfa_offset 8
	jmp	__printf_chk@PLT
.L178:
	.cfi_restore_state
	addq	$24, %rsp
	.cfi_def_cfa_offset 56
	popq	%rbx
	.cfi_def_cfa_offset 48
	popq	%rbp
	.cfi_def_cfa_offset 40
	popq	%r12
	.cfi_def_cfa_offset 32
	popq	%r13
	.cfi_def_cfa_offset 24
	popq	%r14
	.cfi_def_cfa_offset 16
	popq	%r15
	.cfi_def_cfa_offset 8
	ret
	.cfi_endproc
.LFE2052:
	.size	_Z25parseCommandLineArgumentsiPPc, .-_Z25parseCommandLineArgumentsiPPc
	.globl	_Z32__device_stub__Z9Find_gRNAPcPsisPcPsis
	.type	_Z32__device_stub__Z9Find_gRNAPcPsisPcPsis, @function
_Z32__device_stub__Z9Find_gRNAPcPsisPcPsis:
.LFB2078:
	.cfi_startproc
	endbr64
	subq	$152, %rsp
	.cfi_def_cfa_offset 160
	movq	%rdi, 24(%rsp)
	leaq	56(%rsp), %rdi
	movq	%rsi, 16(%rsp)
	leaq	68(%rsp), %rsi
	movl	%edx, 12(%rsp)
	leaq	40(%rsp), %rdx
	movw	%cx, 8(%rsp)
	leaq	48(%rsp), %rcx
	movq	%fs:40, %rax
	movq	%rax, 136(%rsp)
	xorl	%eax, %eax
	leaq	24(%rsp), %rax
	movl	$1, 64(%rsp)
	movq	%rax, 104(%rsp)
	leaq	16(%rsp), %rax
	movq	%rax, 112(%rsp)
	leaq	12(%rsp), %rax
	movq	%rax, 120(%rsp)
	leaq	8(%rsp), %rax
	movq	%rax, 128(%rsp)
	movabsq	$4294967297, %rax
	movq	%rax, 56(%rsp)
	movq	%rax, 68(%rsp)
	movl	$1, 76(%rsp)
	call	__cudaPopCallConfiguration@PLT
	testl	%eax, %eax
	jne	.L291
	pushq	48(%rsp)
	.cfi_def_cfa_offset 168
	leaq	_Z9Find_gRNAPcPsis(%rip), %rdi
	pushq	48(%rsp)
	.cfi_def_cfa_offset 176
	movq	84(%rsp), %rcx
	movl	92(%rsp), %r8d
	movq	72(%rsp), %rsi
	movl	80(%rsp), %edx
	leaq	120(%rsp), %r9
	call	cudaLaunchKernel@PLT
	popq	%rax
	.cfi_def_cfa_offset 168
	popq	%rdx
	.cfi_def_cfa_offset 160
.L291:
	movq	136(%rsp), %rax
	subq	%fs:40, %rax
	je	.L293
	call	__stack_chk_fail@PLT
.L293:
	addq	$152, %rsp
	.cfi_def_cfa_offset 8
	ret
	.cfi_endproc
.LFE2078:
	.size	_Z32__device_stub__Z9Find_gRNAPcPsisPcPsis, .-_Z32__device_stub__Z9Find_gRNAPcPsisPcPsis
	.globl	_Z9Find_gRNAPcPsis
	.type	_Z9Find_gRNAPcPsis, @function
_Z9Find_gRNAPcPsis:
.LFB2079:
	.cfi_startproc
	endbr64
	movswl	%cx, %ecx
	jmp	_Z32__device_stub__Z9Find_gRNAPcPsisPcPsis
	.cfi_endproc
.LFE2079:
	.size	_Z9Find_gRNAPcPsis, .-_Z9Find_gRNAPcPsis
	.globl	_Z37__device_stub__Z13TrimmAdaptorsPcPsisPcPsis
	.type	_Z37__device_stub__Z13TrimmAdaptorsPcPsisPcPsis, @function
_Z37__device_stub__Z13TrimmAdaptorsPcPsisPcPsis:
.LFB2080:
	.cfi_startproc
	endbr64
	subq	$152, %rsp
	.cfi_def_cfa_offset 160
	movq	%rdi, 24(%rsp)
	leaq	56(%rsp), %rdi
	movq	%rsi, 16(%rsp)
	leaq	68(%rsp), %rsi
	movl	%edx, 12(%rsp)
	leaq	40(%rsp), %rdx
	movw	%cx, 8(%rsp)
	leaq	48(%rsp), %rcx
	movq	%fs:40, %rax
	movq	%rax, 136(%rsp)
	xorl	%eax, %eax
	leaq	24(%rsp), %rax
	movl	$1, 64(%rsp)
	movq	%rax, 104(%rsp)
	leaq	16(%rsp), %rax
	movq	%rax, 112(%rsp)
	leaq	12(%rsp), %rax
	movq	%rax, 120(%rsp)
	leaq	8(%rsp), %rax
	movq	%rax, 128(%rsp)
	movabsq	$4294967297, %rax
	movq	%rax, 56(%rsp)
	movq	%rax, 68(%rsp)
	movl	$1, 76(%rsp)
	call	__cudaPopCallConfiguration@PLT
	testl	%eax, %eax
	jne	.L296
	pushq	48(%rsp)
	.cfi_def_cfa_offset 168
	leaq	_Z13TrimmAdaptorsPcPsis(%rip), %rdi
	pushq	48(%rsp)
	.cfi_def_cfa_offset 176
	movq	84(%rsp), %rcx
	movl	92(%rsp), %r8d
	movq	72(%rsp), %rsi
	movl	80(%rsp), %edx
	leaq	120(%rsp), %r9
	call	cudaLaunchKernel@PLT
	popq	%rax
	.cfi_def_cfa_offset 168
	popq	%rdx
	.cfi_def_cfa_offset 160
.L296:
	movq	136(%rsp), %rax
	subq	%fs:40, %rax
	je	.L298
	call	__stack_chk_fail@PLT
.L298:
	addq	$152, %rsp
	.cfi_def_cfa_offset 8
	ret
	.cfi_endproc
.LFE2080:
	.size	_Z37__device_stub__Z13TrimmAdaptorsPcPsisPcPsis, .-_Z37__device_stub__Z13TrimmAdaptorsPcPsisPcPsis
	.globl	_Z13TrimmAdaptorsPcPsis
	.type	_Z13TrimmAdaptorsPcPsis, @function
_Z13TrimmAdaptorsPcPsis:
.LFB2081:
	.cfi_startproc
	endbr64
	movswl	%cx, %ecx
	jmp	_Z37__device_stub__Z13TrimmAdaptorsPcPsisPcPsis
	.cfi_endproc
.LFE2081:
	.size	_Z13TrimmAdaptorsPcPsis, .-_Z13TrimmAdaptorsPcPsis
	.globl	_Z34__device_stub__Z10TrimmQualsPcPsisPcPsis
	.type	_Z34__device_stub__Z10TrimmQualsPcPsisPcPsis, @function
_Z34__device_stub__Z10TrimmQualsPcPsisPcPsis:
.LFB2082:
	.cfi_startproc
	endbr64
	subq	$152, %rsp
	.cfi_def_cfa_offset 160
	movq	%rdi, 24(%rsp)
	leaq	56(%rsp), %rdi
	movq	%rsi, 16(%rsp)
	leaq	68(%rsp), %rsi
	movl	%edx, 12(%rsp)
	leaq	40(%rsp), %rdx
	movw	%cx, 8(%rsp)
	leaq	48(%rsp), %rcx
	movq	%fs:40, %rax
	movq	%rax, 136(%rsp)
	xorl	%eax, %eax
	leaq	24(%rsp), %rax
	movl	$1, 64(%rsp)
	movq	%rax, 104(%rsp)
	leaq	16(%rsp), %rax
	movq	%rax, 112(%rsp)
	leaq	12(%rsp), %rax
	movq	%rax, 120(%rsp)
	leaq	8(%rsp), %rax
	movq	%rax, 128(%rsp)
	movabsq	$4294967297, %rax
	movq	%rax, 56(%rsp)
	movq	%rax, 68(%rsp)
	movl	$1, 76(%rsp)
	call	__cudaPopCallConfiguration@PLT
	testl	%eax, %eax
	jne	.L301
	pushq	48(%rsp)
	.cfi_def_cfa_offset 168
	leaq	_Z10TrimmQualsPcPsis(%rip), %rdi
	pushq	48(%rsp)
	.cfi_def_cfa_offset 176
	movq	84(%rsp), %rcx
	movl	92(%rsp), %r8d
	movq	72(%rsp), %rsi
	movl	80(%rsp), %edx
	leaq	120(%rsp), %r9
	call	cudaLaunchKernel@PLT
	popq	%rax
	.cfi_def_cfa_offset 168
	popq	%rdx
	.cfi_def_cfa_offset 160
.L301:
	movq	136(%rsp), %rax
	subq	%fs:40, %rax
	je	.L303
	call	__stack_chk_fail@PLT
.L303:
	addq	$152, %rsp
	.cfi_def_cfa_offset 8
	ret
	.cfi_endproc
.LFE2082:
	.size	_Z34__device_stub__Z10TrimmQualsPcPsisPcPsis, .-_Z34__device_stub__Z10TrimmQualsPcPsisPcPsis
	.globl	_Z10TrimmQualsPcPsis
	.type	_Z10TrimmQualsPcPsis, @function
_Z10TrimmQualsPcPsis:
.LFB2083:
	.cfi_startproc
	endbr64
	movswl	%cx, %ecx
	jmp	_Z34__device_stub__Z10TrimmQualsPcPsisPcPsis
	.cfi_endproc
.LFE2083:
	.size	_Z10TrimmQualsPcPsis, .-_Z10TrimmQualsPcPsis
	.section	.rodata.str1.1
.LC120:
	.string	"\nPreprocessing reads on GPU\n"
.LC121:
	.string	"[%d] TrimmQuals\n"
.LC122:
	.string	"[%d] Find_gRNA\n"
.LC123:
	.string	"[%d] TrimmAdaptors\n"
.LC124:
	.string	"[%d] Memcpy DtoH %d reads\n"
.LC125:
	.string	"[%d] > ReadsSentToGPU = %d\n"
.LC126:
	.string	"[%d] Writing hReadLen[%d][%d]\n"
	.text
	.globl	_Z20PreprocessReadsOnGPUv
	.type	_Z20PreprocessReadsOnGPUv, @function
_Z20PreprocessReadsOnGPUv:
.LFB2049:
	.cfi_startproc
	endbr64
	pushq	%r15
	.cfi_def_cfa_offset 16
	.cfi_offset 15, -16
	pushq	%r14
	.cfi_def_cfa_offset 24
	.cfi_offset 14, -24
	pushq	%r13
	.cfi_def_cfa_offset 32
	.cfi_offset 13, -32
	pushq	%r12
	.cfi_def_cfa_offset 40
	.cfi_offset 12, -40
	pushq	%rbp
	.cfi_def_cfa_offset 48
	.cfi_offset 6, -48
	pushq	%rbx
	.cfi_def_cfa_offset 56
	.cfi_offset 3, -56
	subq	$120, %rsp
	.cfi_def_cfa_offset 176
	movq	%fs:40, %rax
	movq	%rax, 104(%rsp)
	xorl	%eax, %eax
	cmpb	$0, verbose(%rip)
	je	.L307
	leaq	.LC120(%rip), %rsi
	movl	$2, %edi
	call	__printf_chk@PLT
.L307:
	xorl	%esi, %esi
	movb	$0, (%rsp)
	leaq	dIntArray(%rip), %r14
	xorl	%ebx, %ebx
	movl	%esi, 12(%rsp)
	leaq	upload_stream(%rip), %r15
	leaq	compute_stream(%rip), %r12
	leaq	device(%rip), %r13
.L334:
	movl	12(%rsp), %eax
	cmpl	%eax, numGPUs(%rip)
	jle	.L427
	xorl	%r8d, %r8d
	cmpb	$0, (%rsp)
	movl	%r8d, 72(%rsp,%rbx)
	movl	%r8d, 88(%rsp,%rbx)
	jne	.L308
	leaq	hReadQualstr(%rip), %rax
	movl	MAX_READS_ON_GPU(%rip), %edi
	movq	(%rax,%rbx,2), %rcx
	leaq	hReadSequence(%rip), %rax
	movq	(%rax,%rbx,4), %rdx
	leaq	hReadLen(%rip), %rax
	movq	(%rax,%rbx,4), %rsi
	call	_Z16ReadBlockOfReadsiPsPcS0_
	movl	%eax, 72(%rsp,%rbx)
	movl	%eax, %ebp
	movl	MAX_READS_ON_GPU(%rip), %eax
	movl	%eax, 16(%rsp)
	testl	%ebp, %ebp
	je	.L309
	movl	0(%r13), %edi
	call	cudaSetDevice@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L310
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$674, %r8d
	movq	%rax, %rcx
	jmp	.L426
.L310:
	cmpb	$0, QualityTrimming(%rip)
	movq	(%r15), %r8
	je	.L311
	movswl	MAX_READ_LENGTH(%rip), %edx
	leaq	hReadQualstr(%rip), %rax
	movl	$1, %ecx
	movq	(%rax,%rbx,2), %rsi
	leaq	dQualArray(%rip), %rax
	imull	%ebp, %edx
	movq	(%rax,%rbx,2), %rdi
	movslq	%edx, %rdx
	call	cudaMemcpyAsync@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L311
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$676, %r8d
	movq	%rax, %rcx
.L426:
	movq	stderr(%rip), %rdi
	leaq	.LC5(%rip), %rdx
	movl	$2, %esi
	xorl	%eax, %eax
	call	__fprintf_chk@PLT
	movl	$1, %edi
	call	exit@PLT
.L311:
	movslq	%ebp, %rax
	movq	(%r14), %rdi
	movq	(%r15), %r8
	movl	$1, %ecx
	addq	%rax, %rax
	movq	%rax, (%rsp)
	leaq	hReadLen(%rip), %rax
	movq	(%rsp), %rdx
	movq	(%rax,%rbx,4), %rsi
	call	cudaMemcpyAsync@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L312
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$677, %r8d
	movq	%rax, %rcx
	jmp	.L426
.L312:
	leaq	QUAL_COPY_DONE(%rip), %rdx
	movq	(%r15), %rsi
	movq	(%rdx,%rbx,2), %rdi
	call	cudaEventRecord@PLT
	leaq	QUAL_COPY_DONE(%rip), %rdx
	testl	%eax, %eax
	movl	%eax, %edi
	je	.L313
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$678, %r8d
	movq	%rax, %rcx
	jmp	.L426
.L313:
	movq	(%rdx,%rbx,2), %rsi
	movq	(%r12), %rdi
	xorl	%edx, %edx
	call	cudaStreamWaitEvent@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L314
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$680, %r8d
	movq	%rax, %rcx
	jmp	.L426
.L314:
	cmpb	$0, QualityTrimming(%rip)
	je	.L315
	cmpb	$0, verbose(%rip)
	je	.L316
	movl	0(%r13), %edx
	leaq	.LC121(%rip), %rsi
	movl	$2, %edi
	xorl	%eax, %eax
	call	__printf_chk@PLT
.L316:
	movl	$16777217, %edx
	movl	$1048577, %edi
	movq	(%r12), %r9
	xorl	%r8d, %r8d
	salq	$8, %rdx
	salq	$12, %rdi
	movl	$1, %ecx
	movl	$1, %esi
	movq	%rdx, 60(%rsp)
	movl	$1, 68(%rsp)
	movq	%rdi, 48(%rsp)
	movl	$1, 56(%rsp)
	call	__cudaPushCallConfiguration@PLT
	testl	%eax, %eax
	jne	.L317
	leaq	dQualArray(%rip), %rax
	movswl	MAX_READ_LENGTH(%rip), %ecx
	movq	(%r14), %rsi
	movl	%ebp, %edx
	movq	(%rax,%rbx,2), %rdi
	call	_Z34__device_stub__Z10TrimmQualsPcPsisPcPsis
.L317:
	call	cudaGetLastError@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L315
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$685, %r8d
	movq	%rax, %rcx
	jmp	.L426
.L315:
	leaq	TrimmQ_DONE(%rip), %rax
	movq	(%r12), %rsi
	movq	(%rax,%rbx,2), %rdi
	call	cudaEventRecord@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L318
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$687, %r8d
	movq	%rax, %rcx
	jmp	.L426
.L318:
	cmpb	$0, AdaptorTrimming(%rip)
	jne	.L319
	cmpb	$0, gRNATrimming(%rip)
	je	.L320
.L319:
	movswl	MAX_READ_LENGTH(%rip), %edx
	leaq	hReadSequence(%rip), %rax
	movq	(%r15), %r8
	movl	$1, %ecx
	movq	(%rax,%rbx,4), %rsi
	leaq	dSequenceArray(%rip), %rax
	imull	%ebp, %edx
	movq	(%rax,%rbx,2), %rdi
	movslq	%edx, %rdx
	call	cudaMemcpyAsync@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L320
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$689, %r8d
	movq	%rax, %rcx
	jmp	.L426
.L320:
	leaq	SEQ_COPY_DONE(%rip), %rdx
	movq	(%r15), %rsi
	movq	(%rdx,%rbx,2), %rdi
	call	cudaEventRecord@PLT
	leaq	SEQ_COPY_DONE(%rip), %rdx
	testl	%eax, %eax
	movl	%eax, %edi
	je	.L321
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$690, %r8d
	movq	%rax, %rcx
	jmp	.L426
.L321:
	movq	(%rdx,%rbx,2), %rsi
	movq	(%r12), %rdi
	xorl	%edx, %edx
	call	cudaStreamWaitEvent@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L322
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$692, %r8d
	movq	%rax, %rcx
	jmp	.L426
.L322:
	cmpb	$0, gRNATrimming(%rip)
	je	.L323
	cmpb	$0, verbose(%rip)
	je	.L324
	movl	0(%r13), %edx
	leaq	.LC122(%rip), %rsi
	movl	$2, %edi
	xorl	%eax, %eax
	call	__printf_chk@PLT
.L324:
	movl	$16777217, %edx
	movl	$1048577, %edi
	movq	(%r12), %r9
	xorl	%r8d, %r8d
	salq	$8, %rdx
	salq	$12, %rdi
	movl	$1, %ecx
	movl	$1, %esi
	movq	%rdx, 60(%rsp)
	movl	$1, 68(%rsp)
	movq	%rdi, 48(%rsp)
	movl	$1, 56(%rsp)
	call	__cudaPushCallConfiguration@PLT
	testl	%eax, %eax
	jne	.L325
	leaq	dSequenceArray(%rip), %rax
	movswl	MAX_READ_LENGTH(%rip), %ecx
	movq	(%r14), %rsi
	movl	%ebp, %edx
	movq	(%rax,%rbx,2), %rdi
	call	_Z32__device_stub__Z9Find_gRNAPcPsisPcPsis
.L325:
	call	cudaGetLastError@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L326
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$697, %r8d
	movq	%rax, %rcx
	jmp	.L426
.L323:
	cmpb	$0, AdaptorTrimming(%rip)
	je	.L326
	cmpb	$0, verbose(%rip)
	je	.L327
	movl	0(%r13), %edx
	leaq	.LC123(%rip), %rsi
	movl	$2, %edi
	xorl	%eax, %eax
	call	__printf_chk@PLT
.L327:
	movl	$16777217, %edx
	movl	$1048577, %edi
	movq	(%r12), %r9
	xorl	%r8d, %r8d
	salq	$8, %rdx
	salq	$12, %rdi
	movl	$1, %ecx
	movl	$1, %esi
	movq	%rdx, 60(%rsp)
	movl	$1, 68(%rsp)
	movq	%rdi, 48(%rsp)
	movl	$1, 56(%rsp)
	call	__cudaPushCallConfiguration@PLT
	testl	%eax, %eax
	jne	.L328
	leaq	dSequenceArray(%rip), %rax
	movswl	MAX_READ_LENGTH(%rip), %ecx
	movq	(%r14), %rsi
	movl	%ebp, %edx
	movq	(%rax,%rbx,2), %rdi
	call	_Z37__device_stub__Z13TrimmAdaptorsPcPsisPcPsis
.L328:
	call	cudaGetLastError@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L326
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$705, %r8d
	movq	%rax, %rcx
	jmp	.L426
.L326:
	leaq	TrimmA_DONE(%rip), %rdx
	movq	(%r12), %rsi
	movq	(%rdx,%rbx,2), %rdi
	call	cudaEventRecord@PLT
	leaq	TrimmA_DONE(%rip), %rdx
	testl	%eax, %eax
	movl	%eax, %edi
	je	.L329
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$708, %r8d
	movq	%rax, %rcx
	jmp	.L426
.L329:
	leaq	download_stream(%rip), %r9
	movq	(%rdx,%rbx,2), %rsi
	xorl	%edx, %edx
	movq	(%r9,%rbx,2), %rdi
	call	cudaStreamWaitEvent@PLT
	leaq	download_stream(%rip), %r9
	testl	%eax, %eax
	movl	%eax, %edi
	je	.L330
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$710, %r8d
	movq	%rax, %rcx
	jmp	.L426
.L330:
	leaq	hReadLen(%rip), %rax
	movq	(%r9,%rbx,2), %r8
	movq	(%rsp), %rdx
	movl	$2, %ecx
	movq	(%rax,%rbx,4), %rdi
	movq	(%r14), %rsi
	call	cudaMemcpyAsync@PLT
	leaq	download_stream(%rip), %r9
	testl	%eax, %eax
	movl	%eax, %edi
	je	.L331
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$711, %r8d
	movq	%rax, %rcx
	jmp	.L426
.L331:
	leaq	DTH_COPY_DONE(%rip), %rax
	movq	(%r9,%rbx,2), %rsi
	movq	(%rax,%rbx,2), %rdi
	call	cudaEventRecord@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L332
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$712, %r8d
	movq	%rax, %rcx
	jmp	.L426
.L332:
	cmpb	$0, verbose(%rip)
	je	.L333
	movl	0(%r13), %edx
	movl	%ebp, %ecx
	leaq	.LC124(%rip), %rsi
	xorl	%eax, %eax
	movl	$2, %edi
	call	__printf_chk@PLT
.L333:
	xorl	%edi, %edi
	movl	%ebp, 88(%rsp,%rbx)
	movl	%edi, 72(%rsp,%rbx)
.L309:
	cmpl	%ebp, 16(%rsp)
	setg	(%rsp)
.L308:
	incl	12(%rsp)
	addq	$4, %r13
	addq	$16, %r14
	addq	$8, %r12
	addq	$8, %r15
	addq	$4, %rbx
	jmp	.L334
.L427:
	xorl	%ecx, %ecx
	movl	$1, 20(%rsp)
	movl	%ecx, 40(%rsp)
	movl	%ecx, 44(%rsp)
.L377:
	movb	(%rsp), %al
	movb	%al, 16(%rsp)
	testb	%al, %al
	jne	.L336
	movslq	20(%rsp), %rbp
	movb	$1, 16(%rsp)
	xorl	%r14d, %r14d
	xorl	%ebx, %ebx
	leaq	upload_stream(%rip), %r13
	salq	$3, %rbp
.L337:
	cmpl	%ebx, numGPUs(%rip)
	jle	.L381
	leaq	device(%rip), %rax
	xorl	%edx, %edx
	movl	(%rax,%rbx,4), %edi
	movl	%edx, 72(%rsp,%rbx,4)
	call	cudaSetDevice@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L338
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$730, %r8d
	movq	%rax, %rcx
	jmp	.L426
.L338:
	cmpl	$0, 88(%rsp,%rbx,4)
	jle	.L339
	leaq	TrimmQ_DONE(%rip), %rax
	movq	(%rax,%rbx,8), %rdi
	call	cudaEventSynchronize@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L339
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$734, %r8d
	movq	%rax, %rcx
	jmp	.L426
.L339:
	leaq	hReadSequence(%rip), %rax
	leaq	hReadQualstr(%rip), %r15
	movl	MAX_READS_ON_GPU(%rip), %edi
	movq	(%rax,%rbp), %rdx
	leaq	hReadLen(%rip), %rax
	movq	(%r15,%rbx,8), %rcx
	movq	(%rax,%rbp), %rsi
	call	_Z16ReadBlockOfReadsiPsPcS0_
	cmpl	%eax, MAX_READS_ON_GPU(%rip)
	movl	%eax, 72(%rsp,%rbx,4)
	movl	%eax, %r12d
	movb	$1, %al
	cmovg	%eax, %r14d
	testl	%r12d, %r12d
	je	.L381
	cmpb	$0, QualityTrimming(%rip)
	movq	0(%r13), %r8
	je	.L341
	movswl	MAX_READ_LENGTH(%rip), %edx
	leaq	dQualArray(%rip), %rax
	movq	(%r15,%rbx,8), %rsi
	movl	$1, %ecx
	movq	(%rax,%rbx,8), %rdi
	imull	%r12d, %edx
	movslq	%edx, %rdx
	call	cudaMemcpyAsync@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L341
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$746, %r8d
	movq	%rax, %rcx
	jmp	.L426
.L341:
	leaq	hReadLen(%rip), %rax
	movq	0(%r13), %r8
	movslq	%r12d, %rdx
	movl	$1, %ecx
	movq	(%rax,%rbp), %rsi
	leaq	dIntArray(%rip), %rax
	addq	%rdx, %rdx
	movq	(%rax,%rbp), %rdi
	call	cudaMemcpyAsync@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L342
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$747, %r8d
	movq	%rax, %rcx
	jmp	.L426
.L342:
	leaq	QUAL_COPY_DONE(%rip), %r15
	movq	0(%r13), %rsi
	movq	(%r15,%rbx,8), %rdi
	call	cudaEventRecord@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L343
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$748, %r8d
	movq	%rax, %rcx
	jmp	.L426
.L343:
	leaq	compute_stream(%rip), %rax
	movq	(%r15,%rbx,8), %rsi
	xorl	%edx, %edx
	movq	(%rax,%rbx,8), %rdi
	call	cudaStreamWaitEvent@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L344
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$750, %r8d
	movq	%rax, %rcx
	jmp	.L426
.L344:
	cmpb	$0, QualityTrimming(%rip)
	je	.L345
	cmpb	$0, verbose(%rip)
	je	.L346
	leaq	device(%rip), %rax
	leaq	.LC121(%rip), %rsi
	movl	$2, %edi
	movl	(%rax,%rbx,4), %edx
	xorl	%eax, %eax
	call	__printf_chk@PLT
.L346:
	leaq	compute_stream(%rip), %rax
	movl	$16777217, %edx
	movl	$1048577, %edi
	xorl	%r8d, %r8d
	movq	(%rax,%rbx,8), %r9
	salq	$8, %rdx
	salq	$12, %rdi
	movl	$1, %ecx
	movl	$1, %esi
	movq	%rdx, 60(%rsp)
	movl	$1, 68(%rsp)
	movq	%rdi, 48(%rsp)
	movl	$1, 56(%rsp)
	call	__cudaPushCallConfiguration@PLT
	testl	%eax, %eax
	jne	.L347
	leaq	dIntArray(%rip), %rax
	movswl	MAX_READ_LENGTH(%rip), %ecx
	movl	%r12d, %edx
	movq	(%rax,%rbp), %rsi
	leaq	dQualArray(%rip), %rax
	movq	(%rax,%rbx,8), %rdi
	call	_Z34__device_stub__Z10TrimmQualsPcPsisPcPsis
.L347:
	call	cudaGetLastError@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L345
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$755, %r8d
	movq	%rax, %rcx
	jmp	.L426
.L345:
	movb	$0, 16(%rsp)
	incq	%rbx
	addq	$8, %r13
	addq	$16, %rbp
	jmp	.L337
.L381:
	movb	%r14b, (%rsp)
.L336:
	movslq	20(%rsp), %rax
	leaq	dSequenceArray(%rip), %r12
	leaq	device(%rip), %r13
	xorl	%ebx, %ebx
	leaq	compute_stream(%rip), %rbp
	leaq	upload_stream(%rip), %r14
	leaq	0(,%rax,8), %r15
	leaq	dIntArray(%rip), %rax
	addq	%r15, %rax
	movq	%rax, 24(%rsp)
	leaq	hReadSequence(%rip), %rax
	addq	%r15, %rax
	movq	%rax, 32(%rsp)
.L349:
	cmpl	%ebx, numGPUs(%rip)
	jle	.L428
	movl	72(%rsp,%rbx,4), %eax
	movl	%eax, 12(%rsp)
	testl	%eax, %eax
	jle	.L350
	movl	0(%r13), %edi
	call	cudaSetDevice@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L351
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$764, %r8d
	movq	%rax, %rcx
	jmp	.L426
.L351:
	cmpl	$0, 88(%rsp,%rbx,4)
	jle	.L352
	leaq	TrimmA_DONE(%rip), %rax
	movq	(%rax,%rbx,8), %rdi
	call	cudaEventSynchronize@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L352
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$768, %r8d
	movq	%rax, %rcx
	jmp	.L426
.L352:
	cmpb	$0, AdaptorTrimming(%rip)
	jne	.L353
	cmpb	$0, gRNATrimming(%rip)
	je	.L354
.L353:
	movl	12(%rsp), %eax
	movswl	MAX_READ_LENGTH(%rip), %edx
	movl	$1, %ecx
	movq	(%r12), %rdi
	movq	(%r14,%rbx,8), %r8
	imull	%eax, %edx
	movq	32(%rsp), %rax
	movq	(%rax), %rsi
	movslq	%edx, %rdx
	call	cudaMemcpyAsync@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L354
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$771, %r8d
	movq	%rax, %rcx
	jmp	.L426
.L354:
	leaq	SEQ_COPY_DONE(%rip), %rdx
	movq	(%r14,%rbx,8), %rsi
	movq	(%rdx,%rbx,8), %rdi
	call	cudaEventRecord@PLT
	leaq	SEQ_COPY_DONE(%rip), %rdx
	testl	%eax, %eax
	movl	%eax, %edi
	je	.L355
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$772, %r8d
	movq	%rax, %rcx
	jmp	.L426
.L355:
	movq	(%rdx,%rbx,8), %rsi
	movq	0(%rbp), %rdi
	xorl	%edx, %edx
	call	cudaStreamWaitEvent@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L356
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$774, %r8d
	movq	%rax, %rcx
	jmp	.L426
.L356:
	cmpb	$0, gRNATrimming(%rip)
	je	.L357
	cmpb	$0, verbose(%rip)
	je	.L358
	movl	0(%r13), %edx
	leaq	.LC122(%rip), %rsi
	movl	$2, %edi
	xorl	%eax, %eax
	call	__printf_chk@PLT
.L358:
	movl	$16777217, %edx
	movl	$1048577, %edi
	movq	0(%rbp), %r9
	xorl	%r8d, %r8d
	salq	$8, %rdx
	salq	$12, %rdi
	movl	$1, %ecx
	movl	$1, %esi
	movq	%rdx, 60(%rsp)
	movl	$1, 68(%rsp)
	movq	%rdi, 48(%rsp)
	movl	$1, 56(%rsp)
	call	__cudaPushCallConfiguration@PLT
	testl	%eax, %eax
	jne	.L359
	movq	24(%rsp), %rax
	movswl	MAX_READ_LENGTH(%rip), %ecx
	movl	12(%rsp), %edx
	movq	(%r12), %rdi
	movq	(%rax), %rsi
	call	_Z32__device_stub__Z9Find_gRNAPcPsisPcPsis
.L359:
	call	cudaGetLastError@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L360
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$779, %r8d
	movq	%rax, %rcx
	jmp	.L426
.L357:
	cmpb	$0, AdaptorTrimming(%rip)
	je	.L360
	cmpb	$0, verbose(%rip)
	je	.L361
	movl	0(%r13), %edx
	leaq	.LC123(%rip), %rsi
	movl	$2, %edi
	xorl	%eax, %eax
	call	__printf_chk@PLT
.L361:
	movl	$16777217, %edx
	movl	$1048577, %edi
	movq	0(%rbp), %r9
	xorl	%r8d, %r8d
	salq	$8, %rdx
	salq	$12, %rdi
	movl	$1, %ecx
	movl	$1, %esi
	movq	%rdx, 60(%rsp)
	movl	$1, 68(%rsp)
	movq	%rdi, 48(%rsp)
	movl	$1, 56(%rsp)
	call	__cudaPushCallConfiguration@PLT
	testl	%eax, %eax
	jne	.L362
	movq	24(%rsp), %rax
	movswl	MAX_READ_LENGTH(%rip), %ecx
	movl	12(%rsp), %edx
	movq	(%r12), %rdi
	movq	(%rax), %rsi
	call	_Z37__device_stub__Z13TrimmAdaptorsPcPsisPcPsis
.L362:
	call	cudaGetLastError@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L360
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$787, %r8d
	movq	%rax, %rcx
	jmp	.L426
.L360:
	leaq	TrimmA_DONE(%rip), %rax
	movq	0(%rbp), %rsi
	movq	(%rax,%rbx,8), %rdi
	call	cudaEventRecord@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L350
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$790, %r8d
	movq	%rax, %rcx
	jmp	.L426
.L350:
	incq	%rbx
	addq	$8, %rbp
	addq	$8, %r12
	addq	$4, %r13
	addq	$16, 24(%rsp)
	addq	$16, 32(%rsp)
	jmp	.L349
.L428:
	movslq	40(%rsp), %rax
	leaq	hReadLen(%rip), %rdx
	leaq	download_stream(%rip), %r12
	xorl	%ebx, %ebx
	leaq	device(%rip), %rbp
	leaq	(%rdx,%rax,8), %r14
.L364:
	cmpl	%ebx, numGPUs(%rip)
	movl	%ebx, 12(%rsp)
	jle	.L429
	cmpb	$0, verbose(%rip)
	movl	88(%rsp,%rbx,4), %r13d
	je	.L365
	movl	12(%rsp), %edx
	movl	%r13d, %ecx
	leaq	.LC125(%rip), %rsi
	xorl	%eax, %eax
	movl	$2, %edi
	call	__printf_chk@PLT
.L365:
	testl	%r13d, %r13d
	jle	.L366
	movl	0(%rbp), %edi
	call	cudaSetDevice@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L367
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$800, %r8d
	movq	%rax, %rcx
	jmp	.L426
.L367:
	leaq	DTH_COPY_DONE(%rip), %rax
	movq	(%rax,%rbx,8), %rdi
	call	cudaEventSynchronize@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L368
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$801, %r8d
	movq	%rax, %rcx
	jmp	.L426
.L368:
	cmpb	$0, verbose(%rip)
	je	.L369
	movl	40(%rsp), %r8d
	movl	12(%rsp), %ecx
	movl	$2, %edi
	xorl	%eax, %eax
	movl	0(%rbp), %edx
	leaq	.LC126(%rip), %rsi
	call	__printf_chk@PLT
.L369:
	movswl	MIN_OUT_READ_LEN(%rip), %edx
	movq	(%r14), %rsi
	movl	%r13d, %edi
	call	_Z17WriteBlockOfReadsiPKss
	addl	%r13d, 44(%rsp)
.L366:
	movl	72(%rsp,%rbx,4), %r13d
	testl	%r13d, %r13d
	jle	.L371
	leaq	TrimmA_DONE(%rip), %rax
	movq	(%r12), %rdi
	xorl	%edx, %edx
	movq	(%rax,%rbx,8), %rsi
	call	cudaStreamWaitEvent@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L372
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$809, %r8d
	movq	%rax, %rcx
	jmp	.L426
.L372:
	leaq	dIntArray(%rip), %rax
	movq	(%r12), %r8
	movslq	%r13d, %rdx
	movl	$2, %ecx
	movq	(%rax,%r15), %rsi
	leaq	hReadLen(%rip), %rax
	addq	%rdx, %rdx
	movq	(%rax,%r15), %rdi
	call	cudaMemcpyAsync@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L373
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$810, %r8d
	movq	%rax, %rcx
	jmp	.L426
.L373:
	leaq	DTH_COPY_DONE(%rip), %rax
	movq	(%r12), %rsi
	movq	(%rax,%rbx,8), %rdi
	call	cudaEventRecord@PLT
	movl	%eax, %edi
	testl	%eax, %eax
	je	.L374
	call	cudaGetErrorString@PLT
	leaq	.LC4(%rip), %r9
	movl	$811, %r8d
	movq	%rax, %rcx
	jmp	.L426
.L374:
	cmpb	$0, verbose(%rip)
	je	.L371
	movl	0(%rbp), %edx
	movl	%r13d, %ecx
	leaq	.LC124(%rip), %rsi
	xorl	%eax, %eax
	movl	$2, %edi
	call	__printf_chk@PLT
.L371:
	xorl	%eax, %eax
	movl	%r13d, 88(%rsp,%rbx,4)
	addq	$4, %rbp
	addq	$8, %r12
	movl	%eax, 72(%rsp,%rbx,4)
	addq	$16, %r14
	incq	%rbx
	addq	$16, %r15
	jmp	.L364
.L429:
	movl	40(%rsp), %ebx
	cmpb	$0, 16(%rsp)
	movl	20(%rsp), %eax
	movl	%ebx, 20(%rsp)
	jne	.L430
	movl	%eax, 40(%rsp)
	jmp	.L377
.L430:
	movq	104(%rsp), %rax
	subq	%fs:40, %rax
	je	.L378
	call	__stack_chk_fail@PLT
.L378:
	movl	44(%rsp), %eax
	addq	$120, %rsp
	.cfi_def_cfa_offset 56
	popq	%rbx
	.cfi_def_cfa_offset 48
	popq	%rbp
	.cfi_def_cfa_offset 40
	popq	%r12
	.cfi_def_cfa_offset 32
	popq	%r13
	.cfi_def_cfa_offset 24
	popq	%r14
	.cfi_def_cfa_offset 16
	popq	%r15
	.cfi_def_cfa_offset 8
	ret
	.cfi_endproc
.LFE2049:
	.size	_Z20PreprocessReadsOnGPUv, .-_Z20PreprocessReadsOnGPUv
	.section	.rodata.str1.1
.LC127:
	.string	"\nERROR: No suitable CUDA devices found ... exiting\n"
.LC128:
	.string	"\nOne CUDA device with at least compute capability 3.5 and 6 GB memory found.\n"
.LC129:
	.string	"\n%d CUDA devices with at least compute capability 3.5 and 6 GB memory found.\n"
.LC130:
	.string	"<AUTO DETECTION> FastQ Quality Encoding: PHRED+%d\n"
.LC131:
	.string	"\nERROR: Unable to detect FastQ format version.\n"
.LC132:
	.string	"\nReads processed: %d\n"
.LC133:
	.string	"Reads in input file %s : %d\n"
.LC134:
	.string	"Reads written to output file %s : %d\n"
.LC135:
	.string	"Encountered potential issues with the FastQ file format in %s\n"
.LC136:
	.string	"\nTotal time elapsed: %.0lf seconds\n"
	.section	.text.startup,"ax",@progbits
	.globl	main
	.type	main, @function
main:
.LFB2053:
	.cfi_startproc
	endbr64
	pushq	%rbp
	.cfi_def_cfa_offset 16
	.cfi_offset 6, -16
	movl	%edi, %ebp
	xorl	%edi, %edi
	pushq	%rbx
	.cfi_def_cfa_offset 24
	.cfi_offset 3, -24
	subq	$24, %rsp
	.cfi_def_cfa_offset 48
	movq	%rsi, 8(%rsp)
	call	time@PLT
	movq	8(%rsp), %rsi
	movl	%ebp, %edi
	movq	%rax, %rbx
	call	_Z25parseCommandLineArgumentsiPPc
	cmpl	$0, numGPUs(%rip)
	jne	.L432
	call	_Z8FindGPUsv
	testl	%eax, %eax
	jne	.L433
	movl	$2, %edi
	leaq	.LC127(%rip), %rsi
	call	__printf_chk@PLT
	movl	$1, %edi
	jmp	.L440
.L433:
	movl	numGPUs(%rip), %edx
	cmpl	$1, %edx
	jne	.L434
	leaq	.LC128(%rip), %rsi
	movl	$2, %edi
	xorl	%eax, %eax
	call	__printf_chk@PLT
	jmp	.L432
.L434:
	leaq	.LC129(%rip), %rsi
	movl	$2, %edi
	xorl	%eax, %eax
	call	__printf_chk@PLT
.L432:
	cmpb	$0, auto_phred_detect(%rip)
	je	.L437
	call	_Z25Detect_FastQ_Format_PHREDv
	testb	%al, %al
	je	.L436
	cmpb	$0, verbose(%rip)
	je	.L437
	movswl	PHRED(%rip), %edx
	leaq	.LC130(%rip), %rsi
	movl	$2, %edi
	xorl	%eax, %eax
	call	__printf_chk@PLT
	jmp	.L437
.L436:
	movl	$2, %edi
	leaq	.LC131(%rip), %rsi
	xorl	%eax, %eax
	call	__printf_chk@PLT
	movl	$32, %edi
.L440:
	call	exit@PLT
.L437:
	call	_Z9OpenFilesv
	leaq	input_filename(%rip), %rbp
	call	_Z8InitGPUsv
	movswl	MIN_QUAL_AFTER_BAD(%rip), %r8d
	movswl	MIN_BASE_QUAL(%rip), %ecx
	leaq	Adaptor(%rip), %rdi
	movswl	PHRED(%rip), %edx
	movswl	mismatches(%rip), %esi
	call	_Z18SetAdaptorSequencePKcssss
	call	_Z20PreprocessReadsOnGPUv
	leaq	.LC132(%rip), %rsi
	movl	$2, %edi
	movl	%eax, %edx
	xorl	%eax, %eax
	call	__printf_chk@PLT
	movl	hNumberOfReads(%rip), %ecx
	movq	%rbp, %rdx
	xorl	%eax, %eax
	leaq	.LC133(%rip), %rsi
	movl	$2, %edi
	call	__printf_chk@PLT
	movl	hReadsWritten(%rip), %ecx
	xorl	%eax, %eax
	leaq	output_filename(%rip), %rdx
	leaq	.LC134(%rip), %rsi
	movl	$2, %edi
	call	__printf_chk@PLT
	cmpb	$0, FastQ_WARNING(%rip)
	je	.L438
	movq	%rbp, %rdx
	leaq	.LC135(%rip), %rsi
	movl	$2, %edi
	xorl	%eax, %eax
	call	__printf_chk@PLT
.L438:
	call	_Z10CloseFilesv
	call	_Z8FreeGPUsv
	xorl	%edi, %edi
	call	time@PLT
	movq	%rbx, %rsi
	movq	%rax, %rdi
	call	difftime@PLT
	leaq	.LC136(%rip), %rsi
	movl	$2, %edi
	movb	$1, %al
	call	__printf_chk@PLT
	addq	$24, %rsp
	.cfi_def_cfa_offset 24
	xorl	%eax, %eax
	popq	%rbx
	.cfi_def_cfa_offset 16
	popq	%rbp
	.cfi_def_cfa_offset 8
	ret
	.cfi_endproc
.LFE2053:
	.size	main, .-main
	.section	.rodata.str1.1
.LC137:
	.string	"_Z10TrimmQualsPcPsis"
.LC138:
	.string	"_Z13TrimmAdaptorsPcPsis"
.LC139:
	.string	"_Z9Find_gRNAPcPsis"
.LC140:
	.string	"ADAPTOR"
.LC141:
	.string	"ADAPTOR_LEN"
.LC142:
	.string	"MAX_MM"
.LC143:
	.string	"QUAL_PADDING"
.LC144:
	.string	"MIN_QUAL"
.LC145:
	.string	"MIN_AVERAGE_QUAL_AFTER_BAD"
	.section	.text.startup
	.type	_ZL24__sti____cudaRegisterAllv, @function
_ZL24__sti____cudaRegisterAllv:
.LFB2085:
	.cfi_startproc
	endbr64
	pushq	%rbx
	.cfi_def_cfa_offset 16
	.cfi_offset 3, -16
	leaq	_ZL15__fatDeviceText(%rip), %rdi
	call	__cudaRegisterFatBinary@PLT
	pushq	$0
	.cfi_def_cfa_offset 24
	xorl	%r9d, %r9d
	orl	$-1, %r8d
	pushq	$0
	.cfi_def_cfa_offset 32
	leaq	.LC137(%rip), %rdx
	movq	%rax, %rdi
	movq	%rax, %rbx
	pushq	$0
	.cfi_def_cfa_offset 40
	movq	%rdx, %rcx
	leaq	_Z10TrimmQualsPcPsis(%rip), %rsi
	pushq	$0
	.cfi_def_cfa_offset 48
	movq	%rax, _ZL20__cudaFatCubinHandle(%rip)
	call	__cudaRegisterFunction@PLT
	addq	$32, %rsp
	.cfi_def_cfa_offset 16
	movq	%rbx, %rdi
	xorl	%r9d, %r9d
	pushq	$0
	.cfi_def_cfa_offset 24
	leaq	.LC138(%rip), %rdx
	orl	$-1, %r8d
	leaq	_Z13TrimmAdaptorsPcPsis(%rip), %rsi
	pushq	$0
	.cfi_def_cfa_offset 32
	movq	%rdx, %rcx
	pushq	$0
	.cfi_def_cfa_offset 40
	pushq	$0
	.cfi_def_cfa_offset 48
	call	__cudaRegisterFunction@PLT
	addq	$32, %rsp
	.cfi_def_cfa_offset 16
	movq	%rbx, %rdi
	xorl	%r9d, %r9d
	pushq	$0
	.cfi_def_cfa_offset 24
	leaq	.LC139(%rip), %rdx
	orl	$-1, %r8d
	leaq	_Z9Find_gRNAPcPsis(%rip), %rsi
	pushq	$0
	.cfi_def_cfa_offset 32
	movq	%rdx, %rcx
	pushq	$0
	.cfi_def_cfa_offset 40
	pushq	$0
	.cfi_def_cfa_offset 48
	call	__cudaRegisterFunction@PLT
	addq	$32, %rsp
	.cfi_def_cfa_offset 16
	movq	%rbx, %rdi
	xorl	%r8d, %r8d
	pushq	$0
	.cfi_def_cfa_offset 24
	leaq	.LC140(%rip), %rdx
	movl	$100, %r9d
	leaq	_ZL7ADAPTOR(%rip), %rsi
	pushq	$1
	.cfi_def_cfa_offset 32
	movq	%rdx, %rcx
	call	__cudaRegisterVar@PLT
	popq	%rax
	.cfi_def_cfa_offset 24
	popq	%rdx
	.cfi_def_cfa_offset 16
	pushq	$0
	.cfi_def_cfa_offset 24
	pushq	$1
	.cfi_def_cfa_offset 32
	leaq	.LC141(%rip), %rdx
	movq	%rbx, %rdi
	xorl	%r8d, %r8d
	movq	%rdx, %rcx
	movl	$2, %r9d
	leaq	_ZL11ADAPTOR_LEN(%rip), %rsi
	call	__cudaRegisterVar@PLT
	popq	%rcx
	.cfi_def_cfa_offset 24
	popq	%rsi
	.cfi_def_cfa_offset 16
	pushq	$0
	.cfi_def_cfa_offset 24
	pushq	$1
	.cfi_def_cfa_offset 32
	leaq	.LC142(%rip), %rdx
	movq	%rbx, %rdi
	xorl	%r8d, %r8d
	movq	%rdx, %rcx
	movl	$2, %r9d
	leaq	_ZL6MAX_MM(%rip), %rsi
	call	__cudaRegisterVar@PLT
	popq	%rdi
	.cfi_def_cfa_offset 24
	popq	%r8
	.cfi_def_cfa_offset 16
	pushq	$0
	.cfi_def_cfa_offset 24
	pushq	$1
	.cfi_def_cfa_offset 32
	leaq	.LC143(%rip), %rdx
	movq	%rbx, %rdi
	xorl	%r8d, %r8d
	movq	%rdx, %rcx
	movl	$2, %r9d
	leaq	_ZL12QUAL_PADDING(%rip), %rsi
	call	__cudaRegisterVar@PLT
	popq	%r9
	.cfi_def_cfa_offset 24
	popq	%r10
	.cfi_def_cfa_offset 16
	pushq	$0
	.cfi_def_cfa_offset 24
	pushq	$1
	.cfi_def_cfa_offset 32
	leaq	.LC144(%rip), %rdx
	movq	%rbx, %rdi
	xorl	%r8d, %r8d
	movq	%rdx, %rcx
	movl	$2, %r9d
	leaq	_ZL8MIN_QUAL(%rip), %rsi
	call	__cudaRegisterVar@PLT
	popq	%r11
	.cfi_def_cfa_offset 24
	popq	%rax
	.cfi_def_cfa_offset 16
	pushq	$0
	.cfi_def_cfa_offset 24
	pushq	$1
	.cfi_def_cfa_offset 32
	leaq	.LC145(%rip), %rdx
	movq	%rbx, %rdi
	xorl	%r8d, %r8d
	movq	%rdx, %rcx
	movl	$2, %r9d
	leaq	_ZL26MIN_AVERAGE_QUAL_AFTER_BAD(%rip), %rsi
	call	__cudaRegisterVar@PLT
	movq	_ZL20__cudaFatCubinHandle(%rip), %rdi
	popq	%rax
	.cfi_def_cfa_offset 24
	popq	%rdx
	.cfi_def_cfa_offset 16
	call	__cudaRegisterFatBinaryEnd@PLT
	leaq	_ZL26__cudaUnregisterBinaryUtilv(%rip), %rdi
	popq	%rbx
	.cfi_def_cfa_offset 8
	jmp	atexit@PLT
	.cfi_endproc
.LFE2085:
	.size	_ZL24__sti____cudaRegisterAllv, .-_ZL24__sti____cudaRegisterAllv
	.section	.init_array,"aw"
	.align 8
	.quad	_ZL24__sti____cudaRegisterAllv
	.section	.nvFatBinSegment,"aw"
	.align 8
	.type	_ZL15__fatDeviceText, @object
	.size	_ZL15__fatDeviceText, 24
_ZL15__fatDeviceText:
	.long	1180844977
	.long	1
	.quad	fatbinData
	.quad	0
	.local	_ZL20__cudaFatCubinHandle
	.comm	_ZL20__cudaFatCubinHandle,8,8
	.local	_ZL26MIN_AVERAGE_QUAL_AFTER_BAD
	.comm	_ZL26MIN_AVERAGE_QUAL_AFTER_BAD,2,2
	.local	_ZL8MIN_QUAL
	.comm	_ZL8MIN_QUAL,2,2
	.local	_ZL12QUAL_PADDING
	.comm	_ZL12QUAL_PADDING,2,2
	.local	_ZL6MAX_MM
	.comm	_ZL6MAX_MM,2,2
	.local	_ZL11ADAPTOR_LEN
	.comm	_ZL11ADAPTOR_LEN,2,2
	.local	_ZL7ADAPTOR
	.comm	_ZL7ADAPTOR,100,32
	.globl	Read
	.bss
	.align 32
	.type	Read, @object
	.size	Read, 2000
Read:
	.zero	2000
	.globl	hReadQualstr
	.align 32
	.type	hReadQualstr, @object
	.size	hReadQualstr, 32
hReadQualstr:
	.zero	32
	.globl	hReadSequence
	.align 32
	.type	hReadSequence, @object
	.size	hReadSequence, 64
hReadSequence:
	.zero	64
	.globl	hReadLen
	.align 32
	.type	hReadLen, @object
	.size	hReadLen, 64
hReadLen:
	.zero	64
	.globl	DTH_COPY_DONE
	.align 32
	.type	DTH_COPY_DONE, @object
	.size	DTH_COPY_DONE, 32
DTH_COPY_DONE:
	.zero	32
	.globl	TrimmA_DONE
	.align 32
	.type	TrimmA_DONE, @object
	.size	TrimmA_DONE, 32
TrimmA_DONE:
	.zero	32
	.globl	TrimmQ_DONE
	.align 32
	.type	TrimmQ_DONE, @object
	.size	TrimmQ_DONE, 32
TrimmQ_DONE:
	.zero	32
	.globl	SEQ_COPY_DONE
	.align 32
	.type	SEQ_COPY_DONE, @object
	.size	SEQ_COPY_DONE, 32
SEQ_COPY_DONE:
	.zero	32
	.globl	QUAL_COPY_DONE
	.align 32
	.type	QUAL_COPY_DONE, @object
	.size	QUAL_COPY_DONE, 32
QUAL_COPY_DONE:
	.zero	32
	.globl	dIntArray
	.align 32
	.type	dIntArray, @object
	.size	dIntArray, 64
dIntArray:
	.zero	64
	.globl	dQualArray
	.align 32
	.type	dQualArray, @object
	.size	dQualArray, 32
dQualArray:
	.zero	32
	.globl	dSequenceArray
	.align 32
	.type	dSequenceArray, @object
	.size	dSequenceArray, 32
dSequenceArray:
	.zero	32
	.globl	download_stream
	.align 32
	.type	download_stream, @object
	.size	download_stream, 32
download_stream:
	.zero	32
	.globl	compute_stream
	.align 32
	.type	compute_stream, @object
	.size	compute_stream, 32
compute_stream:
	.zero	32
	.globl	upload_stream
	.align 32
	.type	upload_stream, @object
	.size	upload_stream, 32
upload_stream:
	.zero	32
	.globl	device
	.align 16
	.type	device, @object
	.size	device, 16
device:
	.zero	16
	.globl	numGPUs
	.align 4
	.type	numGPUs, @object
	.size	numGPUs, 4
numGPUs:
	.zero	4
	.globl	mismatches
	.data
	.align 2
	.type	mismatches, @object
	.size	mismatches, 2
mismatches:
	.value	2
	.globl	Adaptor
	.align 32
	.type	Adaptor, @object
	.size	Adaptor, 100
Adaptor:
	.string	"ATCTCGTATGCCGTCTTCTGCTT"
	.zero	76
	.globl	MAX_READS_ON_GPU
	.align 4
	.type	MAX_READS_ON_GPU, @object
	.size	MAX_READS_ON_GPU, 4
MAX_READS_ON_GPU:
	.long	10000000
	.globl	auto_phred_detect
	.bss
	.type	auto_phred_detect, @object
	.size	auto_phred_detect, 1
auto_phred_detect:
	.zero	1
	.globl	PHRED
	.data
	.align 2
	.type	PHRED, @object
	.size	PHRED, 2
PHRED:
	.value	33
	.globl	MIN_QUAL_AFTER_BAD
	.align 2
	.type	MIN_QUAL_AFTER_BAD, @object
	.size	MIN_QUAL_AFTER_BAD, 2
MIN_QUAL_AFTER_BAD:
	.value	25
	.globl	MIN_BASE_QUAL
	.align 2
	.type	MIN_BASE_QUAL, @object
	.size	MIN_BASE_QUAL, 2
MIN_BASE_QUAL:
	.value	20
	.globl	MIN_OUT_READ_LEN
	.align 2
	.type	MIN_OUT_READ_LEN, @object
	.size	MIN_OUT_READ_LEN, 2
MIN_OUT_READ_LEN:
	.value	26
	.globl	MAX_READ_LENGTH
	.align 2
	.type	MAX_READ_LENGTH, @object
	.size	MAX_READ_LENGTH, 2
MAX_READ_LENGTH:
	.value	203
	.globl	FastQ_WARNING
	.bss
	.type	FastQ_WARNING, @object
	.size	FastQ_WARNING, 1
FastQ_WARNING:
	.zero	1
	.globl	verbose
	.type	verbose, @object
	.size	verbose, 1
verbose:
	.zero	1
	.globl	gRNA_length
	.align 4
	.type	gRNA_length, @object
	.size	gRNA_length, 4
gRNA_length:
	.zero	4
	.globl	gRNA_start
	.align 4
	.type	gRNA_start, @object
	.size	gRNA_start, 4
gRNA_start:
	.zero	4
	.globl	gRNATrimming
	.type	gRNATrimming, @object
	.size	gRNATrimming, 1
gRNATrimming:
	.zero	1
	.globl	QualityTrimming
	.data
	.type	QualityTrimming, @object
	.size	QualityTrimming, 1
QualityTrimming:
	.byte	1
	.globl	AdaptorTrimming
	.type	AdaptorTrimming, @object
	.size	AdaptorTrimming, 1
AdaptorTrimming:
	.byte	1
	.globl	write_pigz_output
	.bss
	.type	write_pigz_output, @object
	.size	write_pigz_output, 1
write_pigz_output:
	.zero	1
	.globl	write_gz_output
	.type	write_gz_output, @object
	.size	write_gz_output, 1
write_gz_output:
	.zero	1
	.globl	overwrite_outputfile
	.type	overwrite_outputfile, @object
	.size	overwrite_outputfile, 1
overwrite_outputfile:
	.zero	1
	.globl	outputFile
	.align 8
	.type	outputFile, @object
	.size	outputFile, 8
outputFile:
	.zero	8
	.globl	templateFile
	.align 8
	.type	templateFile, @object
	.size	templateFile, 8
templateFile:
	.zero	8
	.globl	inputFile
	.align 8
	.type	inputFile, @object
	.size	inputFile, 8
inputFile:
	.zero	8
	.globl	PIGZ_PIPE
	.data
	.align 32
	.type	PIGZ_PIPE, @object
	.size	PIGZ_PIPE, 410
PIGZ_PIPE:
	.string	"pigz -> "
	.zero	401
	.globl	GZIP_PIPE
	.align 32
	.type	GZIP_PIPE, @object
	.size	GZIP_PIPE, 410
GZIP_PIPE:
	.string	"gzip -> "
	.zero	401
	.globl	output_filename
	.align 32
	.type	output_filename, @object
	.size	output_filename, 400
output_filename:
	.string	"/mnt/sdc/Sequences/out.txt"
	.zero	373
	.globl	input_filename
	.align 32
	.type	input_filename, @object
	.size	input_filename, 400
input_filename:
	.string	"/home/linux/cuda-workspace/PreprocessReads/test.txt"
	.zero	348
	.globl	hReadsWritten
	.bss
	.align 4
	.type	hReadsWritten, @object
	.size	hReadsWritten, 4
hReadsWritten:
	.zero	4
	.globl	hNumberOfReads
	.align 4
	.type	hNumberOfReads, @object
	.size	hNumberOfReads, 4
hNumberOfReads:
	.zero	4
	.section	.rodata.cst4,"aM",@progbits,4
	.align 4
.LC15:
	.long	897581056
	.ident	"GCC: (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0"
	.section	.note.GNU-stack,"",@progbits
	.section	.note.gnu.property,"a"
	.align 8
	.long	1f - 0f
	.long	4f - 1f
	.long	5
0:
	.string	"GNU"
1:
	.align 8
	.long	0xc0000002
	.long	3f - 2f
2:
	.long	0x3
3:
	.align 8
4:



#include <hip/hip_runtime.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <zlib.h>

int hNumberOfReads = 0;                 // holds number of reads that are processed
int hReadsWritten = 0;                  // number of reads written to output file
char input_filename[400]="/home/linux/cuda-workspace/PreprocessReads/test.txt"; // input file name
char output_filename[400]="/mnt/sdc/Sequences/out.txt";                         // output file name
char GZIP_PIPE[410] = "gzip -> ";       // option -gz will fallback to uncompressed if error on pipe opening
char PIGZ_PIPE[410] = "pigz -> ";       // option -pigz for multithreaded compression will fallback to gz and then to uncompressed
gzFile inputFile;
gzFile templateFile;						// holds a second pointer in input read file for templating output with read name sequence and quality
FILE *outputFile;
bool overwrite_outputfile = false;      // if set true the output file will be overwritten (cmd line option -f)
bool write_gz_output = false;           // specify .gz file compressed output (cmd line option -gz)
bool write_pigz_output = false;         // specify pigz multithreaded compression for output (-pigz option)

bool AdaptorTrimming = true;			// algorithm selectors
bool QualityTrimming = true;
bool gRNATrimming = false;
int gRNA_start;							// holds gRNA position relative to adaptor
int gRNA_length;
bool verbose = false;					// if true print details of processing to screen
bool FastQ_WARNING = false;				// set to true is a FastQ file warning has been issued

short MAX_READ_LENGTH = 203;            // maximal length of reads in input file
short MIN_OUT_READ_LEN = 26;            // minimum length of reads after trimming to write to output file

short MIN_BASE_QUAL = 20;				// parameter for minimum quality for good base
short MIN_QUAL_AFTER_BAD = 25;			// parameter for average base quality after bad base
short PHRED = 33;			        	// subtract from qualities for numerical value of solexa
bool auto_phred_detect = false;         // if true try to detect PHRED format in FastQ input file

int MAX_READS_ON_GPU = 10000000;        // maximum number of reads that fit simultaneously on GPU

#define MAX_ADAPTOR_LENGTH 100          // maximum length of adaptor sequence for trimming, can contain N for any base
#define MAX_FASTQ_BUF_LINE 500          // structure of buffer for read from FastQ file

char Adaptor[MAX_ADAPTOR_LENGTH] = "ATCTCGTATGCCGTCTTCTGCTT"; // adaptor on CPU side from parsing command line
short mismatches = 2;					// holds maximum number of mismatches on cpu side

int numGPUs = 0;                        // holds number of CUDA devices in the system [1 TITAN to max 2 TITAN Z]
#define MAX_GPU_NUM 4
int device[MAX_GPU_NUM];                // device numbers to use
hipStream_t upload_stream[MAX_GPU_NUM];    // cuda streams per device for overlapped asynchronous operation
hipStream_t compute_stream[MAX_GPU_NUM];
hipStream_t download_stream[MAX_GPU_NUM];

char *dSequenceArray[MAX_GPU_NUM];	    // device pointer to data array, will hold hReadSequence and hQualstr
char *dQualArray[MAX_GPU_NUM];			// device pointer to data array, will hold hReadSequence and hQualstr
short *dIntArray[MAX_GPU_NUM][2];       // two device pointers to integer array, will hold hReadLen
hipEvent_t QUAL_COPY_DONE[MAX_GPU_NUM];   // events for device host synchronization
hipEvent_t SEQ_COPY_DONE[MAX_GPU_NUM];
hipEvent_t TrimmQ_DONE[MAX_GPU_NUM];
hipEvent_t TrimmA_DONE[MAX_GPU_NUM];
hipEvent_t DTH_COPY_DONE[MAX_GPU_NUM];

short *hReadLen[MAX_GPU_NUM][2];        // two buffer to hold read length on host
char *hReadSequence[MAX_GPU_NUM][2];       // buffer holding sequences of reads on host
char *hReadQualstr[MAX_GPU_NUM];     // two buffer holding qualities of reads on host

struct read
{
    char name[MAX_FASTQ_BUF_LINE];
    char sequence[MAX_FASTQ_BUF_LINE];
    char descr[MAX_FASTQ_BUF_LINE];
    char qualstr[MAX_FASTQ_BUF_LINE];
} Read;                                 // buffer one read from FastQ file i 4 lines



// macro checks return value of the CUDA runtime call and exits the application if the call failed.

#define CUDA_CHECK_RETURN(value) {											\
	hipError_t _m_cudaStat = value;										\
	if (_m_cudaStat != hipSuccess) {										\
		fprintf(stderr, "Error %s at line %d in file %s\n",					\
				hipGetErrorString(_m_cudaStat), __LINE__, __FILE__);		\
		exit(1);															\
	} }


// For trimming adaptor sequences store adaptor and length as well as quality cutoffs in device constant memory

__constant__ __device__ char ADAPTOR[MAX_ADAPTOR_LENGTH];     // adaptor sequence can contain N for any match
__constant__ __device__ short ADAPTOR_LEN;                    // length of adaptor sequence in bases
__constant__ __device__ short MAX_MM=2;                       // maximum mismatches allowed not including Ns
__constant__ __device__ short QUAL_PADDING=33;				  // hold PHRED base for qualities
__constant__ __device__ short MIN_QUAL=20;					  // hold minimal quality that is considered good base
__constant__ __device__ short MIN_AVERAGE_QUAL_AFTER_BAD=25;  // minimum quality average of remaining read after bad base

void SetAdaptorSequence(const char *AdaptorSequence, const short mismatches, const short PHRED, const short MIN_BASE_QUAL, const short MIN_QUAL_AFTER_BAD)
{																// define the adaptor, mismatches and quality parameters before trimming
	short AdLen = strnlen(AdaptorSequence, MAX_ADAPTOR_LENGTH); // get length of adaptor sequence

	for(int dev=0; dev < numGPUs; dev++)
	{
		hipSetDevice(device[dev]);
		if(verbose) printf("[%d] Setting Adaptor sequence %s, length %d on GPU \n", dev, AdaptorSequence, AdLen);
		CUDA_CHECK_RETURN(hipMemcpyToSymbol(HIP_SYMBOL(ADAPTOR), AdaptorSequence, AdLen));           // copy to device
		CUDA_CHECK_RETURN(hipMemcpyToSymbol(HIP_SYMBOL(ADAPTOR_LEN), &AdLen, sizeof(short)));        // constant memory
		if(verbose) printf("[%d] Setting mismatches %d, PHRED+%d on GPU \n", dev, mismatches, PHRED);
		CUDA_CHECK_RETURN(hipMemcpyToSymbol(HIP_SYMBOL(MAX_MM), &mismatches, sizeof(short)));
		CUDA_CHECK_RETURN(hipMemcpyToSymbol(HIP_SYMBOL(QUAL_PADDING), &PHRED, sizeof(short)));
		if(verbose) printf("[%d] Setting minimum base quality %d, average read quality after bad %d on GPU \n", dev, MIN_BASE_QUAL, MIN_QUAL_AFTER_BAD);
		CUDA_CHECK_RETURN(hipMemcpyToSymbol(HIP_SYMBOL(MIN_QUAL), &MIN_BASE_QUAL, sizeof(short)));
		CUDA_CHECK_RETURN(hipMemcpyToSymbol(HIP_SYMBOL(MIN_AVERAGE_QUAL_AFTER_BAD), &MIN_QUAL_AFTER_BAD, sizeof(short)));
	}
}


__global__ void Find_gRNA(char *dDataArray, short *read_length, int reads, short MAX_READ_LENGTH)
{
  for(long idx = blockIdx.x * blockDim.x + threadIdx.x; idx < reads; idx += blockDim.x * gridDim.x)
  {
      if (idx < reads)
      {
          char *sequence = &dDataArray[idx*MAX_READ_LENGTH];
          short rl=read_length[idx];
          short n;
          short p=0;
          short mm=0;
          read_length[idx]=0;
          while (p <= rl-ADAPTOR_LEN)
          {
              mm=0;
              for (n=0; n<ADAPTOR_LEN; n++)
              {
                  if (ADAPTOR[n]!='N' && sequence[p+n]!=ADAPTOR[n])
                  {
                     mm++;
                     if (mm > MAX_MM) break;
                  }
              }
              if (mm <= MAX_MM)
              {
                  read_length[idx]=p;
                  break;
              }
              p++;
          }
          if (mm <= MAX_MM ) continue;
          p=rl-ADAPTOR_LEN+1;
          if (rl >= ADAPTOR_LEN-1)
          {
              mm=0;
              for (n=0; n<ADAPTOR_LEN-1; n++)
              {
                  if (ADAPTOR[n]!='N' && sequence[p+n]!=ADAPTOR[n])
                  {
                     mm++;
                     if (mm >= MAX_MM) break;
                  }
              }
              if (mm < MAX_MM)
              {
                  read_length[idx]=p;
                  continue;
              }
          }
          p++;
          if (rl >= ADAPTOR_LEN-2)
          {
              mm=0;
              for (n=0; n<ADAPTOR_LEN-2; n++)
              {
                  if (ADAPTOR[n]!='N' && sequence[p+n]!=ADAPTOR[n])
                  {
                     mm++;
                     break;
                  }
              }
              if (MAX_MM > (mm+1))
              {
                  read_length[idx]=p;
              }
          }
      }
  }
}

__global__ void TrimmAdaptors(char *dDataArray, short *read_length, int reads, short MAX_READ_LENGTH)
{
  for(long idx = blockIdx.x * blockDim.x + threadIdx.x; idx < reads; idx += blockDim.x * gridDim.x)
  {
      if (idx < reads)
      {
          char *sequence = &dDataArray[idx*MAX_READ_LENGTH];
          short rl=read_length[idx];
          short n;
          short p=0;
          short mm=0;
          while (p <= rl-ADAPTOR_LEN)
          {
              mm=0;
              for (n=0; n<ADAPTOR_LEN; n++)
              {
                  if (ADAPTOR[n]!='N' && sequence[p+n]!=ADAPTOR[n])
                  {
                     mm++;
                     if (mm > MAX_MM) break;
                  }
              }
              if (mm <= MAX_MM)
              {
                  read_length[idx]=p;
                  break;
              }
              p++;
          }
          if (mm <= MAX_MM ) continue;
          p=rl-ADAPTOR_LEN+1;
          if (rl >= ADAPTOR_LEN-1)
          {
              mm=0;
              for (n=0; n<ADAPTOR_LEN-1; n++)
              {
                  if (ADAPTOR[n]!='N' && sequence[p+n]!=ADAPTOR[n])
                  {
                     mm++;
                     if (mm >= MAX_MM) break;
                  }
              }
              if (mm < MAX_MM)
              {
                  read_length[idx]=p;
                  continue;
              }
          }
          p++;
          if (rl >= ADAPTOR_LEN-2)
          {
              mm=0;
              for (n=0; n<ADAPTOR_LEN-2; n++)
              {
                  if (ADAPTOR[n]!='N' && sequence[p+n]!=ADAPTOR[n])
                  {
                     mm++;
                     break;
                  }
              }
              if (MAX_MM > (mm+1))
              {
                  read_length[idx]=p;
              }
          }
      }
  }
}

__global__ void TrimmQuals(char *quals, short *read_length, int reads, short MAX_READ_LENGTH)
{
  for(long idx = blockIdx.x * blockDim.x + threadIdx.x; idx < reads; idx += blockDim.x * gridDim.x)
  {
      if (idx < reads)
      {
          char *q = &quals[idx*MAX_READ_LENGTH];
          short rl=read_length[idx];
          short i;
          for(i=0; i<rl; i++)
          {
              if ((q[i]-QUAL_PADDING)<=MIN_QUAL)
              {
                 short s=0;
                 short r=i+1;
                 while (r<rl)
                 {
                    s=s+q[r]-QUAL_PADDING;
                    r++;
                 }
                 if(s<(MIN_AVERAGE_QUAL_AFTER_BAD*(rl-i+1)))
                 {
                    read_length[idx]=i;
                    break;
                 }
              }
          }

      }
  }
}


void InitGPUs(void)
{
	if(verbose) printf("\n");
	for (int dev=0; dev<numGPUs; dev++)                         // initialize devices and allocate cuda resources
    {
    	if(verbose) printf("[%d] Initializing GPU\n", dev);
    	CUDA_CHECK_RETURN(hipSetDevice(device[dev]));
    	CUDA_CHECK_RETURN(hipMalloc((void **)&dSequenceArray[dev], MAX_READS_ON_GPU * MAX_READ_LENGTH * sizeof(char)));    // one data array
    	CUDA_CHECK_RETURN(hipMalloc((void **)&dQualArray[dev], MAX_READS_ON_GPU * MAX_READ_LENGTH * sizeof(char)));    // one data array
    	CUDA_CHECK_RETURN(hipMalloc((void **)&dIntArray[dev][0], MAX_READS_ON_GPU * sizeof(short)));  // two dIntArrays
    	CUDA_CHECK_RETURN(hipMalloc((void **)&dIntArray[dev][1], MAX_READS_ON_GPU * sizeof(short)));

    	CUDA_CHECK_RETURN(hipStreamCreate(&upload_stream[dev]));                                   // create streams on devices
    	CUDA_CHECK_RETURN(hipStreamCreate(&compute_stream[dev]));
    	CUDA_CHECK_RETURN(hipStreamCreate(&download_stream[dev]));

    	CUDA_CHECK_RETURN(hipEventCreateWithFlags(&QUAL_COPY_DONE[dev], hipEventDisableTiming || hipEventBlockingSync));  // events for device host synchronization
    	CUDA_CHECK_RETURN(hipEventCreateWithFlags(&SEQ_COPY_DONE[dev], hipEventDisableTiming));
    	CUDA_CHECK_RETURN(hipEventCreateWithFlags(&TrimmQ_DONE[dev], hipEventDisableTiming));
    	CUDA_CHECK_RETURN(hipEventCreateWithFlags(&TrimmA_DONE[dev], hipEventDisableTiming));
    	CUDA_CHECK_RETURN(hipEventCreateWithFlags(&DTH_COPY_DONE[dev], hipEventDisableTiming || hipEventBlockingSync));

        if(verbose) printf("[%d] Allocating pinned CPU memory for reads\n", dev);
        CUDA_CHECK_RETURN(hipHostMalloc((void **) &hReadLen[dev][0], MAX_READS_ON_GPU * sizeof(short), hipHostMallocDefault));   // allocate two buffers for reads length
        CUDA_CHECK_RETURN(hipHostMalloc((void **) &hReadLen[dev][1], MAX_READS_ON_GPU * sizeof(short), hipHostMallocDefault));

        CUDA_CHECK_RETURN(hipHostMalloc((void **) &hReadSequence[dev][0], MAX_READS_ON_GPU * MAX_READ_LENGTH * sizeof(char), hipHostMallocDefault));   // two buffers for reads sequence
        CUDA_CHECK_RETURN(hipHostMalloc((void **) &hReadSequence[dev][1], MAX_READS_ON_GPU * MAX_READ_LENGTH * sizeof(char), hipHostMallocDefault));

        CUDA_CHECK_RETURN(hipHostMalloc((void **) &hReadQualstr[dev], MAX_READS_ON_GPU * MAX_READ_LENGTH * sizeof(char), hipHostMallocDefault)); // one buffer for qualities

    }
}

void FreeGPUs(void)
{
    for (int dev=0; dev<numGPUs; dev++)                         // release cuda resources from all devices
    {
    	CUDA_CHECK_RETURN(hipSetDevice(device[dev]));

    	CUDA_CHECK_RETURN(hipEventDestroy(QUAL_COPY_DONE[dev]));
    	CUDA_CHECK_RETURN(hipEventDestroy(SEQ_COPY_DONE[dev]));
    	CUDA_CHECK_RETURN(hipEventDestroy(TrimmQ_DONE[dev]));
    	CUDA_CHECK_RETURN(hipEventDestroy(TrimmA_DONE[dev]));
    	CUDA_CHECK_RETURN(hipEventDestroy(DTH_COPY_DONE[dev]));
    	CUDA_CHECK_RETURN(hipStreamDestroy(upload_stream[dev]));
    	CUDA_CHECK_RETURN(hipStreamDestroy(compute_stream[dev]));
    	CUDA_CHECK_RETURN(hipStreamDestroy(download_stream[dev]));

    	CUDA_CHECK_RETURN(hipFree(dIntArray[dev][0]));
    	CUDA_CHECK_RETURN(hipFree(dIntArray[dev][1]));
    	CUDA_CHECK_RETURN(hipFree(dSequenceArray[dev]));
    	CUDA_CHECK_RETURN(hipFree(dQualArray[dev]));

        hipHostFree(hReadLen[dev][0]);                        // free all page locked host memory
        hipHostFree(hReadLen[dev][1]);
        hipHostFree(hReadSequence[dev][0]);
        hipHostFree(hReadSequence[dev][1]);
        hipHostFree(hReadQualstr[dev]);
    }

}

int FindGPUs(void)
{
    int deviceCount;
    numGPUs = 0;
    CUDA_CHECK_RETURN(hipGetDeviceCount(&deviceCount)); // search cuda devices and identify compute 3.5 with 6 GB
    if (deviceCount == 0) return(0);

    for (int dev=0; dev<deviceCount; dev++)
    {
    	hipSetDevice(dev);
    	hipDeviceProp_t deviceProp;
    	hipGetDeviceProperties(&deviceProp, dev);

    	int driverVersion, runtimeVersion;
    	hipDriverGetVersion(&driverVersion);
    	hipRuntimeGetVersion(&runtimeVersion);

        if(((deviceProp.major == 3 && deviceProp.minor >= 5) || (deviceProp.major > 3)) && deviceProp.totalGlobalMem > 6144000000)
        {
            if(verbose)
            {
            	printf("\nDevice %d: %s\n", dev, deviceProp.name);
        	    printf("  CUDA Driver / Runtime Version:     %d.%d / %d.%d\n", driverVersion/1000, (driverVersion%100)/10, runtimeVersion/1000, (runtimeVersion%100)/10);
        	    printf("  CUDA Compute Capability:           %d.%d\n", deviceProp.major, deviceProp.minor);
                    printf("  PCI bus ID:                        %d:%d\n", deviceProp.pciBusID, deviceProp.pciDeviceID);
        	    printf("  Total amount of global memory:     %.0f MBytes (%llu bytes)\n", (float)deviceProp.totalGlobalMem/1048576.0f, (unsigned long long) deviceProp.totalGlobalMem);
        	    printf("  Number of Multiprocessors:         %d\n", deviceProp.multiProcessorCount);
            }
        	device[numGPUs] = dev;
        	numGPUs++;
        	if (numGPUs >= MAX_GPU_NUM) break;
        }
    }
    return(numGPUs);
}

void OpenFiles()
{
    // handle compression using zlib gzFile functions for input and pipe gzip for output

    if(!overwrite_outputfile)       // test if output file exists if option -f is not specified
    {
        outputFile = fopen(output_filename, "r");
    	if(outputFile!=NULL)
    	{
    		printf("ERROR output file exists already. To overwrite run with option -f\n");
    		exit(255);
    	}  // do not attempt close file as we would have already exited if opening was successful !
    }
	inputFile = gzopen(input_filename, "r");
    if(inputFile == NULL)
    {
    	printf("ERROR opening input file: %s\n", input_filename);
    	exit(255);
    }
	templateFile = gzopen(input_filename, "r");  // holds a second access to input read file for rereading positions for output
    if(templateFile == NULL)
    {
    	printf("ERROR opening second handle to input file.\n");
    	exit(255);
    }
    if(write_pigz_output)
    {
    	outputFile = popen(strcat(PIGZ_PIPE, output_filename), "w");
        if(outputFile == NULL)
        {
        	printf("Option -pigz: could not open pipe ... falling back on libz.\n\tMake sure pigz is installed with: sudo apt-get install pigz\n");
        	write_gz_output = true;
        	write_pigz_output = false;
        }
    }
	if(write_gz_output && !write_pigz_output)
	{
		outputFile = popen(strcat(GZIP_PIPE, output_filename), "w");
        if(outputFile == NULL)
        {
        	printf("Option -gz: could not open pipe ... falling back to uncompressed output.\n");
        	write_gz_output = false;
        }
	}
	if(!write_gz_output && !write_pigz_output) outputFile = fopen(output_filename, "w");
    if(outputFile == NULL)
    {
    	printf("ERROR opening output file: %s\n", output_filename);
    	exit(255);
    }
}

int ReadBlockOfReads(int max_num_to_read, short *hReadLen, char* hReadSequence, char *hReadQualstr)
{
	int n = 0;                                                                    // returns the number of reads read
	short length;

    while(gzgets(inputFile, Read.name, MAX_FASTQ_BUF_LINE) != NULL)
    {
    	if(Read.name[0] == 13) break;				// end if CR <13> or LF <10> are encountered
    	if(Read.name[0] == 10) break;
    	if(gzgets(inputFile, Read.sequence, MAX_FASTQ_BUF_LINE)==NULL)
        {
            printf("ERROR parsing input!\n");
            exit(255);
        }
        if(gzgets(inputFile, Read.descr, MAX_FASTQ_BUF_LINE)==NULL)
        {
            printf("ERROR parsing input!\n");
            exit(255);
        }
        if(gzgets(inputFile, Read.qualstr, MAX_FASTQ_BUF_LINE)==NULL)
        {
            printf("ERROR parsing input!\n");
            exit(255);
        }

        if(!FastQ_WARNING)                         // write warning if FastQ file contains non-standard lines
        {
            if(Read.name[0]!='@' || Read.descr[0]!='+')
            {
            	printf("Warning: Encountered unusual line identifiers in FastQ file format.\n");
            	FastQ_WARNING = true;
            }
        }
        length = strlen(Read.sequence)-1;
        if(length > MAX_READ_LENGTH) length = MAX_READ_LENGTH;

//        printf("%d, ", length);

        memcpy(&hReadSequence[n*MAX_READ_LENGTH], Read.sequence, length);
        memcpy(&hReadQualstr[n*MAX_READ_LENGTH], Read.qualstr, length);
        hReadLen[n] = length;

        n++;
        if(n == max_num_to_read) break;

    }
    hNumberOfReads = hNumberOfReads + n;                           // update global variable to total number of reads
    return(n);
}

int WriteBlockOfReads(int num_of_reads_to_write, const short *hReadLen, short min_out_read_length)
{
    int n=0;
    int w=0;
    short length;
    char str_buffer[MAX_FASTQ_BUF_LINE];

    if(num_of_reads_to_write == 0) return(0);
    if(verbose) printf("I/O > num_of_reads_to_write = %d\n", num_of_reads_to_write);
    while(gzgets(templateFile, Read.name, MAX_FASTQ_BUF_LINE) != NULL)
    {
        if(gzgets(templateFile, Read.sequence, MAX_FASTQ_BUF_LINE)==NULL)
        {
            printf("ERROR parsing input file for writing trimmed output!\n");
            exit(255);
        }
        if(gzgets(templateFile, Read.descr, MAX_FASTQ_BUF_LINE)==NULL)
        {
            printf("ERROR parsing input file for writing trimmed output!\n");
            exit(255);
        }
        if(gzgets(templateFile, Read.qualstr, MAX_FASTQ_BUF_LINE)==NULL)
        {
            printf("ERROR parsing input file for writing trimmed output!\n");
            exit(255);
        }

        length = hReadLen[n];

        if(gRNATrimming)                         // isolate the gRNA from adaptor match
        {
        	if(length>0)
        	{
        		strncpy(str_buffer, &Read.sequence[length+gRNA_start], gRNA_length);
        		strncpy(&Read.sequence[0], str_buffer, gRNA_length);
        		Read.sequence[gRNA_length]=10;
        		Read.sequence[gRNA_length+1]=0;
        		strncpy(str_buffer, &Read.qualstr[length+gRNA_start], gRNA_length);
        		strncpy(&Read.qualstr[0], str_buffer, gRNA_length);
        		Read.qualstr[gRNA_length]=10;
        		Read.qualstr[gRNA_length+1]=0;

                fprintf(outputFile,"%s", Read.name);
                fprintf(outputFile,"%s", Read.sequence);
                fprintf(outputFile,"%s", Read.descr);
                fprintf(outputFile,"%s", Read.qualstr);

                w++;
        	}
        }
        else                                     // normal quality and adaptor trimming
        {
            if(length >= min_out_read_length)
            {
                Read.sequence[length]=10;        // write only reads that are longer than minimum to output file
                Read.sequence[length+1]=0;
                Read.qualstr[length]=10;
                Read.qualstr[length+1]=0;

                fprintf(outputFile,"%s", Read.name);
                fprintf(outputFile,"%s", Read.sequence);
                fprintf(outputFile,"%s", Read.descr);
                fprintf(outputFile,"%s", Read.qualstr);

                w++;
             }
        }

        n++;
        if(n == num_of_reads_to_write) break;
    }
    hReadsWritten = hReadsWritten + w;
    return(n);
}

void CloseFiles(void)
{
    gzclose(inputFile);
    gzclose(templateFile);
    if(write_gz_output || write_pigz_output) pclose(outputFile); else fclose(outputFile);
}

bool Detect_FastQ_Format_PHRED(void)
{
	int n = 0;                                                                    // returns the number of reads read
	short length;
	uint min_qual = 65;
	uint max_qual = 65;
	bool deciphered = false;

	inputFile = gzopen(input_filename, "r");
    if(inputFile == NULL)
    {
    	printf("ERROR opening input file %s\n", input_filename);
    	exit(255);
    }

    while(gzgets(inputFile, Read.name, MAX_FASTQ_BUF_LINE) != NULL)
    {
    	if(Read.name[0] == 13) break;				// end if CR <13> or LF <10> are encountered
    	if(Read.name[0] == 10) break;
    	if(gzgets(inputFile, Read.sequence, MAX_FASTQ_BUF_LINE)==NULL)
        {
            printf("ERROR parsing input!\n");
            exit(255);
        }
        if(gzgets(inputFile, Read.descr, MAX_FASTQ_BUF_LINE)==NULL)
        {
            printf("ERROR parsing input!\n");
            exit(255);
        }
        if(gzgets(inputFile, Read.qualstr, MAX_FASTQ_BUF_LINE)==NULL)
        {
            printf("ERROR parsing input!\n");
            exit(255);
        }

        if(!FastQ_WARNING)                         // write warning if FastQ file contains non-standard lines
        {
            if(Read.name[0]!='@' || Read.descr[0]!='+')
            {
            	printf("Warning: Encountered unusual line identifiers in FastQ file format.");
            	FastQ_WARNING = true;
            }
        }
        length = strlen(Read.sequence)-1;

        for(n=0; n<length;n++)
        {
        	if(min_qual > (uint)Read.qualstr[n])
        	{
        		min_qual = (uint) Read.qualstr[n];
        	}
        	else
        	{
            	if(max_qual < (uint)Read.qualstr[n]) max_qual = (uint) Read.qualstr[n];

        	}
        }
        if(min_qual < 59)
        {
        	PHRED = 33;                                    // FastQ Sanger and Illumina 1.8+ format
        	deciphered = true;
        	break;
        }
        if(max_qual > 80)
        {
        	PHRED = 64;                                    // FastQ Illumina 1.3+ format
        	deciphered = true;
        	break;
        }
    }

    gzclose(inputFile);
    return(deciphered);
}

int PreprocessReadsOnGPU(void)
{
	bool DONE = false;
	bool ALL_DONE = false;

	int ReadsProcessed = 0;
    int ReadsToProcess[MAX_GPU_NUM];
    int ReadsSentToGPU[MAX_GPU_NUM];
    int dev_side = 0;                             // left or right side of device memories [0] or [1]
    int dev_next_side = 1;
    int side_flip;

    if(verbose) printf("\nPreprocessing reads on GPU\n");


    for(int dev=0; dev<numGPUs; dev++)                         // copy data and run kernels initial round to fill CUDA queue and not waste time !
    {
    	ReadsToProcess[dev] = 0;
    	ReadsSentToGPU[dev] = 0;
    	if(!DONE)
        {
        	ReadsToProcess[dev] = ReadBlockOfReads(MAX_READS_ON_GPU, hReadLen[dev][dev_side], hReadSequence[dev][dev_side], hReadQualstr[dev]);

            if(ReadsToProcess[dev] < MAX_READS_ON_GPU)
            {
            	DONE = true;
            }
            if(ReadsToProcess[dev] == 0) continue;

    	    CUDA_CHECK_RETURN(hipSetDevice(device[dev]));

    	    if(QualityTrimming) CUDA_CHECK_RETURN(hipMemcpyAsync(dQualArray[dev], hReadQualstr[dev], ReadsToProcess[dev] * MAX_READ_LENGTH * sizeof(char), hipMemcpyHostToDevice, upload_stream[dev]));
    	    CUDA_CHECK_RETURN(hipMemcpyAsync(dIntArray[dev][dev_side], hReadLen[dev][dev_side], ReadsToProcess[dev] * sizeof(short), hipMemcpyHostToDevice, upload_stream[dev]));
    	    CUDA_CHECK_RETURN(hipEventRecord(QUAL_COPY_DONE[dev], upload_stream[dev]));

    	    CUDA_CHECK_RETURN(hipStreamWaitEvent(compute_stream[dev], QUAL_COPY_DONE[dev], 0));
    	    if(QualityTrimming)
    	    {
    	    	if(verbose) printf("[%d] TrimmQuals\n", device[dev]);
    	    	TrimmQuals<<<4096, 256, 0, compute_stream[dev]>>>(dQualArray[dev], dIntArray[dev][dev_side], ReadsToProcess[dev], MAX_READ_LENGTH);
    	    	CUDA_CHECK_RETURN(hipGetLastError());
    	    }
    	    CUDA_CHECK_RETURN(hipEventRecord(TrimmQ_DONE[dev], compute_stream[dev]));

    	    if(AdaptorTrimming || gRNATrimming) CUDA_CHECK_RETURN(hipMemcpyAsync(dSequenceArray[dev], hReadSequence[dev][dev_side], ReadsToProcess[dev] * MAX_READ_LENGTH * sizeof(char), hipMemcpyHostToDevice, upload_stream[dev]));
    	    CUDA_CHECK_RETURN(hipEventRecord(SEQ_COPY_DONE[dev], upload_stream[dev]));

    	    CUDA_CHECK_RETURN(hipStreamWaitEvent(compute_stream[dev], SEQ_COPY_DONE[dev], 0));
    	    if(gRNATrimming)
    	    {
    	    	if(verbose) printf("[%d] Find_gRNA\n", device[dev]);
    	        Find_gRNA<<<4096, 256, 0, compute_stream[dev]>>>(dSequenceArray[dev], dIntArray[dev][dev_side], ReadsToProcess[dev], MAX_READ_LENGTH);
    	        CUDA_CHECK_RETURN(hipGetLastError());
    	    }
    	    else
    	    {
    	    	if(AdaptorTrimming)
    	    	{
    	    		if(verbose) printf("[%d] TrimmAdaptors\n", device[dev]);
    	    		TrimmAdaptors<<<4096, 256, 0, compute_stream[dev]>>>(dSequenceArray[dev], dIntArray[dev][dev_side], ReadsToProcess[dev], MAX_READ_LENGTH);
    	    		CUDA_CHECK_RETURN(hipGetLastError());
    	    	}
    	    }
    	    CUDA_CHECK_RETURN(hipEventRecord(TrimmA_DONE[dev], compute_stream[dev]));

    	    CUDA_CHECK_RETURN(hipStreamWaitEvent(download_stream[dev], TrimmA_DONE[dev], 0));
    	    CUDA_CHECK_RETURN(hipMemcpyAsync(hReadLen[dev][dev_side], dIntArray[dev][dev_side], ReadsToProcess[dev] * sizeof(short), hipMemcpyDeviceToHost, download_stream[dev]));
    	    CUDA_CHECK_RETURN(hipEventRecord(DTH_COPY_DONE[dev], download_stream[dev]));
    	    if(verbose) printf("[%d] Memcpy DtoH %d reads\n", device[dev], ReadsToProcess[dev]);

    	    ReadsSentToGPU[dev] = ReadsToProcess[dev];
    	    ReadsToProcess[dev] = 0;
       }
    }

    while(!ALL_DONE)
    {
    	ALL_DONE = true;                                            // setup for test if should stop if there is no more data on the GPU

    	if(!DONE)
        {
            for(int dev=0; dev<numGPUs; dev++)                         // read a block of data, copy QUALS to GPU and run QUAL kernel
        	{
            	ReadsToProcess[dev] = 0;

        	    CUDA_CHECK_RETURN(hipSetDevice(device[dev]));

            	if(ReadsSentToGPU[dev]>0)
            	{
            		CUDA_CHECK_RETURN(hipEventSynchronize(TrimmQ_DONE[dev]));
            	}

            	ReadsToProcess[dev] = ReadBlockOfReads(MAX_READS_ON_GPU, hReadLen[dev][dev_next_side], hReadSequence[dev][dev_next_side], hReadQualstr[dev]);
                if(ReadsToProcess[dev] < MAX_READS_ON_GPU)
                {
                	DONE = true;
                }
                if(ReadsToProcess[dev] == 0) break;

                ALL_DONE = false;                                      // there is more work on the GPUs that requires further processing

                if(QualityTrimming) CUDA_CHECK_RETURN(hipMemcpyAsync(dQualArray[dev], hReadQualstr[dev], ReadsToProcess[dev] * MAX_READ_LENGTH * sizeof(char), hipMemcpyHostToDevice, upload_stream[dev]));
        	    CUDA_CHECK_RETURN(hipMemcpyAsync(dIntArray[dev][dev_next_side], hReadLen[dev][dev_next_side], ReadsToProcess[dev] * sizeof(short), hipMemcpyHostToDevice, upload_stream[dev]));
        	    CUDA_CHECK_RETURN(hipEventRecord(QUAL_COPY_DONE[dev], upload_stream[dev]));

        	    CUDA_CHECK_RETURN(hipStreamWaitEvent(compute_stream[dev], QUAL_COPY_DONE[dev], 0));
        	    if(QualityTrimming)
        	    {
        	    	if(verbose) printf("[%d] TrimmQuals\n", device[dev]);
        	    	TrimmQuals<<<4096, 256, 0, compute_stream[dev]>>>(dQualArray[dev], dIntArray[dev][dev_next_side], ReadsToProcess[dev], MAX_READ_LENGTH);
        	    	CUDA_CHECK_RETURN(hipGetLastError());
        	    }
        	}
        }

        for(int dev=0; dev<numGPUs; dev++)                         // copy sequence and run Adaptor trim kernel
    	{
        	if(ReadsToProcess[dev]>0)
        	{
        	    CUDA_CHECK_RETURN(hipSetDevice(device[dev]));

        	    if(ReadsSentToGPU[dev]>0)
        	    {
            	    CUDA_CHECK_RETURN(hipEventSynchronize(TrimmA_DONE[dev]));
        	    }

        	    if(AdaptorTrimming || gRNATrimming) CUDA_CHECK_RETURN(hipMemcpyAsync(dSequenceArray[dev], hReadSequence[dev][dev_next_side], ReadsToProcess[dev] * MAX_READ_LENGTH * sizeof(char), hipMemcpyHostToDevice, upload_stream[dev]));
        	    CUDA_CHECK_RETURN(hipEventRecord(SEQ_COPY_DONE[dev], upload_stream[dev]));

        	    CUDA_CHECK_RETURN(hipStreamWaitEvent(compute_stream[dev], SEQ_COPY_DONE[dev], 0));
        	    if(gRNATrimming)
        	    {
        	    	if(verbose) printf("[%d] Find_gRNA\n", device[dev]);
        	    	Find_gRNA<<<4096, 256, 0, compute_stream[dev]>>>(dSequenceArray[dev], dIntArray[dev][dev_next_side], ReadsToProcess[dev], MAX_READ_LENGTH);
        	    	CUDA_CHECK_RETURN(hipGetLastError());
        	    }
        	    else
        	    {
        	    	if(AdaptorTrimming)
        	    	{
        	    		if(verbose) printf("[%d] TrimmAdaptors\n", device[dev]);
        	    		TrimmAdaptors<<<4096, 256, 0, compute_stream[dev]>>>(dSequenceArray[dev], dIntArray[dev][dev_next_side], ReadsToProcess[dev], MAX_READ_LENGTH);
        	    		CUDA_CHECK_RETURN(hipGetLastError());
        	    	}
        	    }
        	    CUDA_CHECK_RETURN(hipEventRecord(TrimmA_DONE[dev], compute_stream[dev]));
        	}
    	}

        for(int dev=0; dev<numGPUs; dev++)                          // copy data from devices and write output file
    	{
            if(verbose) printf("[%d] > ReadsSentToGPU = %d\n", dev, ReadsSentToGPU[dev]);

        	if(ReadsSentToGPU[dev]>0)
        	{
        	    CUDA_CHECK_RETURN(hipSetDevice(device[dev]));
        		CUDA_CHECK_RETURN(hipEventSynchronize(DTH_COPY_DONE[dev]));
        		if(verbose) printf("[%d] Writing hReadLen[%d][%d]\n", device[dev], dev, dev_side);
        	    WriteBlockOfReads(ReadsSentToGPU[dev], hReadLen[dev][dev_side], MIN_OUT_READ_LEN);    // write output block
        	    ReadsProcessed += ReadsSentToGPU[dev];             // count how many reads were considered for writing - actual output has minimal length requirement
        	}

        	if(ReadsToProcess[dev]>0)
        	{
        	    CUDA_CHECK_RETURN(hipStreamWaitEvent(download_stream[dev], TrimmA_DONE[dev], 0));
        	    CUDA_CHECK_RETURN(hipMemcpyAsync(hReadLen[dev][dev_next_side], dIntArray[dev][dev_next_side], ReadsToProcess[dev] * sizeof(short), hipMemcpyDeviceToHost, download_stream[dev]));
        	    CUDA_CHECK_RETURN(hipEventRecord(DTH_COPY_DONE[dev], download_stream[dev]));
        	    if(verbose) printf("[%d] Memcpy DtoH %d reads\n", device[dev], ReadsToProcess[dev]);
        	}
    	    ReadsSentToGPU[dev] = ReadsToProcess[dev];
    	    ReadsToProcess[dev] = 0;
    	}
        side_flip = dev_side;                                      // dev_side alternate between 0 and 1 to use memory efficiently
        dev_side = dev_next_side;
        dev_next_side = side_flip;
    }
    return(ReadsProcessed);
}

void usage_help(void)
{
	printf("\nPreprocessReads multi-GPU version\n");
	printf("\tsupports up to 4 NVIDIA GPUs with compute capability greater than 3.5 and at least 6 GB memory.\n");
	printf("\tcompiled for minimum CUDA API 6.5 (build 20210107).\n");
	printf("\nProgram Options:\n\n");
	printf("\t-i, -I ....... specify the path for the input file [required]\n");
	printf("\t-o, -O ....... specify the path for the output file [required]\n");
	printf("\t-len, -Len ... specify the minimum length for reads written to the output file\n");
	printf("\t-f ........... over write output file if it exists\n");
	printf("\t-gz .......... write output to file in compressed format (.gz)\n");
	printf("\t-pigz ........ write output to file in compressed format (.gz) using multithreaded compression\n");
	printf("\t-v, -V ....... verbose, prints details on processing to screen\n");
	printf("\t-a, -A ....... adaptor sequence, can contain Ns that will match any base in the read\n");
	printf("\t-mm, -MM ..... number of mismatches allowed in adaptor search (not including Ns)\n");
	printf("\t-Phred ....... sets the base of the qualities PHRED values [default 33], use AUTO for autodetection\n");
	printf("\t-Qmin ........ sets the minimum acceptable quality score for a good base [default 20]\n");
	printf("\t-Qualab ...... sets the minimum average base quality score for remainder of the read after a bad base [default 25]\n");
	printf("\t-dev, -Dev ... specify CUDA device to use (can be used repeatedly for selecting multiple GPUs,\n");
	printf("\t               if not specified an automatic search for GPUs with compute capability 3.5 and 6 GB memory is performed)\n");
	printf("\nAlgorithm selection:\n\n");
	printf("\t/TA .......... select adaptor trimming only (can be also used before option /gRNA to avoid quality trimming)\n");
	printf("\t/TQ .......... select quality trimming only\n");
	printf("\t/TAQ ......... select quality and adaptor trimming [default]\n");
	printf("\t/gRNA ........ select gRNA recovery, followed by start relative to start of adaptor sequence and length of gRNA to be retrieved\n");
	printf("\t               ( /gRNA 12 20 will retrieve 20 nucleotide read sequence starting 12 positions after the 5' end match of adaptor)\n");
	printf("\nProgrammer options variables:\n");
	printf("\t-G ........... set MAX_READS_ON_GPU variable\n");
	printf("\t-R ........... set MAX_READ_LENGTH variable\n");
	printf("\nexample usage:\n");
	printf("\tPreprocessReads -dev 0 -dev 1 -i infile.fastq -o outfilename.fastq -len 26 -a ATTAGATCGATGCTA -mm 2\n\n");
	exit(3);
}

void invalid_command_line_option(const char *errorstr)
{
	printf("\nERROR %s\n", errorstr);
	printf("\nUsage ----------------------------------------------\n");
	usage_help();
}

void parseCommandLineArguments(int argc, char *argv[])
{
	bool inputfile_set = false;
	bool outputfile_set = false;
	bool adaptor_set = false;
	bool mismatch_set = false;
	bool outlen_set = false;
	for(int n=1; n<argc; n++)
	{
		if(argv[n][0] == '-')
		{
			char a = argv[n][1];
			switch (a)
			{
				case 'I':
				case 'i':
					if(inputfile_set) invalid_command_line_option("option -i: input file name already specified.");
					if(++n<argc)
					{
						if(strlen(argv[n])>400) invalid_command_line_option("option -i: input file path length exceeds limit.");
						strcpy(input_filename, argv[n]);
						inputfile_set=true;
						break;
					}
					else invalid_command_line_option("option -i: INPUT file name missing.");
					break;
				case 'O':
				case 'o':
					if(outputfile_set) invalid_command_line_option("option -o: output file name already specified.");
					if(++n<argc)
					{
						if(strlen(argv[n])>400) invalid_command_line_option("option -o: output file path length exceeds limit.");
						strcpy(output_filename, argv[n]);
						outputfile_set=true;
						break;
					}
					else invalid_command_line_option("option -o: OUTPUT file name missing.");
					break;
				case 'l':
				case 'L':
					if(argv[n][2]!='e' || argv[n][3]!='n') invalid_command_line_option("invalid command line option encountered.");
					if(outlen_set) invalid_command_line_option("option -len: minimum read length to include in output file is already specified.");
					if(++n<argc)
					{
						int ol=atoi(argv[n]);
						if(ol<0 || ol>MAX_READ_LENGTH) invalid_command_line_option("option -len: encountered invalid minimum read length to include in output file.");
						MIN_OUT_READ_LEN = (short) ol;
						outlen_set=true;
						break;
					}
					else invalid_command_line_option("option -len: expected minimum output read length not found.");
					break;

				case 'A':
				case 'a':
					if(adaptor_set) invalid_command_line_option("option -a: adaptor sequence already specified.");
					if(++n<argc)
					{
						if(strlen(argv[n])>MAX_ADAPTOR_LENGTH) invalid_command_line_option("option -a: adaptor sequence length exceeds limit.");
						if(strlen(argv[n])<3) invalid_command_line_option("option -a: adaptor sequence length too short.");
						strcpy(Adaptor, argv[n]);
						adaptor_set=true;
						break;
					}
					else invalid_command_line_option("option -a: expected adaptor sequence.");
					break;
				case 'M':
				case 'm':
					if(argv[n][2]!='m' && argv[n][2]!='M') invalid_command_line_option("invalid command line option encountered.");
					if(mismatch_set) invalid_command_line_option("option -mm: number of mismatches is already specified.");
					if(++n<argc)
					{
						int mm=atoi(argv[n]);
						if(mm>20) invalid_command_line_option("option -mm: number of mismatches exceeds limit.");
						mismatches = (short) mm;
						mismatch_set=true;
						break;
					}
					else invalid_command_line_option("option -mm: expected number of mismatches not found.");
					break;
				case 'd':
				case 'D':
					if(argv[n][2]!='e' || argv[n][3]!='v') invalid_command_line_option("invalid command line option encountered.");
					if(numGPUs>=MAX_GPU_NUM) invalid_command_line_option("option -dev: number of CUDA devices exceeds maximum.");
					if(++n<argc)
					{
						int d=atoi(argv[n]);
						if(d<0 || d>20) invalid_command_line_option("option -dev: invalid device number.");
						device[numGPUs] = d;
						numGPUs++;
						break;
					}
					else invalid_command_line_option("option -dev: expected CUDA device number not found.");
					break;
				case 'f':
					overwrite_outputfile = true;                                        // -f
					break;
				case 'g':                                                               // -gz
					if((argv[n][2]=='z') && (strlen(argv[n])==3))
					{
						write_gz_output = true;
						break;
					}
					else invalid_command_line_option("invalid command line option encountered.");
					break;
				case 'p':
				case 'P':
					if((strcmp(argv[n], "-Pigz")==0) || (strcmp(argv[n], "-pigz")==0))  // -pigz
					{
						write_pigz_output = true;
						break;
					}
					else                                                                // -phred
					{
						if(argv[n][2]!='h' || argv[n][3]!='r' || argv[n][4]!='e' || argv[n][5]!='d') invalid_command_line_option("invalid command line option encountered.");
						if(++n<argc)
						{
							if((strcmp(argv[n], "AUTO")==0) || (strcmp(argv[n], "auto")==0))
							{
								auto_phred_detect = true;
								break;
							}
							else
							{
								int d=atoi(argv[n]);
								if(d<0 || d>100) invalid_command_line_option("option -Phred: invalid phred base.");
								PHRED = d;
								break;
							}
						}
						else invalid_command_line_option("option -phred: expected number or AUTO not found.");
					}
					break;
				case 'Q':
				case 'q':
					if((strcmp(argv[n], "-Qmin")==0) || (strcmp(argv[n], "-qmin")==0))
					{
						if(++n<argc)
						{
							int qm=atoi(argv[n]);
							if(qm<10 || qm>64) invalid_command_line_option("option -qmin: outside 10 to 64 limit.");
							MIN_BASE_QUAL = (short) qm;
							break;
						}
						else invalid_command_line_option("option -qmin: expected number not found.");
					}
					else
					{
						if((strcmp(argv[n], "-Qualab")==0) || (strcmp(argv[n], "-qualab")==0))
						{
							if(++n<argc)
							{
								int qm=atoi(argv[n]);
								if(qm<10 || qm>64) invalid_command_line_option("option -qualab: outside 10 to 64 limit.");
								MIN_QUAL_AFTER_BAD = (short) qm;
								break;
							}
							else invalid_command_line_option("option -qmin: expected number not found.");
						}
					}
					break;
				case 'v':
				case 'V':
					verbose = true;
					break;
				case 'H':
				case 'h':
				case '?':
					printf("\nHELP ----------------------------------------------\n");
					usage_help();
					break;
				case 'G':                                                           // programmer option to set MAX_NUM_READS_ON_GPU parameter
					if(++n<argc)
					{
						int mrg=atoi(argv[n]);
						if(mrg<=0) invalid_command_line_option("invalid command line option encountered.");
						MAX_READS_ON_GPU = mrg;
						break;
					}
					else invalid_command_line_option("invalid command line option encountered.");
					break;
				case 'R':                                                           // programmer option to set MAX_READ_LENGTH parameter
					if(++n<argc)
					{
						int mrl=atoi(argv[n]);
						if(mrl<=0 || mrl>10000) invalid_command_line_option("invalid command line option encountered.");
						MAX_READ_LENGTH = (short) mrl;
						break;
					}
					else invalid_command_line_option("invalid command line option encountered.");
					break;

				default:
					invalid_command_line_option("invalid command line option encountered.");
			}
		}
		else
		{
			if(argv[n][0] == '/')
			{
				char a = argv[n][1];
				switch (a)
				{
					case 'T':
						AdaptorTrimming = false;
						QualityTrimming = false;
						gRNATrimming = false;
						if(strlen(argv[n]) == 3)
						{
							if(argv[n][2]=='A')
							{
								AdaptorTrimming = true;
								break;
							}
							else
							{
								if(argv[n][2]=='Q')
								{
									QualityTrimming = true;
									break;
								}
								else invalid_command_line_option("option /T: algorithm selection is invalid.");
							}
						}
						else
						{
							if(strlen(argv[n])==3 && argv[n][2]=='A' && argv[n][3]=='Q')
							{
								AdaptorTrimming = true;
								QualityTrimming = true;
								break;
							}
							else invalid_command_line_option("option /T: algorithm selection is invalid.");
						}
						break;
					case 'g':
						if(strlen(argv[n]) == 5 && argv[n][2]=='R' && argv[n][3]=='N' && argv[n][4]=='A')
						{
							gRNATrimming = true;
							if(++n < argc)
							{
								gRNA_start = atoi(argv[n]);
							}
							else invalid_command_line_option("option /gRNA: expected start position relative to adaptor 5' not found.");
							if(++n < argc)
							{
								gRNA_length = atoi(argv[n]);
							}
							else invalid_command_line_option("option /gRNA: expected gRNA length not found.");
							break;
						}
						else invalid_command_line_option("option /g: algorithm selection is invalid.");
						break;
				}
			}
			else invalid_command_line_option("parsing command line options.");
		}
	}
	if(!inputfile_set || !outputfile_set || ((AdaptorTrimming || gRNATrimming) && !adaptor_set)) invalid_command_line_option("missing required command line options.");
	if(strcmp(input_filename, output_filename)==0)
	{
		printf("ERROR: encountered identical input and output file paths!\n");         // input file cannot be identical to output file
		exit(253);
	}
	printf("Setting parameters:\n");
	printf("\tInput file name  : %s\n", input_filename);
	printf("\tOutput file name : %s\n", output_filename);
	if(AdaptorTrimming || gRNATrimming) printf("\tAdaptor sequence : %s\n", Adaptor);
	if(verbose)
	{
		if(AdaptorTrimming || gRNATrimming) printf("\tMismatches = %d\n", mismatches);
		printf("\tTrimming: ");
		if(QualityTrimming) printf("Quality ");
		if(AdaptorTrimming) printf("Adaptors ");
		if(gRNATrimming) printf("Find gRNA");
		printf("\n");
		if(QualityTrimming)
		{
			printf("\tMinimum accepted base quality = %d; average quality of read after bad base = %d\n", MIN_BASE_QUAL, MIN_QUAL_AFTER_BAD);
		}
		printf("\tFastQ Quality Encoding: ");
		if(!auto_phred_detect) printf("PHRED+%d\n", PHRED); else printf("<AUTO DETECTION>\n");
		printf("\tMAX_READ_LENGTH  : %d\n", MAX_READ_LENGTH);
		printf("\tMinimum read length for output = %d\n", MIN_OUT_READ_LEN);
		if(overwrite_outputfile) printf("\tForce overwrite output file if it exists.\n");
	}
	if(numGPUs>0)
	{
		printf("\nUsing CUDA devices: ");
		for(int n=0; n<numGPUs; n++) printf("[%d]", device[n]);
		printf("\n");
	}
}

int main(int argc, char *argv[])
{
	time_t start_t = time(NULL);                        // for timing the process
	time_t end_t;
    int reads_processed = 0;

    parseCommandLineArguments(argc, argv);                        // get parameters from the command line
    if(numGPUs == 0)
    {
        if(FindGPUs() == 0)                             // check for GPUs
        {
            printf("\nERROR: No suitable CUDA devices found ... exiting\n");
            exit(1);
        }
        else
        {
            if(numGPUs == 1)
            	printf("\nOne CUDA device with at least compute capability 3.5 and 6 GB memory found.\n");
            else
                printf("\n%d CUDA devices with at least compute capability 3.5 and 6 GB memory found.\n", numGPUs);
        }
    }

    if(auto_phred_detect)
    {
    	if(Detect_FastQ_Format_PHRED())
    	{
    		if(verbose) printf("<AUTO DETECTION> FastQ Quality Encoding: PHRED+%d\n", PHRED);
    	}
    	else
    	{
    		printf("\nERROR: Unable to detect FastQ format version.\n");
    		exit(32);
    	}
    }

    OpenFiles();                                    // access files
    InitGPUs();
    SetAdaptorSequence(Adaptor, mismatches, PHRED, MIN_BASE_QUAL, MIN_QUAL_AFTER_BAD);

    reads_processed = PreprocessReadsOnGPU();

    printf("\nReads processed: %d\n", reads_processed);
    printf("Reads in input file %s : %d\n",input_filename, hNumberOfReads);
    printf("Reads written to output file %s : %d\n", output_filename, hReadsWritten);
    if(FastQ_WARNING) printf("Encountered potential issues with the FastQ file format in %s\n", input_filename);

    CloseFiles();
    FreeGPUs();

    end_t = time(NULL);
    printf("\nTotal time elapsed: %.0lf seconds\n", difftime(end_t, start_t));
//    printf("\n<Press RTN key to exit>\n");
//    getchar();

    return(0);
}

	.text
	.file	"PreprocessReads.hip"
	.globl	_Z18SetAdaptorSequencePKcssss   # -- Begin function _Z18SetAdaptorSequencePKcssss
	.type	_Z18SetAdaptorSequencePKcssss,@function
_Z18SetAdaptorSequencePKcssss:          # @_Z18SetAdaptorSequencePKcssss
	.cfi_startproc
# %bb.0:
	pushq	%rbp
	.cfi_def_cfa_offset 16
	pushq	%r15
	.cfi_def_cfa_offset 24
	pushq	%r14
	.cfi_def_cfa_offset 32
	pushq	%r13
	.cfi_def_cfa_offset 40
	pushq	%r12
	.cfi_def_cfa_offset 48
	pushq	%rbx
	.cfi_def_cfa_offset 56
	subq	$24, %rsp
	.cfi_def_cfa_offset 80
	.cfi_offset %rbx, -56
	.cfi_offset %r12, -48
	.cfi_offset %r13, -40
	.cfi_offset %r14, -32
	.cfi_offset %r15, -24
	.cfi_offset %rbp, -16
	movq	%rdi, %rbx
	movw	%si, 22(%rsp)
	movw	%dx, 20(%rsp)
	movw	%cx, 18(%rsp)
	movw	%r8w, 16(%rsp)
	movl	$100, %esi
	callq	strnlen
	movw	%ax, 14(%rsp)
	cmpl	$0, numGPUs(%rip)
	jle	.LBB0_22
# %bb.1:                                # %.lr.ph.preheader
	leaq	22(%rsp), %r15
	leaq	20(%rsp), %r12
	leaq	18(%rsp), %r13
	leaq	16(%rsp), %rbp
	xorl	%r14d, %r14d
.LBB0_3:                                # %.lr.ph
                                        # =>This Inner Loop Header: Depth=1
	movl	device(,%r14,4), %edi
	callq	hipSetDevice
	cmpb	$0, verbose(%rip)
	je	.LBB0_5
# %bb.4:                                #   in Loop: Header=BB0_3 Depth=1
	movswl	14(%rsp), %ecx
	movl	$.L.str, %edi
	movl	%r14d, %esi
	movq	%rbx, %rdx
	xorl	%eax, %eax
	callq	printf
.LBB0_5:                                #   in Loop: Header=BB0_3 Depth=1
	movswq	14(%rsp), %rdx
	movl	$ADAPTOR, %edi
	movq	%rbx, %rsi
	xorl	%ecx, %ecx
	movl	$1, %r8d
	callq	hipMemcpyToSymbol
	testl	%eax, %eax
	jne	.LBB0_6
# %bb.8:                                #   in Loop: Header=BB0_3 Depth=1
	movl	$ADAPTOR_LEN, %edi
	movl	$2, %edx
	leaq	14(%rsp), %rsi
	xorl	%ecx, %ecx
	movl	$1, %r8d
	callq	hipMemcpyToSymbol
	testl	%eax, %eax
	jne	.LBB0_9
# %bb.10:                               #   in Loop: Header=BB0_3 Depth=1
	cmpb	$0, verbose(%rip)
	je	.LBB0_12
# %bb.11:                               #   in Loop: Header=BB0_3 Depth=1
	movswl	22(%rsp), %edx
	movswl	20(%rsp), %ecx
	movl	$.L.str.3, %edi
	movl	%r14d, %esi
	xorl	%eax, %eax
	callq	printf
.LBB0_12:                               #   in Loop: Header=BB0_3 Depth=1
	movl	$MAX_MM, %edi
	movl	$2, %edx
	movq	%r15, %rsi
	xorl	%ecx, %ecx
	movl	$1, %r8d
	callq	hipMemcpyToSymbol
	testl	%eax, %eax
	jne	.LBB0_13
# %bb.14:                               #   in Loop: Header=BB0_3 Depth=1
	movl	$QUAL_PADDING, %edi
	movl	$2, %edx
	movq	%r12, %rsi
	xorl	%ecx, %ecx
	movl	$1, %r8d
	callq	hipMemcpyToSymbol
	testl	%eax, %eax
	jne	.LBB0_15
# %bb.16:                               #   in Loop: Header=BB0_3 Depth=1
	cmpb	$0, verbose(%rip)
	je	.LBB0_18
# %bb.17:                               #   in Loop: Header=BB0_3 Depth=1
	movswl	18(%rsp), %edx
	movswl	16(%rsp), %ecx
	movl	$.L.str.4, %edi
	movl	%r14d, %esi
	xorl	%eax, %eax
	callq	printf
.LBB0_18:                               #   in Loop: Header=BB0_3 Depth=1
	movl	$MIN_QUAL, %edi
	movl	$2, %edx
	movq	%r13, %rsi
	xorl	%ecx, %ecx
	movl	$1, %r8d
	callq	hipMemcpyToSymbol
	testl	%eax, %eax
	jne	.LBB0_19
# %bb.20:                               #   in Loop: Header=BB0_3 Depth=1
	movl	$MIN_AVERAGE_QUAL_AFTER_BAD, %edi
	movl	$2, %edx
	movq	%rbp, %rsi
	xorl	%ecx, %ecx
	movl	$1, %r8d
	callq	hipMemcpyToSymbol
	testl	%eax, %eax
	jne	.LBB0_21
# %bb.2:                                #   in Loop: Header=BB0_3 Depth=1
	incq	%r14
	movslq	numGPUs(%rip), %rax
	cmpq	%rax, %r14
	jl	.LBB0_3
.LBB0_22:                               # %._crit_edge
	addq	$24, %rsp
	.cfi_def_cfa_offset 56
	popq	%rbx
	.cfi_def_cfa_offset 48
	popq	%r12
	.cfi_def_cfa_offset 40
	popq	%r13
	.cfi_def_cfa_offset 32
	popq	%r14
	.cfi_def_cfa_offset 24
	popq	%r15
	.cfi_def_cfa_offset 16
	popq	%rbp
	.cfi_def_cfa_offset 8
	retq
.LBB0_21:
	.cfi_def_cfa_offset 80
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$112, %ecx
	jmp	.LBB0_7
.LBB0_19:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$111, %ecx
	jmp	.LBB0_7
.LBB0_15:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$109, %ecx
	jmp	.LBB0_7
.LBB0_13:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$108, %ecx
	jmp	.LBB0_7
.LBB0_9:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$106, %ecx
	jmp	.LBB0_7
.LBB0_6:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$105, %ecx
.LBB0_7:
	xorl	%eax, %eax
	callq	fprintf
	movl	$1, %edi
	callq	exit
.Lfunc_end0:
	.size	_Z18SetAdaptorSequencePKcssss, .Lfunc_end0-_Z18SetAdaptorSequencePKcssss
	.cfi_endproc
                                        # -- End function
	.globl	_Z24__device_stub__Find_gRNAPcPsis # -- Begin function _Z24__device_stub__Find_gRNAPcPsis
	.type	_Z24__device_stub__Find_gRNAPcPsis,@function
_Z24__device_stub__Find_gRNAPcPsis:     # @_Z24__device_stub__Find_gRNAPcPsis
	.cfi_startproc
# %bb.0:
	pushq	%r15
	.cfi_def_cfa_offset 16
	pushq	%r14
	.cfi_def_cfa_offset 24
	pushq	%r13
	.cfi_def_cfa_offset 32
	pushq	%r12
	.cfi_def_cfa_offset 40
	pushq	%rbx
	.cfi_def_cfa_offset 48
	subq	$112, %rsp
	.cfi_def_cfa_offset 160
	.cfi_offset %rbx, -48
	.cfi_offset %r12, -40
	.cfi_offset %r13, -32
	.cfi_offset %r14, -24
	.cfi_offset %r15, -16
	leaq	40(%rsp), %rax
	movq	%rdi, (%rax)
	leaq	32(%rsp), %rdi
	movq	%rsi, (%rdi)
	leaq	12(%rsp), %rsi
	movl	%edx, (%rsi)
	leaq	10(%rsp), %rdx
	movw	%cx, (%rdx)
	leaq	80(%rsp), %rbx
	movq	%rax, (%rbx)
	movq	%rdi, 8(%rbx)
	movq	%rsi, 16(%rbx)
	movq	%rdx, 24(%rbx)
	leaq	64(%rsp), %r14
	leaq	48(%rsp), %r15
	leaq	24(%rsp), %r12
	leaq	16(%rsp), %r13
	movq	%r14, %rdi
	movq	%r15, %rsi
	movq	%r12, %rdx
	movq	%r13, %rcx
	callq	__hipPopCallConfiguration
	movq	(%r14), %rsi
	movl	8(%r14), %edx
	movq	(%r15), %rcx
	movl	8(%r15), %r8d
	movl	$_Z9Find_gRNAPcPsis, %edi
	movq	%rbx, %r9
	pushq	(%r13)
	.cfi_adjust_cfa_offset 8
	pushq	(%r12)
	.cfi_adjust_cfa_offset 8
	callq	hipLaunchKernel
	addq	$128, %rsp
	.cfi_adjust_cfa_offset -128
	popq	%rbx
	.cfi_def_cfa_offset 40
	popq	%r12
	.cfi_def_cfa_offset 32
	popq	%r13
	.cfi_def_cfa_offset 24
	popq	%r14
	.cfi_def_cfa_offset 16
	popq	%r15
	.cfi_def_cfa_offset 8
	retq
.Lfunc_end1:
	.size	_Z24__device_stub__Find_gRNAPcPsis, .Lfunc_end1-_Z24__device_stub__Find_gRNAPcPsis
	.cfi_endproc
                                        # -- End function
	.globl	_Z28__device_stub__TrimmAdaptorsPcPsis # -- Begin function _Z28__device_stub__TrimmAdaptorsPcPsis
	.type	_Z28__device_stub__TrimmAdaptorsPcPsis,@function
_Z28__device_stub__TrimmAdaptorsPcPsis: # @_Z28__device_stub__TrimmAdaptorsPcPsis
	.cfi_startproc
# %bb.0:
	pushq	%r15
	.cfi_def_cfa_offset 16
	pushq	%r14
	.cfi_def_cfa_offset 24
	pushq	%r13
	.cfi_def_cfa_offset 32
	pushq	%r12
	.cfi_def_cfa_offset 40
	pushq	%rbx
	.cfi_def_cfa_offset 48
	subq	$112, %rsp
	.cfi_def_cfa_offset 160
	.cfi_offset %rbx, -48
	.cfi_offset %r12, -40
	.cfi_offset %r13, -32
	.cfi_offset %r14, -24
	.cfi_offset %r15, -16
	leaq	40(%rsp), %rax
	movq	%rdi, (%rax)
	leaq	32(%rsp), %rdi
	movq	%rsi, (%rdi)
	leaq	12(%rsp), %rsi
	movl	%edx, (%rsi)
	leaq	10(%rsp), %rdx
	movw	%cx, (%rdx)
	leaq	80(%rsp), %rbx
	movq	%rax, (%rbx)
	movq	%rdi, 8(%rbx)
	movq	%rsi, 16(%rbx)
	movq	%rdx, 24(%rbx)
	leaq	64(%rsp), %r14
	leaq	48(%rsp), %r15
	leaq	24(%rsp), %r12
	leaq	16(%rsp), %r13
	movq	%r14, %rdi
	movq	%r15, %rsi
	movq	%r12, %rdx
	movq	%r13, %rcx
	callq	__hipPopCallConfiguration
	movq	(%r14), %rsi
	movl	8(%r14), %edx
	movq	(%r15), %rcx
	movl	8(%r15), %r8d
	movl	$_Z13TrimmAdaptorsPcPsis, %edi
	movq	%rbx, %r9
	pushq	(%r13)
	.cfi_adjust_cfa_offset 8
	pushq	(%r12)
	.cfi_adjust_cfa_offset 8
	callq	hipLaunchKernel
	addq	$128, %rsp
	.cfi_adjust_cfa_offset -128
	popq	%rbx
	.cfi_def_cfa_offset 40
	popq	%r12
	.cfi_def_cfa_offset 32
	popq	%r13
	.cfi_def_cfa_offset 24
	popq	%r14
	.cfi_def_cfa_offset 16
	popq	%r15
	.cfi_def_cfa_offset 8
	retq
.Lfunc_end2:
	.size	_Z28__device_stub__TrimmAdaptorsPcPsis, .Lfunc_end2-_Z28__device_stub__TrimmAdaptorsPcPsis
	.cfi_endproc
                                        # -- End function
	.globl	_Z25__device_stub__TrimmQualsPcPsis # -- Begin function _Z25__device_stub__TrimmQualsPcPsis
	.type	_Z25__device_stub__TrimmQualsPcPsis,@function
_Z25__device_stub__TrimmQualsPcPsis:    # @_Z25__device_stub__TrimmQualsPcPsis
	.cfi_startproc
# %bb.0:
	pushq	%r15
	.cfi_def_cfa_offset 16
	pushq	%r14
	.cfi_def_cfa_offset 24
	pushq	%r13
	.cfi_def_cfa_offset 32
	pushq	%r12
	.cfi_def_cfa_offset 40
	pushq	%rbx
	.cfi_def_cfa_offset 48
	subq	$112, %rsp
	.cfi_def_cfa_offset 160
	.cfi_offset %rbx, -48
	.cfi_offset %r12, -40
	.cfi_offset %r13, -32
	.cfi_offset %r14, -24
	.cfi_offset %r15, -16
	leaq	40(%rsp), %rax
	movq	%rdi, (%rax)
	leaq	32(%rsp), %rdi
	movq	%rsi, (%rdi)
	leaq	12(%rsp), %rsi
	movl	%edx, (%rsi)
	leaq	10(%rsp), %rdx
	movw	%cx, (%rdx)
	leaq	80(%rsp), %rbx
	movq	%rax, (%rbx)
	movq	%rdi, 8(%rbx)
	movq	%rsi, 16(%rbx)
	movq	%rdx, 24(%rbx)
	leaq	64(%rsp), %r14
	leaq	48(%rsp), %r15
	leaq	24(%rsp), %r12
	leaq	16(%rsp), %r13
	movq	%r14, %rdi
	movq	%r15, %rsi
	movq	%r12, %rdx
	movq	%r13, %rcx
	callq	__hipPopCallConfiguration
	movq	(%r14), %rsi
	movl	8(%r14), %edx
	movq	(%r15), %rcx
	movl	8(%r15), %r8d
	movl	$_Z10TrimmQualsPcPsis, %edi
	movq	%rbx, %r9
	pushq	(%r13)
	.cfi_adjust_cfa_offset 8
	pushq	(%r12)
	.cfi_adjust_cfa_offset 8
	callq	hipLaunchKernel
	addq	$128, %rsp
	.cfi_adjust_cfa_offset -128
	popq	%rbx
	.cfi_def_cfa_offset 40
	popq	%r12
	.cfi_def_cfa_offset 32
	popq	%r13
	.cfi_def_cfa_offset 24
	popq	%r14
	.cfi_def_cfa_offset 16
	popq	%r15
	.cfi_def_cfa_offset 8
	retq
.Lfunc_end3:
	.size	_Z25__device_stub__TrimmQualsPcPsis, .Lfunc_end3-_Z25__device_stub__TrimmQualsPcPsis
	.cfi_endproc
                                        # -- End function
	.globl	_Z8InitGPUsv                    # -- Begin function _Z8InitGPUsv
	.type	_Z8InitGPUsv,@function
_Z8InitGPUsv:                           # @_Z8InitGPUsv
	.cfi_startproc
# %bb.0:
	pushq	%r15
	.cfi_def_cfa_offset 16
	pushq	%r14
	.cfi_def_cfa_offset 24
	pushq	%r13
	.cfi_def_cfa_offset 32
	pushq	%r12
	.cfi_def_cfa_offset 40
	pushq	%rbx
	.cfi_def_cfa_offset 48
	.cfi_offset %rbx, -48
	.cfi_offset %r12, -40
	.cfi_offset %r13, -32
	.cfi_offset %r14, -24
	.cfi_offset %r15, -16
	cmpb	$0, verbose(%rip)
	je	.LBB4_2
# %bb.1:
	movl	$10, %edi
	callq	putchar@PLT
.LBB4_2:
	cmpl	$0, numGPUs(%rip)
	jle	.LBB4_46
# %bb.3:                                # %.lr.ph.preheader
	movl	$hReadSequence, %ebx
	movl	$hReadLen, %r14d
	movl	$dIntArray, %r15d
	xorl	%r13d, %r13d
	xorl	%r12d, %r12d
.LBB4_5:                                # %.lr.ph
                                        # =>This Inner Loop Header: Depth=1
	cmpb	$0, verbose(%rip)
	je	.LBB4_7
# %bb.6:                                #   in Loop: Header=BB4_5 Depth=1
	movl	$.L.str.6, %edi
	movl	%r12d, %esi
	xorl	%eax, %eax
	callq	printf
.LBB4_7:                                #   in Loop: Header=BB4_5 Depth=1
	movl	device(,%r12,4), %edi
	callq	hipSetDevice
	testl	%eax, %eax
	jne	.LBB4_8
# %bb.10:                               #   in Loop: Header=BB4_5 Depth=1
	leaq	dSequenceArray(%r13), %rdi
	movslq	MAX_READS_ON_GPU(%rip), %rax
	movswq	MAX_READ_LENGTH(%rip), %rsi
	imulq	%rax, %rsi
	callq	hipMalloc
	testl	%eax, %eax
	jne	.LBB4_11
# %bb.12:                               #   in Loop: Header=BB4_5 Depth=1
	leaq	dQualArray(%r13), %rdi
	movslq	MAX_READS_ON_GPU(%rip), %rax
	movswq	MAX_READ_LENGTH(%rip), %rsi
	imulq	%rax, %rsi
	callq	hipMalloc
	testl	%eax, %eax
	jne	.LBB4_13
# %bb.14:                               #   in Loop: Header=BB4_5 Depth=1
	movslq	MAX_READS_ON_GPU(%rip), %rsi
	addq	%rsi, %rsi
	movq	%r15, %rdi
	callq	hipMalloc
	testl	%eax, %eax
	jne	.LBB4_15
# %bb.16:                               #   in Loop: Header=BB4_5 Depth=1
	leaq	8(%r15), %rdi
	movslq	MAX_READS_ON_GPU(%rip), %rsi
	addq	%rsi, %rsi
	callq	hipMalloc
	testl	%eax, %eax
	jne	.LBB4_17
# %bb.18:                               #   in Loop: Header=BB4_5 Depth=1
	leaq	upload_stream(%r13), %rdi
	callq	hipStreamCreate
	testl	%eax, %eax
	jne	.LBB4_19
# %bb.20:                               #   in Loop: Header=BB4_5 Depth=1
	leaq	compute_stream(%r13), %rdi
	callq	hipStreamCreate
	testl	%eax, %eax
	jne	.LBB4_21
# %bb.22:                               #   in Loop: Header=BB4_5 Depth=1
	leaq	download_stream(%r13), %rdi
	callq	hipStreamCreate
	testl	%eax, %eax
	jne	.LBB4_23
# %bb.24:                               #   in Loop: Header=BB4_5 Depth=1
	leaq	QUAL_COPY_DONE(%r13), %rdi
	movl	$1, %esi
	callq	hipEventCreateWithFlags
	testl	%eax, %eax
	jne	.LBB4_25
# %bb.26:                               #   in Loop: Header=BB4_5 Depth=1
	leaq	SEQ_COPY_DONE(%r13), %rdi
	movl	$2, %esi
	callq	hipEventCreateWithFlags
	testl	%eax, %eax
	jne	.LBB4_27
# %bb.28:                               #   in Loop: Header=BB4_5 Depth=1
	leaq	TrimmQ_DONE(%r13), %rdi
	movl	$2, %esi
	callq	hipEventCreateWithFlags
	testl	%eax, %eax
	jne	.LBB4_29
# %bb.30:                               #   in Loop: Header=BB4_5 Depth=1
	leaq	TrimmA_DONE(%r13), %rdi
	movl	$2, %esi
	callq	hipEventCreateWithFlags
	testl	%eax, %eax
	jne	.LBB4_31
# %bb.32:                               #   in Loop: Header=BB4_5 Depth=1
	leaq	DTH_COPY_DONE(%r13), %rdi
	movl	$1, %esi
	callq	hipEventCreateWithFlags
	testl	%eax, %eax
	jne	.LBB4_33
# %bb.34:                               #   in Loop: Header=BB4_5 Depth=1
	cmpb	$0, verbose(%rip)
	je	.LBB4_36
# %bb.35:                               #   in Loop: Header=BB4_5 Depth=1
	movl	$.L.str.7, %edi
	movl	%r12d, %esi
	xorl	%eax, %eax
	callq	printf
.LBB4_36:                               #   in Loop: Header=BB4_5 Depth=1
	movslq	MAX_READS_ON_GPU(%rip), %rsi
	addq	%rsi, %rsi
	movq	%r14, %rdi
	xorl	%edx, %edx
	callq	hipHostMalloc
	testl	%eax, %eax
	jne	.LBB4_37
# %bb.38:                               #   in Loop: Header=BB4_5 Depth=1
	leaq	8(%r14), %rdi
	movslq	MAX_READS_ON_GPU(%rip), %rsi
	addq	%rsi, %rsi
	xorl	%edx, %edx
	callq	hipHostMalloc
	testl	%eax, %eax
	jne	.LBB4_39
# %bb.40:                               #   in Loop: Header=BB4_5 Depth=1
	movslq	MAX_READS_ON_GPU(%rip), %rax
	movswq	MAX_READ_LENGTH(%rip), %rsi
	imulq	%rax, %rsi
	movq	%rbx, %rdi
	xorl	%edx, %edx
	callq	hipHostMalloc
	testl	%eax, %eax
	jne	.LBB4_41
# %bb.42:                               #   in Loop: Header=BB4_5 Depth=1
	leaq	8(%rbx), %rdi
	movslq	MAX_READS_ON_GPU(%rip), %rax
	movswq	MAX_READ_LENGTH(%rip), %rsi
	imulq	%rax, %rsi
	xorl	%edx, %edx
	callq	hipHostMalloc
	testl	%eax, %eax
	jne	.LBB4_43
# %bb.44:                               #   in Loop: Header=BB4_5 Depth=1
	leaq	hReadQualstr(%r13), %rdi
	movslq	MAX_READS_ON_GPU(%rip), %rax
	movswq	MAX_READ_LENGTH(%rip), %rsi
	imulq	%rax, %rsi
	xorl	%edx, %edx
	callq	hipHostMalloc
	testl	%eax, %eax
	jne	.LBB4_45
# %bb.4:                                #   in Loop: Header=BB4_5 Depth=1
	incq	%r12
	movslq	numGPUs(%rip), %rax
	addq	$8, %r13
	addq	$16, %rbx
	addq	$16, %r14
	addq	$16, %r15
	cmpq	%rax, %r12
	jl	.LBB4_5
.LBB4_46:                               # %._crit_edge
	popq	%rbx
	.cfi_def_cfa_offset 40
	popq	%r12
	.cfi_def_cfa_offset 32
	popq	%r13
	.cfi_def_cfa_offset 24
	popq	%r14
	.cfi_def_cfa_offset 16
	popq	%r15
	.cfi_def_cfa_offset 8
	retq
.LBB4_43:
	.cfi_def_cfa_offset 48
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$316, %ecx                      # imm = 0x13C
	jmp	.LBB4_9
.LBB4_41:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$315, %ecx                      # imm = 0x13B
	jmp	.LBB4_9
.LBB4_39:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$313, %ecx                      # imm = 0x139
	jmp	.LBB4_9
.LBB4_37:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$312, %ecx                      # imm = 0x138
	jmp	.LBB4_9
.LBB4_33:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$309, %ecx                      # imm = 0x135
	jmp	.LBB4_9
.LBB4_31:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$308, %ecx                      # imm = 0x134
	jmp	.LBB4_9
.LBB4_29:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$307, %ecx                      # imm = 0x133
	jmp	.LBB4_9
.LBB4_27:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$306, %ecx                      # imm = 0x132
	jmp	.LBB4_9
.LBB4_25:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$305, %ecx                      # imm = 0x131
	jmp	.LBB4_9
.LBB4_23:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$303, %ecx                      # imm = 0x12F
	jmp	.LBB4_9
.LBB4_21:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$302, %ecx                      # imm = 0x12E
	jmp	.LBB4_9
.LBB4_19:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$301, %ecx                      # imm = 0x12D
	jmp	.LBB4_9
.LBB4_17:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$299, %ecx                      # imm = 0x12B
	jmp	.LBB4_9
.LBB4_15:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$298, %ecx                      # imm = 0x12A
	jmp	.LBB4_9
.LBB4_13:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$297, %ecx                      # imm = 0x129
	jmp	.LBB4_9
.LBB4_11:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$296, %ecx                      # imm = 0x128
	jmp	.LBB4_9
.LBB4_8:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$295, %ecx                      # imm = 0x127
	jmp	.LBB4_9
.LBB4_45:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$318, %ecx                      # imm = 0x13E
.LBB4_9:
	xorl	%eax, %eax
	callq	fprintf
	movl	$1, %edi
	callq	exit
.Lfunc_end4:
	.size	_Z8InitGPUsv, .Lfunc_end4-_Z8InitGPUsv
	.cfi_endproc
                                        # -- End function
	.globl	_Z8FreeGPUsv                    # -- Begin function _Z8FreeGPUsv
	.type	_Z8FreeGPUsv,@function
_Z8FreeGPUsv:                           # @_Z8FreeGPUsv
	.cfi_startproc
# %bb.0:
	pushq	%r14
	.cfi_def_cfa_offset 16
	pushq	%rbx
	.cfi_def_cfa_offset 24
	pushq	%rax
	.cfi_def_cfa_offset 32
	.cfi_offset %rbx, -24
	.cfi_offset %r14, -16
	cmpl	$0, numGPUs(%rip)
	jle	.LBB5_30
# %bb.1:                                # %.lr.ph.preheader
	xorl	%ebx, %ebx
	xorl	%r14d, %r14d
.LBB5_2:                                # %.lr.ph
                                        # =>This Inner Loop Header: Depth=1
	movl	device(%rbx), %edi
	callq	hipSetDevice
	testl	%eax, %eax
	jne	.LBB5_3
# %bb.5:                                #   in Loop: Header=BB5_2 Depth=1
	movq	QUAL_COPY_DONE(%rbx,%rbx), %rdi
	callq	hipEventDestroy
	testl	%eax, %eax
	jne	.LBB5_6
# %bb.7:                                #   in Loop: Header=BB5_2 Depth=1
	movq	SEQ_COPY_DONE(%rbx,%rbx), %rdi
	callq	hipEventDestroy
	testl	%eax, %eax
	jne	.LBB5_8
# %bb.9:                                #   in Loop: Header=BB5_2 Depth=1
	movq	TrimmQ_DONE(%rbx,%rbx), %rdi
	callq	hipEventDestroy
	testl	%eax, %eax
	jne	.LBB5_10
# %bb.11:                               #   in Loop: Header=BB5_2 Depth=1
	movq	TrimmA_DONE(%rbx,%rbx), %rdi
	callq	hipEventDestroy
	testl	%eax, %eax
	jne	.LBB5_12
# %bb.13:                               #   in Loop: Header=BB5_2 Depth=1
	movq	DTH_COPY_DONE(%rbx,%rbx), %rdi
	callq	hipEventDestroy
	testl	%eax, %eax
	jne	.LBB5_14
# %bb.15:                               #   in Loop: Header=BB5_2 Depth=1
	movq	upload_stream(%rbx,%rbx), %rdi
	callq	hipStreamDestroy
	testl	%eax, %eax
	jne	.LBB5_16
# %bb.17:                               #   in Loop: Header=BB5_2 Depth=1
	movq	compute_stream(%rbx,%rbx), %rdi
	callq	hipStreamDestroy
	testl	%eax, %eax
	jne	.LBB5_18
# %bb.19:                               #   in Loop: Header=BB5_2 Depth=1
	movq	download_stream(%rbx,%rbx), %rdi
	callq	hipStreamDestroy
	testl	%eax, %eax
	jne	.LBB5_20
# %bb.21:                               #   in Loop: Header=BB5_2 Depth=1
	movq	dIntArray(,%rbx,4), %rdi
	callq	hipFree
	testl	%eax, %eax
	jne	.LBB5_22
# %bb.23:                               #   in Loop: Header=BB5_2 Depth=1
	movq	dIntArray+8(,%rbx,4), %rdi
	callq	hipFree
	testl	%eax, %eax
	jne	.LBB5_24
# %bb.25:                               #   in Loop: Header=BB5_2 Depth=1
	movq	dSequenceArray(%rbx,%rbx), %rdi
	callq	hipFree
	testl	%eax, %eax
	jne	.LBB5_26
# %bb.27:                               #   in Loop: Header=BB5_2 Depth=1
	movq	dQualArray(%rbx,%rbx), %rdi
	callq	hipFree
	testl	%eax, %eax
	jne	.LBB5_28
# %bb.29:                               #   in Loop: Header=BB5_2 Depth=1
	movq	hReadLen(,%rbx,4), %rdi
	callq	hipHostFree
	movq	hReadLen+8(,%rbx,4), %rdi
	callq	hipHostFree
	movq	hReadSequence(,%rbx,4), %rdi
	callq	hipHostFree
	movq	hReadSequence+8(,%rbx,4), %rdi
	callq	hipHostFree
	movq	hReadQualstr(%rbx,%rbx), %rdi
	callq	hipHostFree
	incq	%r14
	movslq	numGPUs(%rip), %rax
	addq	$4, %rbx
	cmpq	%rax, %r14
	jl	.LBB5_2
.LBB5_30:                               # %._crit_edge
	addq	$8, %rsp
	.cfi_def_cfa_offset 24
	popq	%rbx
	.cfi_def_cfa_offset 16
	popq	%r14
	.cfi_def_cfa_offset 8
	retq
.LBB5_28:
	.cfi_def_cfa_offset 32
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$341, %ecx                      # imm = 0x155
	jmp	.LBB5_4
.LBB5_26:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$340, %ecx                      # imm = 0x154
	jmp	.LBB5_4
.LBB5_24:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$339, %ecx                      # imm = 0x153
	jmp	.LBB5_4
.LBB5_22:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$338, %ecx                      # imm = 0x152
	jmp	.LBB5_4
.LBB5_20:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$336, %ecx                      # imm = 0x150
	jmp	.LBB5_4
.LBB5_18:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$335, %ecx                      # imm = 0x14F
	jmp	.LBB5_4
.LBB5_16:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$334, %ecx                      # imm = 0x14E
	jmp	.LBB5_4
.LBB5_14:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$333, %ecx                      # imm = 0x14D
	jmp	.LBB5_4
.LBB5_12:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$332, %ecx                      # imm = 0x14C
	jmp	.LBB5_4
.LBB5_10:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$331, %ecx                      # imm = 0x14B
	jmp	.LBB5_4
.LBB5_8:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$330, %ecx                      # imm = 0x14A
	jmp	.LBB5_4
.LBB5_6:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$329, %ecx                      # imm = 0x149
	jmp	.LBB5_4
.LBB5_3:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$327, %ecx                      # imm = 0x147
.LBB5_4:
	xorl	%eax, %eax
	callq	fprintf
	movl	$1, %edi
	callq	exit
.Lfunc_end5:
	.size	_Z8FreeGPUsv, .Lfunc_end5-_Z8FreeGPUsv
	.cfi_endproc
                                        # -- End function
	.section	.rodata.cst4,"aM",@progbits,4
	.p2align	2, 0x0                          # -- Begin function _Z8FindGPUsv
.LCPI6_0:
	.long	0x35800000                      # float 9.53674316E-7
	.text
	.globl	_Z8FindGPUsv
	.type	_Z8FindGPUsv,@function
_Z8FindGPUsv:                           # @_Z8FindGPUsv
	.cfi_startproc
# %bb.0:
	pushq	%rbp
	.cfi_def_cfa_offset 16
	pushq	%r15
	.cfi_def_cfa_offset 24
	pushq	%r14
	.cfi_def_cfa_offset 32
	pushq	%r13
	.cfi_def_cfa_offset 40
	pushq	%r12
	.cfi_def_cfa_offset 48
	pushq	%rbx
	.cfi_def_cfa_offset 56
	subq	$1496, %rsp                     # imm = 0x5D8
	.cfi_def_cfa_offset 1552
	.cfi_offset %rbx, -56
	.cfi_offset %r12, -48
	.cfi_offset %r13, -40
	.cfi_offset %r14, -32
	.cfi_offset %r15, -24
	.cfi_offset %rbp, -16
	movl	$0, numGPUs(%rip)
	leaq	12(%rsp), %rdi
	callq	hipGetDeviceCount
	testl	%eax, %eax
	jne	.LBB6_16
# %bb.1:
	cmpl	$0, 12(%rsp)
	je	.LBB6_2
# %bb.3:                                # %.preheader
	jle	.LBB6_14
# %bb.4:                                # %.lr.ph
	xorl	%ebx, %ebx
	leaq	24(%rsp), %r14
	leaq	20(%rsp), %r15
	leaq	16(%rsp), %r12
	movabsq	$6144000001, %r13               # imm = 0x16E360001
	movl	$65535, %ebp                    # imm = 0xFFFF
.LBB6_5:                                # =>This Inner Loop Header: Depth=1
	movl	%ebx, %edi
	callq	hipSetDevice
	movq	%r14, %rdi
	movl	%ebx, %esi
	callq	hipGetDevicePropertiesR0600
	movq	%r15, %rdi
	callq	hipDriverGetVersion
	movq	%r12, %rdi
	callq	hipRuntimeGetVersion
	movl	384(%rsp), %eax
	cmpl	$3, %eax
	setne	%cl
	cmpl	$5, 388(%rsp)
	setl	%dl
	orb	%cl, %dl
	cmpl	$4, %eax
	setl	%al
	testb	%dl, %al
	jne	.LBB6_13
# %bb.6:                                #   in Loop: Header=BB6_5 Depth=1
	cmpq	%r13, 312(%rsp)
	jb	.LBB6_13
# %bb.7:                                #   in Loop: Header=BB6_5 Depth=1
	cmpb	$0, verbose(%rip)
	je	.LBB6_12
# %bb.8:                                #   in Loop: Header=BB6_5 Depth=1
	movl	$.L.str.8, %edi
	movl	%ebx, %esi
	movq	%r14, %rdx
	xorl	%eax, %eax
	callq	printf
	movslq	20(%rsp), %rax
	imulq	$274877907, %rax, %rsi          # imm = 0x10624DD3
	movq	%rsi, %rcx
	shrq	$63, %rcx
	sarq	$38, %rsi
	addl	%ecx, %esi
	imulq	$1374389535, %rax, %rcx         # imm = 0x51EB851F
	movq	%rcx, %rdx
	shrq	$63, %rdx
	shrq	$37, %rcx
	addl	%edx, %ecx
	imull	$100, %ecx, %ecx
	subl	%ecx, %eax
	movsbl	%al, %eax
	imull	$103, %eax, %eax
	movswl	%ax, %ecx
	andl	%ebp, %eax
	shrl	$15, %eax
	shrl	$10, %ecx
	addb	%al, %cl
	movsbl	%cl, %edx
	movslq	16(%rsp), %rax
	imulq	$274877907, %rax, %rcx          # imm = 0x10624DD3
	movq	%rcx, %rdi
	shrq	$63, %rdi
	sarq	$38, %rcx
	addl	%edi, %ecx
	imulq	$1374389535, %rax, %rdi         # imm = 0x51EB851F
	movq	%rdi, %r8
	shrq	$63, %r8
	shrq	$37, %rdi
	addl	%r8d, %edi
	imull	$100, %edi, %edi
	subl	%edi, %eax
	movsbl	%al, %eax
	imull	$103, %eax, %eax
	movswl	%ax, %edi
	andl	%ebp, %eax
	shrl	$15, %eax
	shrl	$10, %edi
	addb	%al, %dil
	movsbl	%dil, %r8d
	movl	$.L.str.9, %edi
                                        # kill: def $esi killed $esi killed $rsi
                                        # kill: def $ecx killed $ecx killed $rcx
	xorl	%eax, %eax
	callq	printf
	movl	384(%rsp), %esi
	movl	388(%rsp), %edx
	movl	$.L.str.10, %edi
	xorl	%eax, %eax
	callq	printf
	movl	608(%rsp), %esi
	movl	612(%rsp), %edx
	movl	$.L.str.11, %edi
	xorl	%eax, %eax
	callq	printf
	movq	312(%rsp), %rsi
	testq	%rsi, %rsi
	js	.LBB6_9
# %bb.10:                               #   in Loop: Header=BB6_5 Depth=1
	cvtsi2ss	%rsi, %xmm0
	jmp	.LBB6_11
.LBB6_9:                                #   in Loop: Header=BB6_5 Depth=1
	movq	%rsi, %rax
	shrq	%rax
	movl	%esi, %ecx
	andl	$1, %ecx
	orq	%rax, %rcx
	cvtsi2ss	%rcx, %xmm0
	addss	%xmm0, %xmm0
.LBB6_11:                               #   in Loop: Header=BB6_5 Depth=1
	mulss	.LCPI6_0(%rip), %xmm0
	cvtss2sd	%xmm0, %xmm0
	movl	$.L.str.12, %edi
	movb	$1, %al
	callq	printf
	movl	412(%rsp), %esi
	movl	$.L.str.13, %edi
	xorl	%eax, %eax
	callq	printf
.LBB6_12:                               #   in Loop: Header=BB6_5 Depth=1
	movslq	numGPUs(%rip), %rax
	leal	1(%rax), %ecx
	movl	%ebx, device(,%rax,4)
	movl	%ecx, numGPUs(%rip)
	cmpq	$2, %rax
	jg	.LBB6_14
.LBB6_13:                               # %.critedge
                                        #   in Loop: Header=BB6_5 Depth=1
	incl	%ebx
	cmpl	12(%rsp), %ebx
	jl	.LBB6_5
.LBB6_14:                               # %.loopexit
	movl	numGPUs(%rip), %eax
	jmp	.LBB6_15
.LBB6_2:
	xorl	%eax, %eax
.LBB6_15:
	addq	$1496, %rsp                     # imm = 0x5D8
	.cfi_def_cfa_offset 56
	popq	%rbx
	.cfi_def_cfa_offset 48
	popq	%r12
	.cfi_def_cfa_offset 40
	popq	%r13
	.cfi_def_cfa_offset 32
	popq	%r14
	.cfi_def_cfa_offset 24
	popq	%r15
	.cfi_def_cfa_offset 16
	popq	%rbp
	.cfi_def_cfa_offset 8
	retq
.LBB6_16:
	.cfi_def_cfa_offset 1552
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$356, %ecx                      # imm = 0x164
	xorl	%eax, %eax
	callq	fprintf
	movl	$1, %edi
	callq	exit
.Lfunc_end6:
	.size	_Z8FindGPUsv, .Lfunc_end6-_Z8FindGPUsv
	.cfi_endproc
                                        # -- End function
	.globl	_Z9OpenFilesv                   # -- Begin function _Z9OpenFilesv
	.type	_Z9OpenFilesv,@function
_Z9OpenFilesv:                          # @_Z9OpenFilesv
	.cfi_startproc
# %bb.0:
	pushq	%rbx
	.cfi_def_cfa_offset 16
	.cfi_offset %rbx, -16
	cmpb	$0, overwrite_outputfile(%rip)
	jne	.LBB7_2
# %bb.1:
	movl	$output_filename, %edi
	movl	$.L.str.14, %esi
	callq	fopen
	movq	%rax, outputFile(%rip)
	testq	%rax, %rax
	jne	.LBB7_22
.LBB7_2:
	movl	$input_filename, %edi
	movl	$.L.str.14, %esi
	callq	gzopen
	movq	%rax, inputFile(%rip)
	testq	%rax, %rax
	je	.LBB7_18
# %bb.3:
	movl	$input_filename, %edi
	movl	$.L.str.14, %esi
	callq	gzopen
	movq	%rax, templateFile(%rip)
	testq	%rax, %rax
	je	.LBB7_19
# %bb.4:
	movb	$1, %bl
	cmpb	$0, write_pigz_output(%rip)
	je	.LBB7_8
# %bb.5:
	movl	$PIGZ_PIPE, %edi
	movl	$output_filename, %esi
	callq	strcat
	movl	$PIGZ_PIPE, %edi
	movl	$.L.str.18, %esi
	callq	popen
	movq	%rax, outputFile(%rip)
	testq	%rax, %rax
	je	.LBB7_7
# %bb.6:                                # %._crit_edge
	cmpb	$0, write_pigz_output(%rip)
	sete	%bl
	jmp	.LBB7_8
.LBB7_7:
	movl	$.Lstr.1, %edi
	callq	puts@PLT
	movb	$1, write_gz_output(%rip)
	movb	$0, write_pigz_output(%rip)
.LBB7_8:
	movb	write_gz_output(%rip), %al
	testb	%al, %al
	je	.LBB7_13
# %bb.9:
	testb	%bl, %bl
	je	.LBB7_13
# %bb.10:
	movl	$GZIP_PIPE, %edi
	movl	$output_filename, %esi
	callq	strcat
	movl	$GZIP_PIPE, %edi
	movl	$.L.str.18, %esi
	callq	popen
	movq	%rax, outputFile(%rip)
	testq	%rax, %rax
	je	.LBB7_12
# %bb.11:                               # %._crit_edge11
	movb	write_gz_output(%rip), %al
	jmp	.LBB7_13
.LBB7_12:
	movl	$.Lstr.2, %edi
	callq	puts@PLT
	movb	$0, write_gz_output(%rip)
	xorl	%eax, %eax
.LBB7_13:
	orb	write_pigz_output(%rip), %al
	jne	.LBB7_15
# %bb.14:
	movl	$output_filename, %edi
	movl	$.L.str.18, %esi
	callq	fopen
	movq	%rax, outputFile(%rip)
	jmp	.LBB7_16
.LBB7_15:                               # %thread-pre-split
	movq	outputFile(%rip), %rax
.LBB7_16:
	testq	%rax, %rax
	je	.LBB7_20
# %bb.17:
	popq	%rbx
	.cfi_def_cfa_offset 8
	retq
.LBB7_18:
	.cfi_def_cfa_offset 16
	movl	$.L.str.16, %edi
	movl	$input_filename, %esi
	jmp	.LBB7_21
.LBB7_19:
	movl	$.Lstr.3, %edi
	jmp	.LBB7_23
.LBB7_20:
	movl	$.L.str.21, %edi
	movl	$output_filename, %esi
.LBB7_21:
	xorl	%eax, %eax
	callq	printf
	jmp	.LBB7_24
.LBB7_22:
	movl	$.Lstr, %edi
.LBB7_23:
	callq	puts@PLT
.LBB7_24:
	movl	$255, %edi
	callq	exit
.Lfunc_end7:
	.size	_Z9OpenFilesv, .Lfunc_end7-_Z9OpenFilesv
	.cfi_endproc
                                        # -- End function
	.globl	_Z16ReadBlockOfReadsiPsPcS0_    # -- Begin function _Z16ReadBlockOfReadsiPsPcS0_
	.type	_Z16ReadBlockOfReadsiPsPcS0_,@function
_Z16ReadBlockOfReadsiPsPcS0_:           # @_Z16ReadBlockOfReadsiPsPcS0_
	.cfi_startproc
# %bb.0:
	pushq	%rbp
	.cfi_def_cfa_offset 16
	pushq	%r15
	.cfi_def_cfa_offset 24
	pushq	%r14
	.cfi_def_cfa_offset 32
	pushq	%r13
	.cfi_def_cfa_offset 40
	pushq	%r12
	.cfi_def_cfa_offset 48
	pushq	%rbx
	.cfi_def_cfa_offset 56
	pushq	%rax
	.cfi_def_cfa_offset 64
	.cfi_offset %rbx, -56
	.cfi_offset %r12, -48
	.cfi_offset %r13, -40
	.cfi_offset %r14, -32
	.cfi_offset %r15, -24
	.cfi_offset %rbp, -16
	movq	%rcx, (%rsp)                    # 8-byte Spill
	movq	%rdx, %r15
	movq	%rsi, %r12
	movl	%edi, %r14d
	xorl	%ebx, %ebx
.LBB8_1:                                # =>This Inner Loop Header: Depth=1
	movq	inputFile(%rip), %rdi
	movl	$Read, %esi
	movl	$500, %edx                      # imm = 0x1F4
	callq	gzgets
	testq	%rax, %rax
	je	.LBB8_13
# %bb.2:                                #   in Loop: Header=BB8_1 Depth=1
	movb	Read(%rip), %al
	cmpb	$13, %al
	je	.LBB8_13
# %bb.3:                                #   in Loop: Header=BB8_1 Depth=1
	cmpb	$10, %al
	je	.LBB8_13
# %bb.4:                                #   in Loop: Header=BB8_1 Depth=1
	movq	inputFile(%rip), %rdi
	movl	$Read+500, %esi
	movl	$500, %edx                      # imm = 0x1F4
	callq	gzgets
	testq	%rax, %rax
	je	.LBB8_14
# %bb.5:                                #   in Loop: Header=BB8_1 Depth=1
	movq	inputFile(%rip), %rdi
	movl	$Read+1000, %esi
	movl	$500, %edx                      # imm = 0x1F4
	callq	gzgets
	testq	%rax, %rax
	je	.LBB8_14
# %bb.6:                                #   in Loop: Header=BB8_1 Depth=1
	movq	inputFile(%rip), %rdi
	movl	$Read+1500, %esi
	movl	$500, %edx                      # imm = 0x1F4
	callq	gzgets
	testq	%rax, %rax
	je	.LBB8_14
# %bb.7:                                #   in Loop: Header=BB8_1 Depth=1
	cmpb	$0, FastQ_WARNING(%rip)
	jne	.LBB8_11
# %bb.8:                                #   in Loop: Header=BB8_1 Depth=1
	cmpb	$64, Read(%rip)
	jne	.LBB8_10
# %bb.9:                                #   in Loop: Header=BB8_1 Depth=1
	cmpb	$43, Read+1000(%rip)
	je	.LBB8_11
.LBB8_10:                               #   in Loop: Header=BB8_1 Depth=1
	movl	$.Lstr.4, %edi
	callq	puts@PLT
	movb	$1, FastQ_WARNING(%rip)
.LBB8_11:                               #   in Loop: Header=BB8_1 Depth=1
	movl	$Read+500, %edi
	callq	strlen
	movq	%rax, %r13
	decl	%r13d
	movswl	MAX_READ_LENGTH(%rip), %eax
	cmpw	%ax, %r13w
	cmovgel	%eax, %r13d
	imull	%ebx, %eax
	movslq	%eax, %rdi
	addq	%r15, %rdi
	movswq	%r13w, %rbp
	movl	$Read+500, %esi
	movq	%rbp, %rdx
	callq	memcpy@PLT
	movswl	MAX_READ_LENGTH(%rip), %eax
	imull	%ebx, %eax
	movslq	%eax, %rdi
	addq	(%rsp), %rdi                    # 8-byte Folded Reload
	movl	$Read+1500, %esi
	movq	%rbp, %rdx
	callq	memcpy@PLT
	movw	%r13w, (%r12,%rbx,2)
	incq	%rbx
	cmpq	%rbx, %r14
	jne	.LBB8_1
# %bb.12:                               # %.split.loop.exit.loopexit
	movl	%r14d, %ebx
.LBB8_13:                               # %.split.loop.exit
	addl	%ebx, hNumberOfReads(%rip)
	movl	%ebx, %eax
	addq	$8, %rsp
	.cfi_def_cfa_offset 56
	popq	%rbx
	.cfi_def_cfa_offset 48
	popq	%r12
	.cfi_def_cfa_offset 40
	popq	%r13
	.cfi_def_cfa_offset 32
	popq	%r14
	.cfi_def_cfa_offset 24
	popq	%r15
	.cfi_def_cfa_offset 16
	popq	%rbp
	.cfi_def_cfa_offset 8
	retq
.LBB8_14:
	.cfi_def_cfa_offset 64
	movl	$.Lstr.13, %edi
	callq	puts@PLT
	movl	$255, %edi
	callq	exit
.Lfunc_end8:
	.size	_Z16ReadBlockOfReadsiPsPcS0_, .Lfunc_end8-_Z16ReadBlockOfReadsiPsPcS0_
	.cfi_endproc
                                        # -- End function
	.globl	_Z17WriteBlockOfReadsiPKss      # -- Begin function _Z17WriteBlockOfReadsiPKss
	.type	_Z17WriteBlockOfReadsiPKss,@function
_Z17WriteBlockOfReadsiPKss:             # @_Z17WriteBlockOfReadsiPKss
	.cfi_startproc
# %bb.0:
	pushq	%rbp
	.cfi_def_cfa_offset 16
	pushq	%r15
	.cfi_def_cfa_offset 24
	pushq	%r14
	.cfi_def_cfa_offset 32
	pushq	%r13
	.cfi_def_cfa_offset 40
	pushq	%r12
	.cfi_def_cfa_offset 48
	pushq	%rbx
	.cfi_def_cfa_offset 56
	subq	$536, %rsp                      # imm = 0x218
	.cfi_def_cfa_offset 592
	.cfi_offset %rbx, -56
	.cfi_offset %r12, -48
	.cfi_offset %r13, -40
	.cfi_offset %r14, -32
	.cfi_offset %r15, -24
	.cfi_offset %rbp, -16
	movl	%edx, 8(%rsp)                   # 4-byte Spill
	movq	%rsi, 24(%rsp)                  # 8-byte Spill
	testl	%edi, %edi
	je	.LBB9_1
# %bb.2:
	movl	%edi, %esi
	movl	%edi, %r14d
	cmpb	$0, verbose(%rip)
	je	.LBB9_4
# %bb.3:
	movl	$.L.str.24, %edi
	xorl	%eax, %eax
	callq	printf
.LBB9_4:
	xorl	%r15d, %r15d
	xorl	%ebp, %ebp
	movq	%r14, 16(%rsp)                  # 8-byte Spill
.LBB9_5:                                # =>This Inner Loop Header: Depth=1
	movq	templateFile(%rip), %rdi
	movl	$Read, %esi
	movl	$500, %edx                      # imm = 0x1F4
	callq	gzgets
	testq	%rax, %rax
	je	.LBB9_17
# %bb.6:                                #   in Loop: Header=BB9_5 Depth=1
	movq	templateFile(%rip), %rdi
	movl	$Read+500, %esi
	movl	$500, %edx                      # imm = 0x1F4
	callq	gzgets
	testq	%rax, %rax
	je	.LBB9_19
# %bb.7:                                #   in Loop: Header=BB9_5 Depth=1
	movq	templateFile(%rip), %rdi
	movl	$Read+1000, %esi
	movl	$500, %edx                      # imm = 0x1F4
	callq	gzgets
	testq	%rax, %rax
	je	.LBB9_19
# %bb.8:                                #   in Loop: Header=BB9_5 Depth=1
	movq	templateFile(%rip), %rdi
	movl	$Read+1500, %esi
	movl	$500, %edx                      # imm = 0x1F4
	callq	gzgets
	testq	%rax, %rax
	je	.LBB9_19
# %bb.9:                                #   in Loop: Header=BB9_5 Depth=1
	movq	24(%rsp), %rax                  # 8-byte Reload
	movzwl	(%rax,%r15,2), %eax
	cmpb	$0, gRNATrimming(%rip)
	je	.LBB9_12
# %bb.10:                               #   in Loop: Header=BB9_5 Depth=1
	testw	%ax, %ax
	jle	.LBB9_15
# %bb.11:                               #   in Loop: Header=BB9_5 Depth=1
	movslq	gRNA_start(%rip), %r14
	movl	%ebp, 12(%rsp)                  # 4-byte Spill
	movzwl	%ax, %ebp
	leaq	(%r14,%rbp), %rsi
	addq	$Read+500, %rsi
	movslq	gRNA_length(%rip), %r13
	leaq	32(%rsp), %rbx
	movq	%rbx, %rdi
	movq	%r13, %rdx
	callq	strncpy
	movl	$Read+500, %edi
	movq	%rbx, %rsi
	movq	%r13, %rdx
	callq	strncpy
	movb	$10, Read+500(%r13)
	leaq	1(%r13), %r12
	movb	$0, Read+501(%r13)
	leaq	(%r14,%rbp), %rsi
	addq	$Read+1500, %rsi
	movl	12(%rsp), %ebp                  # 4-byte Reload
	movq	16(%rsp), %r14                  # 8-byte Reload
	movq	%rbx, %rdi
	movq	%r13, %rdx
	callq	strncpy
	movl	$Read+1500, %edi
	movq	%rbx, %rsi
	movq	%r13, %rdx
	callq	strncpy
	jmp	.LBB9_14
.LBB9_12:                               #   in Loop: Header=BB9_5 Depth=1
	cmpw	8(%rsp), %ax                    # 2-byte Folded Reload
	jl	.LBB9_15
# %bb.13:                               #   in Loop: Header=BB9_5 Depth=1
	movswq	%ax, %r13
	movb	$10, Read+500(%r13)
	leaq	1(%r13), %r12
	movb	$0, Read+501(%r13)
.LBB9_14:                               # %.sink.split
                                        #   in Loop: Header=BB9_5 Depth=1
	movb	$10, Read+1500(%r13)
	movb	$0, Read+1500(%r12)
	movq	outputFile(%rip), %rsi
	movl	$Read, %edi
	callq	fputs@PLT
	movq	outputFile(%rip), %rsi
	movl	$Read+500, %edi
	callq	fputs@PLT
	movq	outputFile(%rip), %rsi
	movl	$Read+1000, %edi
	callq	fputs@PLT
	movq	outputFile(%rip), %rsi
	movl	$Read+1500, %edi
	callq	fputs@PLT
	incl	%ebp
.LBB9_15:                               #   in Loop: Header=BB9_5 Depth=1
	incq	%r15
	cmpq	%r15, %r14
	jne	.LBB9_5
# %bb.16:                               # %.split.loop.exit.loopexit
	movl	%r14d, %r15d
.LBB9_17:                               # %.split.loop.exit
	addl	%ebp, hReadsWritten(%rip)
	jmp	.LBB9_18
.LBB9_1:
	xorl	%r15d, %r15d
.LBB9_18:
	movl	%r15d, %eax
	addq	$536, %rsp                      # imm = 0x218
	.cfi_def_cfa_offset 56
	popq	%rbx
	.cfi_def_cfa_offset 48
	popq	%r12
	.cfi_def_cfa_offset 40
	popq	%r13
	.cfi_def_cfa_offset 32
	popq	%r14
	.cfi_def_cfa_offset 24
	popq	%r15
	.cfi_def_cfa_offset 16
	popq	%rbp
	.cfi_def_cfa_offset 8
	retq
.LBB9_19:
	.cfi_def_cfa_offset 592
	movl	$.Lstr.10, %edi
	callq	puts@PLT
	movl	$255, %edi
	callq	exit
.Lfunc_end9:
	.size	_Z17WriteBlockOfReadsiPKss, .Lfunc_end9-_Z17WriteBlockOfReadsiPKss
	.cfi_endproc
                                        # -- End function
	.globl	_Z10CloseFilesv                 # -- Begin function _Z10CloseFilesv
	.type	_Z10CloseFilesv,@function
_Z10CloseFilesv:                        # @_Z10CloseFilesv
	.cfi_startproc
# %bb.0:
	pushq	%rax
	.cfi_def_cfa_offset 16
	movq	inputFile(%rip), %rdi
	callq	gzclose
	movq	templateFile(%rip), %rdi
	callq	gzclose
	movb	write_gz_output(%rip), %al
	orb	write_pigz_output(%rip), %al
	movq	outputFile(%rip), %rdi
	jne	.LBB10_1
# %bb.2:
	popq	%rax
	.cfi_def_cfa_offset 8
	jmp	fclose                          # TAILCALL
.LBB10_1:
	.cfi_def_cfa_offset 16
	popq	%rax
	.cfi_def_cfa_offset 8
	jmp	pclose                          # TAILCALL
.Lfunc_end10:
	.size	_Z10CloseFilesv, .Lfunc_end10-_Z10CloseFilesv
	.cfi_endproc
                                        # -- End function
	.globl	_Z25Detect_FastQ_Format_PHREDv  # -- Begin function _Z25Detect_FastQ_Format_PHREDv
	.type	_Z25Detect_FastQ_Format_PHREDv,@function
_Z25Detect_FastQ_Format_PHREDv:         # @_Z25Detect_FastQ_Format_PHREDv
	.cfi_startproc
# %bb.0:
	pushq	%rbp
	.cfi_def_cfa_offset 16
	pushq	%r14
	.cfi_def_cfa_offset 24
	pushq	%rbx
	.cfi_def_cfa_offset 32
	.cfi_offset %rbx, -32
	.cfi_offset %r14, -24
	.cfi_offset %rbp, -16
	movl	$input_filename, %edi
	movl	$.L.str.14, %esi
	callq	gzopen
	movq	%rax, inputFile(%rip)
	testq	%rax, %rax
	je	.LBB11_21
# %bb.1:                                # %.preheader.preheader
	movl	$65, %ebp
	movl	$65, %r14d
.LBB11_2:                               # %.preheader
                                        # =>This Loop Header: Depth=1
                                        #     Child Loop BB11_12 Depth 2
	movq	inputFile(%rip), %rdi
	movl	$Read, %esi
	movl	$500, %edx                      # imm = 0x1F4
	callq	gzgets
	testq	%rax, %rax
	sete	%al
	movb	Read(%rip), %cl
	cmpb	$13, %cl
	sete	%dl
	cmpb	$10, %cl
	sete	%bl
	orb	%dl, %bl
	orb	%al, %bl
	jne	.LBB11_18
# %bb.3:                                #   in Loop: Header=BB11_2 Depth=1
	movq	inputFile(%rip), %rdi
	movl	$Read+500, %esi
	movl	$500, %edx                      # imm = 0x1F4
	callq	gzgets
	testq	%rax, %rax
	je	.LBB11_19
# %bb.4:                                #   in Loop: Header=BB11_2 Depth=1
	movq	inputFile(%rip), %rdi
	movl	$Read+1000, %esi
	movl	$500, %edx                      # imm = 0x1F4
	callq	gzgets
	testq	%rax, %rax
	je	.LBB11_19
# %bb.5:                                #   in Loop: Header=BB11_2 Depth=1
	movq	inputFile(%rip), %rdi
	movl	$Read+1500, %esi
	movl	$500, %edx                      # imm = 0x1F4
	callq	gzgets
	testq	%rax, %rax
	je	.LBB11_19
# %bb.6:                                #   in Loop: Header=BB11_2 Depth=1
	cmpb	$0, FastQ_WARNING(%rip)
	jne	.LBB11_10
# %bb.7:                                #   in Loop: Header=BB11_2 Depth=1
	cmpb	$64, Read(%rip)
	jne	.LBB11_9
# %bb.8:                                #   in Loop: Header=BB11_2 Depth=1
	cmpb	$43, Read+1000(%rip)
	je	.LBB11_10
.LBB11_9:                               #   in Loop: Header=BB11_2 Depth=1
	movl	$.Lstr.4, %edi
	xorl	%eax, %eax
	callq	printf
	movb	$1, FastQ_WARNING(%rip)
.LBB11_10:                              #   in Loop: Header=BB11_2 Depth=1
	movl	$Read+500, %edi
	callq	strlen
	decl	%eax
	cwtl
	testl	%eax, %eax
	jle	.LBB11_14
# %bb.11:                               # %.lr.ph.preheader
                                        #   in Loop: Header=BB11_2 Depth=1
	movl	%eax, %eax
	xorl	%ecx, %ecx
.LBB11_12:                              # %.lr.ph
                                        #   Parent Loop BB11_2 Depth=1
                                        # =>  This Inner Loop Header: Depth=2
	movl	%ebp, %edx
	movl	%r14d, %esi
	movsbl	Read+1500(%rcx), %ebp
	cmpl	%ebp, %r14d
	movl	%ebp, %r14d
	cmoval	%esi, %r14d
	cmpl	%ebp, %edx
	cmoval	%esi, %r14d
	cmovbl	%edx, %ebp
	incq	%rcx
	cmpq	%rcx, %rax
	jne	.LBB11_12
# %bb.13:                               # %._crit_edge
                                        #   in Loop: Header=BB11_2 Depth=1
	cmpl	$59, %ebp
	jb	.LBB11_16
.LBB11_14:                              # %._crit_edge.thread
                                        #   in Loop: Header=BB11_2 Depth=1
	cmpl	$81, %r14d
	jb	.LBB11_2
# %bb.15:
	movw	$64, %ax
	jmp	.LBB11_17
.LBB11_16:
	movw	$33, %ax
.LBB11_17:                              # %.loopexit.sink.split
	movw	%ax, PHRED(%rip)
.LBB11_18:                              # %.loopexit
	xorb	$1, %bl
	movq	inputFile(%rip), %rdi
	callq	gzclose
	movl	%ebx, %eax
	popq	%rbx
	.cfi_def_cfa_offset 24
	popq	%r14
	.cfi_def_cfa_offset 16
	popq	%rbp
	.cfi_def_cfa_offset 8
	retq
.LBB11_19:
	.cfi_def_cfa_offset 32
	movl	$.Lstr.13, %edi
	callq	puts@PLT
.LBB11_20:
	movl	$255, %edi
	callq	exit
.LBB11_21:
	movl	$.L.str.27, %edi
	movl	$input_filename, %esi
	xorl	%eax, %eax
	callq	printf
	jmp	.LBB11_20
.Lfunc_end11:
	.size	_Z25Detect_FastQ_Format_PHREDv, .Lfunc_end11-_Z25Detect_FastQ_Format_PHREDv
	.cfi_endproc
                                        # -- End function
	.globl	_Z20PreprocessReadsOnGPUv       # -- Begin function _Z20PreprocessReadsOnGPUv
	.type	_Z20PreprocessReadsOnGPUv,@function
_Z20PreprocessReadsOnGPUv:              # @_Z20PreprocessReadsOnGPUv
	.cfi_startproc
# %bb.0:
	pushq	%rbp
	.cfi_def_cfa_offset 16
	pushq	%r15
	.cfi_def_cfa_offset 24
	pushq	%r14
	.cfi_def_cfa_offset 32
	pushq	%r13
	.cfi_def_cfa_offset 40
	pushq	%r12
	.cfi_def_cfa_offset 48
	pushq	%rbx
	.cfi_def_cfa_offset 56
	subq	$72, %rsp
	.cfi_def_cfa_offset 128
	.cfi_offset %rbx, -56
	.cfi_offset %r12, -48
	.cfi_offset %r13, -40
	.cfi_offset %r14, -32
	.cfi_offset %r15, -24
	.cfi_offset %rbp, -16
	cmpb	$0, verbose(%rip)
	je	.LBB12_2
# %bb.1:
	movl	$.Lstr.14, %edi
	callq	puts@PLT
.LBB12_2:
	movabsq	$4294967552, %rbx               # imm = 0x100000100
	movl	numGPUs(%rip), %eax
	testl	%eax, %eax
	jle	.LBB12_3
# %bb.4:                                # %.lr.ph.preheader
	xorl	%r15d, %r15d
	leaq	3840(%rbx), %rax
	movq	%rax, 16(%rsp)                  # 8-byte Spill
	xorl	%r14d, %r14d
	xorl	%ebx, %ebx
	xorl	%r13d, %r13d
.LBB12_5:                               # %.lr.ph
                                        # =>This Inner Loop Header: Depth=1
	movl	%r15d, 32(%rsp,%r14)
	movl	%r15d, 48(%rsp,%r14)
	testb	$1, %r13b
	jne	.LBB12_60
# %bb.6:                                #   in Loop: Header=BB12_5 Depth=1
	movl	MAX_READS_ON_GPU(%rip), %edi
	movq	hReadLen(,%r14,4), %rsi
	movq	hReadSequence(,%r14,4), %rdx
	movq	hReadQualstr(%r14,%r14), %rcx
	callq	_Z16ReadBlockOfReadsiPsPcS0_
	movl	%eax, %ebp
	movl	%eax, 32(%rsp,%r14)
	cmpl	MAX_READS_ON_GPU(%rip), %eax
	movzbl	%r13b, %r13d
	movl	$1, %eax
	cmovll	%eax, %r13d
	testl	%ebp, %ebp
	je	.LBB12_60
# %bb.7:                                #   in Loop: Header=BB12_5 Depth=1
	movl	device(%r14), %edi
	callq	hipSetDevice
	testl	%eax, %eax
	jne	.LBB12_8
# %bb.10:                               #   in Loop: Header=BB12_5 Depth=1
	cmpb	$0, QualityTrimming(%rip)
	movslq	%ebp, %r12
	je	.LBB12_13
# %bb.11:                               #   in Loop: Header=BB12_5 Depth=1
	movq	dQualArray(%r14,%r14), %rdi
	movq	hReadQualstr(%r14,%r14), %rsi
	movswq	MAX_READ_LENGTH(%rip), %rdx
	imulq	%r12, %rdx
	movq	upload_stream(%r14,%r14), %r8
	movl	$1, %ecx
	callq	hipMemcpyAsync
	testl	%eax, %eax
	jne	.LBB12_12
.LBB12_13:                              #   in Loop: Header=BB12_5 Depth=1
	movq	dIntArray(,%r14,4), %rdi
	movq	hReadLen(,%r14,4), %rsi
	leaq	(%r12,%r12), %r15
	movq	upload_stream(%r14,%r14), %r8
	movq	%r15, %rdx
	movl	$1, %ecx
	callq	hipMemcpyAsync
	testl	%eax, %eax
	jne	.LBB12_14
# %bb.15:                               #   in Loop: Header=BB12_5 Depth=1
	movq	QUAL_COPY_DONE(%r14,%r14), %rdi
	movq	upload_stream(%r14,%r14), %rsi
	callq	hipEventRecord
	testl	%eax, %eax
	jne	.LBB12_16
# %bb.17:                               #   in Loop: Header=BB12_5 Depth=1
	movq	compute_stream(%r14,%r14), %rdi
	movq	QUAL_COPY_DONE(%r14,%r14), %rsi
	xorl	%edx, %edx
	callq	hipStreamWaitEvent
	testl	%eax, %eax
	jne	.LBB12_18
# %bb.19:                               #   in Loop: Header=BB12_5 Depth=1
	cmpb	$0, QualityTrimming(%rip)
	je	.LBB12_26
# %bb.20:                               #   in Loop: Header=BB12_5 Depth=1
	cmpb	$0, verbose(%rip)
	je	.LBB12_22
# %bb.21:                               #   in Loop: Header=BB12_5 Depth=1
	movl	device(%r14), %esi
	movl	$.L.str.30, %edi
	xorl	%eax, %eax
	callq	printf
.LBB12_22:                              #   in Loop: Header=BB12_5 Depth=1
	movq	compute_stream(%r14,%r14), %r9
	movq	16(%rsp), %rdi                  # 8-byte Reload
	movl	$1, %esi
	movabsq	$4294967552, %rdx               # imm = 0x100000100
	movl	$1, %ecx
	xorl	%r8d, %r8d
	callq	__hipPushCallConfiguration
	testl	%eax, %eax
	jne	.LBB12_24
# %bb.23:                               #   in Loop: Header=BB12_5 Depth=1
	movq	dQualArray(%r14,%r14), %rdi
	movq	dIntArray(,%r14,4), %rsi
	movswl	MAX_READ_LENGTH(%rip), %ecx
	movl	%ebp, %edx
	callq	_Z25__device_stub__TrimmQualsPcPsis
.LBB12_24:                              #   in Loop: Header=BB12_5 Depth=1
	callq	hipGetLastError
	testl	%eax, %eax
	jne	.LBB12_25
.LBB12_26:                              #   in Loop: Header=BB12_5 Depth=1
	movq	TrimmQ_DONE(%r14,%r14), %rdi
	movq	compute_stream(%r14,%r14), %rsi
	callq	hipEventRecord
	testl	%eax, %eax
	jne	.LBB12_27
# %bb.28:                               #   in Loop: Header=BB12_5 Depth=1
	movb	AdaptorTrimming(%rip), %al
	orb	gRNATrimming(%rip), %al
	je	.LBB12_31
# %bb.29:                               #   in Loop: Header=BB12_5 Depth=1
	movq	dSequenceArray(%r14,%r14), %rdi
	movq	hReadSequence(,%r14,4), %rsi
	movswq	MAX_READ_LENGTH(%rip), %rax
	imulq	%rax, %r12
	movq	upload_stream(%r14,%r14), %r8
	movq	%r12, %rdx
	movl	$1, %ecx
	callq	hipMemcpyAsync
	testl	%eax, %eax
	jne	.LBB12_30
.LBB12_31:                              #   in Loop: Header=BB12_5 Depth=1
	movq	SEQ_COPY_DONE(%r14,%r14), %rdi
	movq	upload_stream(%r14,%r14), %rsi
	callq	hipEventRecord
	testl	%eax, %eax
	jne	.LBB12_32
# %bb.33:                               #   in Loop: Header=BB12_5 Depth=1
	movq	compute_stream(%r14,%r14), %rdi
	movq	SEQ_COPY_DONE(%r14,%r14), %rsi
	xorl	%edx, %edx
	callq	hipStreamWaitEvent
	testl	%eax, %eax
	jne	.LBB12_34
# %bb.35:                               #   in Loop: Header=BB12_5 Depth=1
	cmpb	$0, gRNATrimming(%rip)
	je	.LBB12_42
# %bb.36:                               #   in Loop: Header=BB12_5 Depth=1
	cmpb	$0, verbose(%rip)
	je	.LBB12_38
# %bb.37:                               #   in Loop: Header=BB12_5 Depth=1
	movl	device(%r14), %esi
	movl	$.L.str.31, %edi
	xorl	%eax, %eax
	callq	printf
.LBB12_38:                              #   in Loop: Header=BB12_5 Depth=1
	movq	compute_stream(%r14,%r14), %r9
	movq	16(%rsp), %rdi                  # 8-byte Reload
	movl	$1, %esi
	movabsq	$4294967552, %rdx               # imm = 0x100000100
	movl	$1, %ecx
	xorl	%r8d, %r8d
	callq	__hipPushCallConfiguration
	testl	%eax, %eax
	jne	.LBB12_40
# %bb.39:                               #   in Loop: Header=BB12_5 Depth=1
	movq	dSequenceArray(%r14,%r14), %rdi
	movq	dIntArray(,%r14,4), %rsi
	movswl	MAX_READ_LENGTH(%rip), %ecx
	movl	%ebp, %edx
	callq	_Z24__device_stub__Find_gRNAPcPsis
.LBB12_40:                              #   in Loop: Header=BB12_5 Depth=1
	callq	hipGetLastError
	testl	%eax, %eax
	je	.LBB12_49
	jmp	.LBB12_41
.LBB12_42:                              #   in Loop: Header=BB12_5 Depth=1
	cmpb	$0, AdaptorTrimming(%rip)
	je	.LBB12_49
# %bb.43:                               #   in Loop: Header=BB12_5 Depth=1
	cmpb	$0, verbose(%rip)
	je	.LBB12_45
# %bb.44:                               #   in Loop: Header=BB12_5 Depth=1
	movl	device(%r14), %esi
	movl	$.L.str.32, %edi
	xorl	%eax, %eax
	callq	printf
.LBB12_45:                              #   in Loop: Header=BB12_5 Depth=1
	movq	compute_stream(%r14,%r14), %r9
	movq	16(%rsp), %rdi                  # 8-byte Reload
	movl	$1, %esi
	movabsq	$4294967552, %rdx               # imm = 0x100000100
	movl	$1, %ecx
	xorl	%r8d, %r8d
	callq	__hipPushCallConfiguration
	testl	%eax, %eax
	jne	.LBB12_47
# %bb.46:                               #   in Loop: Header=BB12_5 Depth=1
	movq	dSequenceArray(%r14,%r14), %rdi
	movq	dIntArray(,%r14,4), %rsi
	movswl	MAX_READ_LENGTH(%rip), %ecx
	movl	%ebp, %edx
	callq	_Z28__device_stub__TrimmAdaptorsPcPsis
.LBB12_47:                              #   in Loop: Header=BB12_5 Depth=1
	callq	hipGetLastError
	testl	%eax, %eax
	jne	.LBB12_48
.LBB12_49:                              #   in Loop: Header=BB12_5 Depth=1
	movq	TrimmA_DONE(%r14,%r14), %rdi
	movq	compute_stream(%r14,%r14), %rsi
	callq	hipEventRecord
	testl	%eax, %eax
	jne	.LBB12_50
# %bb.51:                               #   in Loop: Header=BB12_5 Depth=1
	movq	download_stream(%r14,%r14), %rdi
	movq	TrimmA_DONE(%r14,%r14), %rsi
	xorl	%edx, %edx
	callq	hipStreamWaitEvent
	testl	%eax, %eax
	jne	.LBB12_52
# %bb.53:                               #   in Loop: Header=BB12_5 Depth=1
	movq	hReadLen(,%r14,4), %rdi
	movq	dIntArray(,%r14,4), %rsi
	movq	download_stream(%r14,%r14), %r8
	movq	%r15, %rdx
	movl	$2, %ecx
	callq	hipMemcpyAsync
	testl	%eax, %eax
	jne	.LBB12_54
# %bb.55:                               #   in Loop: Header=BB12_5 Depth=1
	movq	DTH_COPY_DONE(%r14,%r14), %rdi
	movq	download_stream(%r14,%r14), %rsi
	callq	hipEventRecord
	testl	%eax, %eax
	movl	$0, %r15d
	jne	.LBB12_56
# %bb.57:                               #   in Loop: Header=BB12_5 Depth=1
	cmpb	$0, verbose(%rip)
	je	.LBB12_59
# %bb.58:                               #   in Loop: Header=BB12_5 Depth=1
	movl	device(%r14), %esi
	movl	$.L.str.33, %edi
	movl	%ebp, %edx
	xorl	%eax, %eax
	callq	printf
.LBB12_59:                              #   in Loop: Header=BB12_5 Depth=1
	movl	%ebp, 48(%rsp,%r14)
	movl	$0, 32(%rsp,%r14)
.LBB12_60:                              #   in Loop: Header=BB12_5 Depth=1
	incq	%rbx
	movslq	numGPUs(%rip), %rax
	addq	$4, %r14
	cmpq	%rax, %rbx
	jl	.LBB12_5
# %bb.61:
	movabsq	$4294967552, %rbx               # imm = 0x100000100
	jmp	.LBB12_62
.LBB12_3:
	xorl	%r13d, %r13d
.LBB12_62:                              # %.preheader420.preheader
	xorl	%ebp, %ebp
	xorl	%ecx, %ecx
	movl	$1, 24(%rsp)                    # 4-byte Folded Spill
.LBB12_64:                              # %.preheader420
                                        # =>This Loop Header: Depth=1
                                        #     Child Loop BB12_67 Depth 2
                                        #     Child Loop BB12_94 Depth 2
                                        #     Child Loop BB12_127 Depth 2
	movl	24(%rsp), %edx                  # 4-byte Reload
	movl	%ecx, 24(%rsp)                  # 4-byte Spill
	movb	$1, %r12b
	movl	%edx, 28(%rsp)                  # 4-byte Spill
	movl	%edx, %ecx
	movq	%rcx, 16(%rsp)                  # 8-byte Spill
	testb	$1, %r13b
	jne	.LBB12_92
# %bb.65:                               # %.preheader420
                                        #   in Loop: Header=BB12_64 Depth=1
	testl	%eax, %eax
	jle	.LBB12_92
# %bb.66:                               # %.lr.ph618
                                        #   in Loop: Header=BB12_64 Depth=1
	movl	%ebp, 12(%rsp)                  # 4-byte Spill
	movb	$1, %r12b
	movq	16(%rsp), %rax                  # 8-byte Reload
	leaq	(,%rax,8), %rbp
	xorl	%r14d, %r14d
	xorl	%ebx, %ebx
.LBB12_67:                              #   Parent Loop BB12_64 Depth=1
                                        # =>  This Inner Loop Header: Depth=2
	movl	device(%r14), %edi
	callq	hipSetDevice
	testl	%eax, %eax
	jne	.LBB12_68
# %bb.69:                               #   in Loop: Header=BB12_67 Depth=2
	cmpl	$0, 48(%rsp,%r14)
	jle	.LBB12_72
# %bb.70:                               #   in Loop: Header=BB12_67 Depth=2
	movq	TrimmQ_DONE(%r14,%r14), %rdi
	callq	hipEventSynchronize
	testl	%eax, %eax
	jne	.LBB12_71
.LBB12_72:                              #   in Loop: Header=BB12_67 Depth=2
	movl	MAX_READS_ON_GPU(%rip), %edi
	movq	hReadLen(%rbp,%r14,4), %rsi
	movq	hReadSequence(%rbp,%r14,4), %rdx
	movq	hReadQualstr(%r14,%r14), %rcx
	callq	_Z16ReadBlockOfReadsiPsPcS0_
	movl	%eax, %r15d
	movl	%eax, 32(%rsp,%r14)
	cmpl	MAX_READS_ON_GPU(%rip), %eax
	movzbl	%r13b, %r13d
	movl	$1, %eax
	cmovll	%eax, %r13d
	testl	%r15d, %r15d
	je	.LBB12_73
# %bb.74:                               #   in Loop: Header=BB12_67 Depth=2
	cmpb	$0, QualityTrimming(%rip)
	movslq	%r15d, %r12
	je	.LBB12_77
# %bb.75:                               #   in Loop: Header=BB12_67 Depth=2
	movq	dQualArray(%r14,%r14), %rdi
	movq	hReadQualstr(%r14,%r14), %rsi
	movswq	MAX_READ_LENGTH(%rip), %rdx
	imulq	%r12, %rdx
	movq	upload_stream(%r14,%r14), %r8
	movl	$1, %ecx
	callq	hipMemcpyAsync
	testl	%eax, %eax
	jne	.LBB12_76
.LBB12_77:                              #   in Loop: Header=BB12_67 Depth=2
	movq	dIntArray(%rbp,%r14,4), %rdi
	movq	hReadLen(%rbp,%r14,4), %rsi
	addq	%r12, %r12
	movq	upload_stream(%r14,%r14), %r8
	movq	%r12, %rdx
	movl	$1, %ecx
	callq	hipMemcpyAsync
	testl	%eax, %eax
	jne	.LBB12_78
# %bb.79:                               #   in Loop: Header=BB12_67 Depth=2
	movq	QUAL_COPY_DONE(%r14,%r14), %rdi
	movq	upload_stream(%r14,%r14), %rsi
	callq	hipEventRecord
	testl	%eax, %eax
	jne	.LBB12_80
# %bb.81:                               #   in Loop: Header=BB12_67 Depth=2
	movq	compute_stream(%r14,%r14), %rdi
	movq	QUAL_COPY_DONE(%r14,%r14), %rsi
	xorl	%edx, %edx
	callq	hipStreamWaitEvent
	testl	%eax, %eax
	jne	.LBB12_82
# %bb.83:                               #   in Loop: Header=BB12_67 Depth=2
	cmpb	$0, QualityTrimming(%rip)
	je	.LBB12_90
# %bb.84:                               #   in Loop: Header=BB12_67 Depth=2
	cmpb	$0, verbose(%rip)
	je	.LBB12_86
# %bb.85:                               #   in Loop: Header=BB12_67 Depth=2
	movl	device(%r14), %esi
	movl	$.L.str.30, %edi
	xorl	%eax, %eax
	callq	printf
.LBB12_86:                              #   in Loop: Header=BB12_67 Depth=2
	movq	compute_stream(%r14,%r14), %r9
	movabsq	$4294967552, %rdx               # imm = 0x100000100
	leaq	3840(%rdx), %rdi
	movl	$1, %esi
	movl	$1, %ecx
	xorl	%r8d, %r8d
	callq	__hipPushCallConfiguration
	testl	%eax, %eax
	jne	.LBB12_88
# %bb.87:                               #   in Loop: Header=BB12_67 Depth=2
	movq	dQualArray(%r14,%r14), %rdi
	leaq	(,%r14,4), %rax
	movq	16(%rsp), %rcx                  # 8-byte Reload
	movq	dIntArray(%rax,%rcx,8), %rsi
	movswl	MAX_READ_LENGTH(%rip), %ecx
	movl	%r15d, %edx
	callq	_Z25__device_stub__TrimmQualsPcPsis
.LBB12_88:                              #   in Loop: Header=BB12_67 Depth=2
	callq	hipGetLastError
	testl	%eax, %eax
	jne	.LBB12_89
.LBB12_90:                              #   in Loop: Header=BB12_67 Depth=2
	incq	%rbx
	movslq	numGPUs(%rip), %rax
	addq	$4, %r14
	xorl	%r12d, %r12d
	cmpq	%rax, %rbx
	jl	.LBB12_67
	jmp	.LBB12_91
.LBB12_73:                              # %..loopexit419.loopexit_crit_edge
                                        #   in Loop: Header=BB12_64 Depth=1
	movl	numGPUs(%rip), %eax
.LBB12_91:                              #   in Loop: Header=BB12_64 Depth=1
	movabsq	$4294967552, %rbx               # imm = 0x100000100
	movl	12(%rsp), %ebp                  # 4-byte Reload
.LBB12_92:                              # %.loopexit419
                                        #   in Loop: Header=BB12_64 Depth=1
	testl	%eax, %eax
	jle	.LBB12_63
# %bb.93:                               # %.lr.ph625
                                        #   in Loop: Header=BB12_64 Depth=1
	movl	%r12d, 12(%rsp)                 # 4-byte Spill
	movl	%ebp, %r14d
	xorl	%r12d, %r12d
	xorl	%ebp, %ebp
.LBB12_94:                              #   Parent Loop BB12_64 Depth=1
                                        # =>  This Inner Loop Header: Depth=2
	movslq	32(%rsp,%r12), %r15
	testq	%r15, %r15
	jle	.LBB12_125
# %bb.95:                               #   in Loop: Header=BB12_94 Depth=2
	movl	device(%r12), %edi
	callq	hipSetDevice
	testl	%eax, %eax
	jne	.LBB12_96
# %bb.99:                               #   in Loop: Header=BB12_94 Depth=2
	cmpl	$0, 48(%rsp,%r12)
	jle	.LBB12_102
# %bb.100:                              #   in Loop: Header=BB12_94 Depth=2
	movq	TrimmA_DONE(%r12,%r12), %rdi
	callq	hipEventSynchronize
	testl	%eax, %eax
	jne	.LBB12_101
.LBB12_102:                             #   in Loop: Header=BB12_94 Depth=2
	movb	AdaptorTrimming(%rip), %al
	orb	gRNATrimming(%rip), %al
	je	.LBB12_105
# %bb.103:                              #   in Loop: Header=BB12_94 Depth=2
	movq	dSequenceArray(%r12,%r12), %rdi
	movq	16(%rsp), %rax                  # 8-byte Reload
	leaq	(,%rax,8), %rax
	movq	hReadSequence(%rax,%r12,4), %rsi
	movswq	MAX_READ_LENGTH(%rip), %rdx
	imulq	%r15, %rdx
	movq	upload_stream(%r12,%r12), %r8
	movl	$1, %ecx
	callq	hipMemcpyAsync
	testl	%eax, %eax
	jne	.LBB12_104
.LBB12_105:                             #   in Loop: Header=BB12_94 Depth=2
	movq	SEQ_COPY_DONE(%r12,%r12), %rdi
	movq	upload_stream(%r12,%r12), %rsi
	callq	hipEventRecord
	testl	%eax, %eax
	jne	.LBB12_106
# %bb.107:                              #   in Loop: Header=BB12_94 Depth=2
	movq	compute_stream(%r12,%r12), %rdi
	movq	SEQ_COPY_DONE(%r12,%r12), %rsi
	xorl	%edx, %edx
	callq	hipStreamWaitEvent
	testl	%eax, %eax
	jne	.LBB12_108
# %bb.109:                              #   in Loop: Header=BB12_94 Depth=2
	cmpb	$0, gRNATrimming(%rip)
	je	.LBB12_116
# %bb.110:                              #   in Loop: Header=BB12_94 Depth=2
	cmpb	$0, verbose(%rip)
	je	.LBB12_112
# %bb.111:                              #   in Loop: Header=BB12_94 Depth=2
	movl	device(%r12), %esi
	movl	$.L.str.31, %edi
	xorl	%eax, %eax
	callq	printf
.LBB12_112:                             #   in Loop: Header=BB12_94 Depth=2
	movq	compute_stream(%r12,%r12), %r9
	leaq	3840(%rbx), %rdi
	movl	$1, %esi
	movq	%rbx, %rdx
	movl	$1, %ecx
	xorl	%r8d, %r8d
	callq	__hipPushCallConfiguration
	testl	%eax, %eax
	jne	.LBB12_114
# %bb.113:                              #   in Loop: Header=BB12_94 Depth=2
	movq	dSequenceArray(%r12,%r12), %rdi
	movq	16(%rsp), %rax                  # 8-byte Reload
	leaq	(,%rax,8), %rax
	movq	dIntArray(%rax,%r12,4), %rsi
	movswl	MAX_READ_LENGTH(%rip), %ecx
	movl	%r15d, %edx
	callq	_Z24__device_stub__Find_gRNAPcPsis
.LBB12_114:                             #   in Loop: Header=BB12_94 Depth=2
	callq	hipGetLastError
	testl	%eax, %eax
	je	.LBB12_123
	jmp	.LBB12_115
.LBB12_116:                             #   in Loop: Header=BB12_94 Depth=2
	cmpb	$0, AdaptorTrimming(%rip)
	je	.LBB12_123
# %bb.117:                              #   in Loop: Header=BB12_94 Depth=2
	cmpb	$0, verbose(%rip)
	je	.LBB12_119
# %bb.118:                              #   in Loop: Header=BB12_94 Depth=2
	movl	device(%r12), %esi
	movl	$.L.str.32, %edi
	xorl	%eax, %eax
	callq	printf
.LBB12_119:                             #   in Loop: Header=BB12_94 Depth=2
	movq	compute_stream(%r12,%r12), %r9
	leaq	3840(%rbx), %rdi
	movl	$1, %esi
	movq	%rbx, %rdx
	movl	$1, %ecx
	xorl	%r8d, %r8d
	callq	__hipPushCallConfiguration
	testl	%eax, %eax
	jne	.LBB12_121
# %bb.120:                              #   in Loop: Header=BB12_94 Depth=2
	movq	dSequenceArray(%r12,%r12), %rdi
	movq	16(%rsp), %rax                  # 8-byte Reload
	leaq	(,%rax,8), %rax
	movq	dIntArray(%rax,%r12,4), %rsi
	movswl	MAX_READ_LENGTH(%rip), %ecx
	movl	%r15d, %edx
	callq	_Z28__device_stub__TrimmAdaptorsPcPsis
.LBB12_121:                             #   in Loop: Header=BB12_94 Depth=2
	callq	hipGetLastError
	testl	%eax, %eax
	jne	.LBB12_122
.LBB12_123:                             #   in Loop: Header=BB12_94 Depth=2
	movq	TrimmA_DONE(%r12,%r12), %rdi
	movq	compute_stream(%r12,%r12), %rsi
	callq	hipEventRecord
	testl	%eax, %eax
	jne	.LBB12_149
# %bb.124:                              # %._crit_edge
                                        #   in Loop: Header=BB12_94 Depth=2
	movl	numGPUs(%rip), %eax
.LBB12_125:                             #   in Loop: Header=BB12_94 Depth=2
	incq	%rbp
	movslq	%eax, %rcx
	addq	$4, %r12
	cmpq	%rcx, %rbp
	jl	.LBB12_94
# %bb.97:                               # %.preheader
                                        #   in Loop: Header=BB12_64 Depth=1
	testl	%eax, %eax
	movl	%r14d, %ebp
	jle	.LBB12_98
# %bb.126:                              # %.lr.ph629
                                        #   in Loop: Header=BB12_64 Depth=1
	movl	24(%rsp), %ebx                  # 4-byte Reload
	shlq	$3, %rbx
	xorl	%r14d, %r14d
	xorl	%r15d, %r15d
.LBB12_127:                             #   Parent Loop BB12_64 Depth=1
                                        # =>  This Inner Loop Header: Depth=2
	cmpb	$0, verbose(%rip)
	movl	48(%rsp,%r14), %r12d
	je	.LBB12_129
# %bb.128:                              #   in Loop: Header=BB12_127 Depth=2
	movl	$.L.str.34, %edi
	movl	%r15d, %esi
	movl	%r12d, %edx
	xorl	%eax, %eax
	callq	printf
.LBB12_129:                             # %._crit_edge799
                                        #   in Loop: Header=BB12_127 Depth=2
	testl	%r12d, %r12d
	jle	.LBB12_137
# %bb.130:                              #   in Loop: Header=BB12_127 Depth=2
	movl	device(%r14), %edi
	callq	hipSetDevice
	testl	%eax, %eax
	jne	.LBB12_131
# %bb.132:                              #   in Loop: Header=BB12_127 Depth=2
	movq	DTH_COPY_DONE(%r14,%r14), %rdi
	callq	hipEventSynchronize
	testl	%eax, %eax
	jne	.LBB12_133
# %bb.134:                              #   in Loop: Header=BB12_127 Depth=2
	cmpb	$0, verbose(%rip)
	je	.LBB12_136
# %bb.135:                              #   in Loop: Header=BB12_127 Depth=2
	movl	device(%r14), %esi
	movl	$.L.str.35, %edi
	movl	%r15d, %edx
	movl	24(%rsp), %ecx                  # 4-byte Reload
	xorl	%eax, %eax
	callq	printf
.LBB12_136:                             #   in Loop: Header=BB12_127 Depth=2
	movq	hReadLen(%rbx,%r14,4), %rsi
	movswl	MIN_OUT_READ_LEN(%rip), %edx
	movl	%r12d, %edi
	callq	_Z17WriteBlockOfReadsiPKss
	addl	%r12d, %ebp
.LBB12_137:                             #   in Loop: Header=BB12_127 Depth=2
	movl	32(%rsp,%r14), %r12d
	testl	%r12d, %r12d
	jle	.LBB12_146
# %bb.138:                              #   in Loop: Header=BB12_127 Depth=2
	movq	download_stream(%r14,%r14), %rdi
	movq	TrimmA_DONE(%r14,%r14), %rsi
	xorl	%edx, %edx
	callq	hipStreamWaitEvent
	testl	%eax, %eax
	jne	.LBB12_139
# %bb.140:                              #   in Loop: Header=BB12_127 Depth=2
	movq	16(%rsp), %rax                  # 8-byte Reload
	leaq	(,%rax,8), %rax
	movq	hReadLen(%rax,%r14,4), %rdi
	movq	dIntArray(%rax,%r14,4), %rsi
	leaq	(%r12,%r12), %rdx
	movq	download_stream(%r14,%r14), %r8
	movl	$2, %ecx
	callq	hipMemcpyAsync
	testl	%eax, %eax
	jne	.LBB12_141
# %bb.142:                              #   in Loop: Header=BB12_127 Depth=2
	movq	DTH_COPY_DONE(%r14,%r14), %rdi
	movq	download_stream(%r14,%r14), %rsi
	callq	hipEventRecord
	testl	%eax, %eax
	jne	.LBB12_143
# %bb.144:                              #   in Loop: Header=BB12_127 Depth=2
	cmpb	$0, verbose(%rip)
	je	.LBB12_146
# %bb.145:                              #   in Loop: Header=BB12_127 Depth=2
	movl	device(%r14), %esi
	movl	$.L.str.33, %edi
	movl	%r12d, %edx
	xorl	%eax, %eax
	callq	printf
.LBB12_146:                             #   in Loop: Header=BB12_127 Depth=2
	movl	%r12d, 48(%rsp,%r14)
	movl	$0, 32(%rsp,%r14)
	incq	%r15
	movslq	numGPUs(%rip), %rax
	addq	$4, %r14
	cmpq	%rax, %r15
	jl	.LBB12_127
# %bb.147:                              #   in Loop: Header=BB12_64 Depth=1
	movabsq	$4294967552, %rbx               # imm = 0x100000100
.LBB12_98:                              #   in Loop: Header=BB12_64 Depth=1
	movl	12(%rsp), %r12d                 # 4-byte Reload
.LBB12_63:                              # %.loopexit
                                        #   in Loop: Header=BB12_64 Depth=1
	movl	28(%rsp), %ecx                  # 4-byte Reload
	testb	$1, %r12b
	je	.LBB12_64
# %bb.148:
	movl	%ebp, %eax
	addq	$72, %rsp
	.cfi_def_cfa_offset 56
	popq	%rbx
	.cfi_def_cfa_offset 48
	popq	%r12
	.cfi_def_cfa_offset 40
	popq	%r13
	.cfi_def_cfa_offset 32
	popq	%r14
	.cfi_def_cfa_offset 24
	popq	%r15
	.cfi_def_cfa_offset 16
	popq	%rbp
	.cfi_def_cfa_offset 8
	retq
.LBB12_108:
	.cfi_def_cfa_offset 128
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$776, %ecx                      # imm = 0x308
	jmp	.LBB12_9
.LBB12_106:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$774, %ecx                      # imm = 0x306
	jmp	.LBB12_9
.LBB12_149:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$792, %ecx                      # imm = 0x318
	jmp	.LBB12_9
.LBB12_96:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$766, %ecx                      # imm = 0x2FE
	jmp	.LBB12_9
.LBB12_68:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$732, %ecx                      # imm = 0x2DC
	jmp	.LBB12_9
.LBB12_80:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$750, %ecx                      # imm = 0x2EE
	jmp	.LBB12_9
.LBB12_82:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$752, %ecx                      # imm = 0x2F0
	jmp	.LBB12_9
.LBB12_78:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$749, %ecx                      # imm = 0x2ED
	jmp	.LBB12_9
.LBB12_101:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$770, %ecx                      # imm = 0x302
	jmp	.LBB12_9
.LBB12_115:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$781, %ecx                      # imm = 0x30D
	jmp	.LBB12_9
.LBB12_141:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$812, %ecx                      # imm = 0x32C
	jmp	.LBB12_9
.LBB12_139:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$811, %ecx                      # imm = 0x32B
	jmp	.LBB12_9
.LBB12_133:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$803, %ecx                      # imm = 0x323
	jmp	.LBB12_9
.LBB12_131:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$802, %ecx                      # imm = 0x322
	jmp	.LBB12_9
.LBB12_143:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$813, %ecx                      # imm = 0x32D
	jmp	.LBB12_9
.LBB12_104:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$773, %ecx                      # imm = 0x305
	jmp	.LBB12_9
.LBB12_71:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$736, %ecx                      # imm = 0x2E0
	jmp	.LBB12_9
.LBB12_76:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$748, %ecx                      # imm = 0x2EC
	jmp	.LBB12_9
.LBB12_89:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$757, %ecx                      # imm = 0x2F5
	jmp	.LBB12_9
.LBB12_122:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$789, %ecx                      # imm = 0x315
.LBB12_9:
	xorl	%eax, %eax
	callq	fprintf
	movl	$1, %edi
	callq	exit
.LBB12_54:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$713, %ecx                      # imm = 0x2C9
	jmp	.LBB12_9
.LBB12_14:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$679, %ecx                      # imm = 0x2A7
	jmp	.LBB12_9
.LBB12_32:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$692, %ecx                      # imm = 0x2B4
	jmp	.LBB12_9
.LBB12_56:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$714, %ecx                      # imm = 0x2CA
	jmp	.LBB12_9
.LBB12_16:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$680, %ecx                      # imm = 0x2A8
	jmp	.LBB12_9
.LBB12_34:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$694, %ecx                      # imm = 0x2B6
	jmp	.LBB12_9
.LBB12_18:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$682, %ecx                      # imm = 0x2AA
	jmp	.LBB12_9
.LBB12_50:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$710, %ecx                      # imm = 0x2C6
	jmp	.LBB12_9
.LBB12_8:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$676, %ecx                      # imm = 0x2A4
	jmp	.LBB12_9
.LBB12_27:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$689, %ecx                      # imm = 0x2B1
	jmp	.LBB12_9
.LBB12_52:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$712, %ecx                      # imm = 0x2C8
	jmp	.LBB12_9
.LBB12_12:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$678, %ecx                      # imm = 0x2A6
	jmp	.LBB12_9
.LBB12_25:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$687, %ecx                      # imm = 0x2AF
	jmp	.LBB12_9
.LBB12_41:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$699, %ecx                      # imm = 0x2BB
	jmp	.LBB12_9
.LBB12_30:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$691, %ecx                      # imm = 0x2B3
	jmp	.LBB12_9
.LBB12_48:
	movq	stderr(%rip), %rbx
	movl	%eax, %edi
	callq	hipGetErrorString
	movl	$.L.str.1, %esi
	movl	$.L.str.2, %r8d
	movq	%rbx, %rdi
	movq	%rax, %rdx
	movl	$707, %ecx                      # imm = 0x2C3
	jmp	.LBB12_9
.Lfunc_end12:
	.size	_Z20PreprocessReadsOnGPUv, .Lfunc_end12-_Z20PreprocessReadsOnGPUv
	.cfi_endproc
                                        # -- End function
	.globl	_Z10usage_helpv                 # -- Begin function _Z10usage_helpv
	.type	_Z10usage_helpv,@function
_Z10usage_helpv:                        # @_Z10usage_helpv
	.cfi_startproc
# %bb.0:
	pushq	%rax
	.cfi_def_cfa_offset 16
	movl	$.Lstr.15, %edi
	callq	puts@PLT
	movl	$.Lstr.16, %edi
	callq	puts@PLT
	movl	$.Lstr.17, %edi
	callq	puts@PLT
	movl	$.Lstr.18, %edi
	callq	puts@PLT
	movl	$.Lstr.19, %edi
	callq	puts@PLT
	movl	$.Lstr.20, %edi
	callq	puts@PLT
	movl	$.Lstr.21, %edi
	callq	puts@PLT
	movl	$.Lstr.22, %edi
	callq	puts@PLT
	movl	$.Lstr.23, %edi
	callq	puts@PLT
	movl	$.Lstr.24, %edi
	callq	puts@PLT
	movl	$.Lstr.25, %edi
	callq	puts@PLT
	movl	$.Lstr.26, %edi
	callq	puts@PLT
	movl	$.Lstr.27, %edi
	callq	puts@PLT
	movl	$.Lstr.28, %edi
	callq	puts@PLT
	movl	$.Lstr.29, %edi
	callq	puts@PLT
	movl	$.Lstr.30, %edi
	callq	puts@PLT
	movl	$.Lstr.31, %edi
	callq	puts@PLT
	movl	$.Lstr.32, %edi
	callq	puts@PLT
	movl	$.Lstr.33, %edi
	callq	puts@PLT
	movl	$.Lstr.34, %edi
	callq	puts@PLT
	movl	$.Lstr.35, %edi
	callq	puts@PLT
	movl	$.Lstr.36, %edi
	callq	puts@PLT
	movl	$.Lstr.37, %edi
	callq	puts@PLT
	movl	$.Lstr.38, %edi
	callq	puts@PLT
	movl	$.Lstr.39, %edi
	callq	puts@PLT
	movl	$.Lstr.40, %edi
	callq	puts@PLT
	movl	$.Lstr.41, %edi
	callq	puts@PLT
	movl	$.Lstr.42, %edi
	callq	puts@PLT
	movl	$.Lstr.43, %edi
	callq	puts@PLT
	movl	$3, %edi
	callq	exit
.Lfunc_end13:
	.size	_Z10usage_helpv, .Lfunc_end13-_Z10usage_helpv
	.cfi_endproc
                                        # -- End function
	.globl	_Z27invalid_command_line_optionPKc # -- Begin function _Z27invalid_command_line_optionPKc
	.type	_Z27invalid_command_line_optionPKc,@function
_Z27invalid_command_line_optionPKc:     # @_Z27invalid_command_line_optionPKc
	.cfi_startproc
# %bb.0:
	pushq	%rax
	.cfi_def_cfa_offset 16
	movq	%rdi, %rsi
	movl	$.L.str.65, %edi
	xorl	%eax, %eax
	callq	printf
	movl	$.Lstr.44, %edi
	callq	puts@PLT
	callq	_Z10usage_helpv
.Lfunc_end14:
	.size	_Z27invalid_command_line_optionPKc, .Lfunc_end14-_Z27invalid_command_line_optionPKc
	.cfi_endproc
                                        # -- End function
	.globl	_Z25parseCommandLineArgumentsiPPc # -- Begin function _Z25parseCommandLineArgumentsiPPc
	.type	_Z25parseCommandLineArgumentsiPPc,@function
_Z25parseCommandLineArgumentsiPPc:      # @_Z25parseCommandLineArgumentsiPPc
	.cfi_startproc
# %bb.0:
	pushq	%rbp
	.cfi_def_cfa_offset 16
	pushq	%r15
	.cfi_def_cfa_offset 24
	pushq	%r14
	.cfi_def_cfa_offset 32
	pushq	%r13
	.cfi_def_cfa_offset 40
	pushq	%r12
	.cfi_def_cfa_offset 48
	pushq	%rbx
	.cfi_def_cfa_offset 56
	subq	$24, %rsp
	.cfi_def_cfa_offset 80
	.cfi_offset %rbx, -56
	.cfi_offset %r12, -48
	.cfi_offset %r13, -40
	.cfi_offset %r14, -32
	.cfi_offset %r15, -24
	.cfi_offset %rbp, -16
	cmpl	$2, %edi
	jl	.LBB15_121
# %bb.1:                                # %.lr.ph.preheader
	movq	%rsi, %rbx
	movl	%edi, %ebp
	movl	numGPUs(%rip), %eax
	movl	%eax, 12(%rsp)                  # 4-byte Spill
	movl	$1, %r13d
	movzwl	MAX_READ_LENGTH(%rip), %r12d
	xorl	%r14d, %r14d
	movl	$0, 8(%rsp)                     # 4-byte Folded Spill
	movl	$0, 4(%rsp)                     # 4-byte Folded Spill
	movl	$0, (%rsp)                      # 4-byte Folded Spill
	movl	$0, 20(%rsp)                    # 4-byte Folded Spill
	movl	$0, 16(%rsp)                    # 4-byte Folded Spill
.LBB15_2:                               # %.lr.ph
                                        # =>This Inner Loop Header: Depth=1
	movslq	%r13d, %rax
	movq	(%rbx,%rax,8), %r15
	movzbl	(%r15), %eax
	cmpl	$47, %eax
	je	.LBB15_11
# %bb.3:                                # %.lr.ph
                                        #   in Loop: Header=BB15_2 Depth=1
	cmpl	$45, %eax
	jne	.LBB15_116
# %bb.4:                                #   in Loop: Header=BB15_2 Depth=1
	movzbl	1(%r15), %eax
	addl	$-63, %eax
	cmpl	$55, %eax
	ja	.LBB15_117
# %bb.5:                                #   in Loop: Header=BB15_2 Depth=1
	jmpq	*.LJTI15_0(,%rax,8)
.LBB15_6:                               #   in Loop: Header=BB15_2 Depth=1
	testb	$1, (%rsp)                      # 1-byte Folded Reload
	jne	.LBB15_139
# %bb.7:                                #   in Loop: Header=BB15_2 Depth=1
	incl	%r13d
	cmpl	%ebp, %r13d
	jge	.LBB15_140
# %bb.8:                                #   in Loop: Header=BB15_2 Depth=1
	movslq	%r13d, %rax
	movq	(%rbx,%rax,8), %r15
	movq	%r15, %rdi
	callq	strlen
	cmpq	$101, %rax
	jae	.LBB15_142
# %bb.9:                                #   in Loop: Header=BB15_2 Depth=1
	cmpq	$2, %rax
	jbe	.LBB15_141
# %bb.10:                               #   in Loop: Header=BB15_2 Depth=1
	movl	$Adaptor, %edi
	movq	%r15, %rsi
	callq	strcpy
	movb	$1, %al
	movl	%eax, (%rsp)                    # 4-byte Spill
	jmp	.LBB15_85
.LBB15_11:                              #   in Loop: Header=BB15_2 Depth=1
	movzbl	1(%r15), %eax
	cmpl	$103, %eax
	je	.LBB15_17
# %bb.12:                               #   in Loop: Header=BB15_2 Depth=1
	cmpl	$84, %eax
	jne	.LBB15_85
# %bb.13:                               #   in Loop: Header=BB15_2 Depth=1
	movb	%r14b, AdaptorTrimming(%rip)
	movb	%r14b, QualityTrimming(%rip)
	movb	%r14b, gRNATrimming(%rip)
	movq	%r15, %rdi
	callq	strlen
	cmpq	$3, %rax
	jne	.LBB15_118
# %bb.14:                               #   in Loop: Header=BB15_2 Depth=1
	movzbl	2(%r15), %eax
	cmpl	$81, %eax
	je	.LBB15_24
# %bb.15:                               #   in Loop: Header=BB15_2 Depth=1
	cmpl	$65, %eax
	jne	.LBB15_118
# %bb.16:                               #   in Loop: Header=BB15_2 Depth=1
	movb	$1, AdaptorTrimming(%rip)
	jmp	.LBB15_85
.LBB15_17:                              #   in Loop: Header=BB15_2 Depth=1
	movq	%r15, %rdi
	callq	strlen
	cmpq	$5, %rax
	jne	.LBB15_115
# %bb.18:                               #   in Loop: Header=BB15_2 Depth=1
	cmpb	$82, 2(%r15)
	jne	.LBB15_115
# %bb.19:                               #   in Loop: Header=BB15_2 Depth=1
	cmpb	$78, 3(%r15)
	jne	.LBB15_115
# %bb.20:                               #   in Loop: Header=BB15_2 Depth=1
	cmpb	$65, 4(%r15)
	jne	.LBB15_115
# %bb.21:                               #   in Loop: Header=BB15_2 Depth=1
	movb	$1, gRNATrimming(%rip)
	leal	1(%r13), %eax
	cmpl	%ebp, %eax
	jge	.LBB15_119
# %bb.22:                               #   in Loop: Header=BB15_2 Depth=1
	cltq
	movq	(%rbx,%rax,8), %rdi
	callq	atoi
	movl	%eax, gRNA_start(%rip)
	addl	$2, %r13d
	cmpl	%ebp, %r13d
	jge	.LBB15_120
# %bb.23:                               #   in Loop: Header=BB15_2 Depth=1
	movslq	%r13d, %rax
	movq	(%rbx,%rax,8), %rdi
	callq	atoi
	movl	%eax, gRNA_length(%rip)
	jmp	.LBB15_85
.LBB15_24:                              #   in Loop: Header=BB15_2 Depth=1
	movb	$1, QualityTrimming(%rip)
	jmp	.LBB15_85
.LBB15_25:                              #   in Loop: Header=BB15_2 Depth=1
	movl	$.L.str.93, %esi
	movq	%r15, %rdi
	callq	strcmp
	testl	%eax, %eax
	je	.LBB15_70
# %bb.26:                               #   in Loop: Header=BB15_2 Depth=1
	movl	$.L.str.94, %esi
	movq	%r15, %rdi
	callq	strcmp
	testl	%eax, %eax
	je	.LBB15_70
# %bb.27:                               #   in Loop: Header=BB15_2 Depth=1
	movl	$.L.str.97, %esi
	movq	%r15, %rdi
	callq	strcmp
	testl	%eax, %eax
	je	.LBB15_29
# %bb.28:                               #   in Loop: Header=BB15_2 Depth=1
	movl	$.L.str.98, %esi
	movq	%r15, %rdi
	callq	strcmp
	testl	%eax, %eax
	jne	.LBB15_85
.LBB15_29:                              #   in Loop: Header=BB15_2 Depth=1
	incl	%r13d
	cmpl	%ebp, %r13d
	jge	.LBB15_143
# %bb.30:                               #   in Loop: Header=BB15_2 Depth=1
	movslq	%r13d, %rax
	movq	(%rbx,%rax,8), %rdi
	callq	atoi
                                        # kill: def $eax killed $eax def $rax
	leal	-65(%rax), %ecx
	cmpl	$-56, %ecx
	jbe	.LBB15_147
# %bb.31:                               #   in Loop: Header=BB15_2 Depth=1
	movw	%ax, MIN_QUAL_AFTER_BAD(%rip)
	jmp	.LBB15_85
.LBB15_32:                              #   in Loop: Header=BB15_2 Depth=1
	movl	$.L.str.87, %esi
	movq	%r15, %rdi
	callq	strcmp
	testl	%eax, %eax
	je	.LBB15_73
# %bb.33:                               #   in Loop: Header=BB15_2 Depth=1
	movl	$.L.str.88, %esi
	movq	%r15, %rdi
	callq	strcmp
	testl	%eax, %eax
	je	.LBB15_73
# %bb.34:                               #   in Loop: Header=BB15_2 Depth=1
	cmpb	$104, 2(%r15)
	jne	.LBB15_117
# %bb.35:                               #   in Loop: Header=BB15_2 Depth=1
	cmpb	$114, 3(%r15)
	jne	.LBB15_117
# %bb.36:                               #   in Loop: Header=BB15_2 Depth=1
	cmpb	$101, 4(%r15)
	jne	.LBB15_117
# %bb.37:                               #   in Loop: Header=BB15_2 Depth=1
	cmpb	$100, 5(%r15)
	jne	.LBB15_117
# %bb.38:                               #   in Loop: Header=BB15_2 Depth=1
	incl	%r13d
	cmpl	%ebp, %r13d
	jge	.LBB15_146
# %bb.39:                               #   in Loop: Header=BB15_2 Depth=1
	movslq	%r13d, %rax
	movq	(%rbx,%rax,8), %r15
	movl	$.L.str.89, %esi
	movq	%r15, %rdi
	callq	strcmp
	testl	%eax, %eax
	je	.LBB15_84
# %bb.40:                               #   in Loop: Header=BB15_2 Depth=1
	movl	$.L.str.90, %esi
	movq	%r15, %rdi
	callq	strcmp
	testl	%eax, %eax
	je	.LBB15_84
# %bb.41:                               #   in Loop: Header=BB15_2 Depth=1
	movq	%r15, %rdi
	callq	atoi
	cmpl	$101, %eax
	jae	.LBB15_148
# %bb.42:                               #   in Loop: Header=BB15_2 Depth=1
	movw	%ax, PHRED(%rip)
	jmp	.LBB15_85
.LBB15_43:                              #   in Loop: Header=BB15_2 Depth=1
	cmpb	$101, 2(%r15)
	jne	.LBB15_117
# %bb.44:                               #   in Loop: Header=BB15_2 Depth=1
	cmpb	$118, 3(%r15)
	jne	.LBB15_117
# %bb.45:                               #   in Loop: Header=BB15_2 Depth=1
	cmpl	$4, 12(%rsp)                    # 4-byte Folded Reload
	jge	.LBB15_138
# %bb.46:                               #   in Loop: Header=BB15_2 Depth=1
	incl	%r13d
	cmpl	%ebp, %r13d
	jge	.LBB15_136
# %bb.47:                               #   in Loop: Header=BB15_2 Depth=1
	movslq	%r13d, %rax
	movq	(%rbx,%rax,8), %rdi
	callq	atoi
	cmpl	$21, %eax
	jae	.LBB15_137
# %bb.48:                               #   in Loop: Header=BB15_2 Depth=1
	movl	12(%rsp), %edx                  # 4-byte Reload
	movslq	%edx, %rcx
	movl	%eax, device(,%rcx,4)
	incl	%edx
	movl	%edx, 12(%rsp)                  # 4-byte Spill
	movl	%edx, numGPUs(%rip)
	jmp	.LBB15_85
.LBB15_49:                              #   in Loop: Header=BB15_2 Depth=1
	testb	$1, 8(%rsp)                     # 1-byte Folded Reload
	jne	.LBB15_133
# %bb.50:                               #   in Loop: Header=BB15_2 Depth=1
	incl	%r13d
	cmpl	%ebp, %r13d
	jge	.LBB15_134
# %bb.51:                               #   in Loop: Header=BB15_2 Depth=1
	movslq	%r13d, %rax
	movq	(%rbx,%rax,8), %r15
	movq	%r15, %rdi
	callq	strlen
	cmpq	$401, %rax                      # imm = 0x191
	jae	.LBB15_135
# %bb.52:                               #   in Loop: Header=BB15_2 Depth=1
	movl	$input_filename, %edi
	movq	%r15, %rsi
	callq	strcpy
	movb	$1, %al
	movl	%eax, 8(%rsp)                   # 4-byte Spill
	jmp	.LBB15_85
.LBB15_53:                              #   in Loop: Header=BB15_2 Depth=1
	cmpb	$101, 2(%r15)
	jne	.LBB15_117
# %bb.54:                               #   in Loop: Header=BB15_2 Depth=1
	cmpb	$110, 3(%r15)
	jne	.LBB15_117
# %bb.55:                               #   in Loop: Header=BB15_2 Depth=1
	testb	$1, 16(%rsp)                    # 1-byte Folded Reload
	jne	.LBB15_130
# %bb.56:                               #   in Loop: Header=BB15_2 Depth=1
	incl	%r13d
	cmpl	%ebp, %r13d
	jge	.LBB15_131
# %bb.57:                               #   in Loop: Header=BB15_2 Depth=1
	movslq	%r13d, %rax
	movq	(%rbx,%rax,8), %rdi
	callq	atoi
	testl	%eax, %eax
	js	.LBB15_132
# %bb.58:                               #   in Loop: Header=BB15_2 Depth=1
	movswl	%r12w, %ecx
	cmpl	%ecx, %eax
	jg	.LBB15_132
# %bb.59:                               #   in Loop: Header=BB15_2 Depth=1
	movw	%ax, MIN_OUT_READ_LEN(%rip)
	movb	$1, %al
	movl	%eax, 16(%rsp)                  # 4-byte Spill
	jmp	.LBB15_85
.LBB15_60:                              #   in Loop: Header=BB15_2 Depth=1
	movb	$1, verbose(%rip)
	jmp	.LBB15_85
.LBB15_61:                              #   in Loop: Header=BB15_2 Depth=1
	testb	$1, 4(%rsp)                     # 1-byte Folded Reload
	jne	.LBB15_124
# %bb.62:                               #   in Loop: Header=BB15_2 Depth=1
	incl	%r13d
	cmpl	%ebp, %r13d
	jge	.LBB15_125
# %bb.63:                               #   in Loop: Header=BB15_2 Depth=1
	movslq	%r13d, %rax
	movq	(%rbx,%rax,8), %r15
	movq	%r15, %rdi
	callq	strlen
	cmpq	$401, %rax                      # imm = 0x191
	jae	.LBB15_126
# %bb.64:                               #   in Loop: Header=BB15_2 Depth=1
	movl	$output_filename, %edi
	movq	%r15, %rsi
	callq	strcpy
	movb	$1, %al
	movl	%eax, 4(%rsp)                   # 4-byte Spill
	jmp	.LBB15_85
.LBB15_65:                              #   in Loop: Header=BB15_2 Depth=1
	movzbl	2(%r15), %eax
	orl	$32, %eax
	cmpl	$109, %eax
	jne	.LBB15_117
# %bb.66:                               #   in Loop: Header=BB15_2 Depth=1
	testb	$1, 20(%rsp)                    # 1-byte Folded Reload
	jne	.LBB15_127
# %bb.67:                               #   in Loop: Header=BB15_2 Depth=1
	incl	%r13d
	cmpl	%ebp, %r13d
	jge	.LBB15_128
# %bb.68:                               #   in Loop: Header=BB15_2 Depth=1
	movslq	%r13d, %rax
	movq	(%rbx,%rax,8), %rdi
	callq	atoi
	cmpl	$21, %eax
	jge	.LBB15_129
# %bb.69:                               #   in Loop: Header=BB15_2 Depth=1
	movw	%ax, mismatches(%rip)
	movb	$1, %al
	movl	%eax, 20(%rsp)                  # 4-byte Spill
	jmp	.LBB15_85
.LBB15_70:                              #   in Loop: Header=BB15_2 Depth=1
	incl	%r13d
	cmpl	%ebp, %r13d
	jge	.LBB15_143
# %bb.71:                               #   in Loop: Header=BB15_2 Depth=1
	movslq	%r13d, %rax
	movq	(%rbx,%rax,8), %rdi
	callq	atoi
                                        # kill: def $eax killed $eax def $rax
	leal	-65(%rax), %ecx
	cmpl	$-56, %ecx
	jbe	.LBB15_145
# %bb.72:                               #   in Loop: Header=BB15_2 Depth=1
	movw	%ax, MIN_BASE_QUAL(%rip)
	jmp	.LBB15_85
.LBB15_73:                              #   in Loop: Header=BB15_2 Depth=1
	movb	$1, write_pigz_output(%rip)
	jmp	.LBB15_85
.LBB15_74:                              #   in Loop: Header=BB15_2 Depth=1
	incl	%r13d
	cmpl	%ebp, %r13d
	jge	.LBB15_117
# %bb.75:                               #   in Loop: Header=BB15_2 Depth=1
	movslq	%r13d, %rax
	movq	(%rbx,%rax,8), %rdi
	callq	atoi
	movl	%eax, %r12d
	movl	$-10001, %ecx                   # imm = 0xD8EF
	leal	(%r12,%rcx), %eax
	cmpl	%ecx, %eax
	jbe	.LBB15_117
# %bb.76:                               #   in Loop: Header=BB15_2 Depth=1
	movw	%r12w, MAX_READ_LENGTH(%rip)
	jmp	.LBB15_85
.LBB15_77:                              #   in Loop: Header=BB15_2 Depth=1
	cmpb	$122, 2(%r15)
	jne	.LBB15_117
# %bb.78:                               #   in Loop: Header=BB15_2 Depth=1
	movq	%r15, %rdi
	callq	strlen
	cmpq	$3, %rax
	jne	.LBB15_117
# %bb.79:                               #   in Loop: Header=BB15_2 Depth=1
	movb	$1, write_gz_output(%rip)
	jmp	.LBB15_85
.LBB15_80:                              #   in Loop: Header=BB15_2 Depth=1
	incl	%r13d
	cmpl	%ebp, %r13d
	jge	.LBB15_117
# %bb.81:                               #   in Loop: Header=BB15_2 Depth=1
	movslq	%r13d, %rax
	movq	(%rbx,%rax,8), %rdi
	callq	atoi
	testl	%eax, %eax
	jle	.LBB15_117
# %bb.82:                               #   in Loop: Header=BB15_2 Depth=1
	movl	%eax, MAX_READS_ON_GPU(%rip)
	jmp	.LBB15_85
.LBB15_83:                              #   in Loop: Header=BB15_2 Depth=1
	movb	$1, overwrite_outputfile(%rip)
	jmp	.LBB15_85
.LBB15_84:                              #   in Loop: Header=BB15_2 Depth=1
	movb	$1, auto_phred_detect(%rip)
.LBB15_85:                              #   in Loop: Header=BB15_2 Depth=1
	incl	%r13d
	cmpl	%ebp, %r13d
	jl	.LBB15_2
# %bb.86:                               # %._crit_edge
	testb	$1, 8(%rsp)                     # 1-byte Folded Reload
	je	.LBB15_121
# %bb.87:                               # %._crit_edge
	movl	4(%rsp), %eax                   # 4-byte Reload
	andb	$1, %al
	je	.LBB15_121
# %bb.88:
	movb	AdaptorTrimming(%rip), %al
	orb	gRNATrimming(%rip), %al
	je	.LBB15_90
# %bb.89:
	movl	(%rsp), %eax                    # 4-byte Reload
	andb	$1, %al
	je	.LBB15_121
.LBB15_90:
	movl	$input_filename, %edi
	movl	$output_filename, %esi
	callq	strcmp
	testl	%eax, %eax
	je	.LBB15_144
# %bb.91:
	movl	$.Lstr.45, %edi
	callq	puts@PLT
	movl	$.L.str.109, %edi
	movl	$input_filename, %esi
	xorl	%eax, %eax
	callq	printf
	movl	$.L.str.110, %edi
	movl	$output_filename, %esi
	xorl	%eax, %eax
	callq	printf
	movb	AdaptorTrimming(%rip), %al
	orb	gRNATrimming(%rip), %al
	je	.LBB15_93
# %bb.92:
	movl	$.L.str.111, %edi
	movl	$Adaptor, %esi
	xorl	%eax, %eax
	callq	printf
.LBB15_93:
	cmpb	$0, verbose(%rip)
	je	.LBB15_109
# %bb.94:
	movb	AdaptorTrimming(%rip), %al
	orb	gRNATrimming(%rip), %al
	je	.LBB15_96
# %bb.95:
	movswl	mismatches(%rip), %esi
	movl	$.L.str.112, %edi
	xorl	%eax, %eax
	callq	printf
.LBB15_96:
	movl	$.L.str.113, %edi
	xorl	%eax, %eax
	callq	printf
	cmpb	$0, QualityTrimming(%rip)
	je	.LBB15_98
# %bb.97:
	movl	$.L.str.114, %edi
	xorl	%eax, %eax
	callq	printf
.LBB15_98:
	cmpb	$0, AdaptorTrimming(%rip)
	je	.LBB15_100
# %bb.99:
	movl	$.L.str.115, %edi
	xorl	%eax, %eax
	callq	printf
.LBB15_100:
	cmpb	$0, gRNATrimming(%rip)
	je	.LBB15_102
# %bb.101:
	movl	$.L.str.116, %edi
	xorl	%eax, %eax
	callq	printf
.LBB15_102:
	movl	$10, %edi
	callq	putchar@PLT
	cmpb	$0, QualityTrimming(%rip)
	je	.LBB15_104
# %bb.103:
	movswl	MIN_BASE_QUAL(%rip), %esi
	movswl	MIN_QUAL_AFTER_BAD(%rip), %edx
	movl	$.L.str.117, %edi
	xorl	%eax, %eax
	callq	printf
.LBB15_104:
	movl	$.L.str.118, %edi
	xorl	%eax, %eax
	callq	printf
	cmpb	$0, auto_phred_detect(%rip)
	je	.LBB15_106
# %bb.105:
	movl	$.Lstr.46, %edi
	callq	puts@PLT
	jmp	.LBB15_107
.LBB15_106:
	movswl	PHRED(%rip), %esi
	movl	$.L.str.119, %edi
	xorl	%eax, %eax
	callq	printf
.LBB15_107:
	movswl	MAX_READ_LENGTH(%rip), %esi
	movl	$.L.str.121, %edi
	xorl	%eax, %eax
	callq	printf
	movswl	MIN_OUT_READ_LEN(%rip), %esi
	movl	$.L.str.122, %edi
	xorl	%eax, %eax
	callq	printf
	cmpb	$0, overwrite_outputfile(%rip)
	je	.LBB15_109
# %bb.108:
	movl	$.Lstr.47, %edi
	callq	puts@PLT
.LBB15_109:
	cmpl	$0, numGPUs(%rip)
	jle	.LBB15_114
# %bb.110:
	movl	$.L.str.124, %edi
	xorl	%eax, %eax
	callq	printf
	cmpl	$0, numGPUs(%rip)
	jle	.LBB15_113
# %bb.111:                              # %.lr.ph482.preheader
	xorl	%ebx, %ebx
.LBB15_112:                             # %.lr.ph482
                                        # =>This Inner Loop Header: Depth=1
	movl	device(,%rbx,4), %esi
	movl	$.L.str.125, %edi
	xorl	%eax, %eax
	callq	printf
	incq	%rbx
	movslq	numGPUs(%rip), %rax
	cmpq	%rax, %rbx
	jl	.LBB15_112
.LBB15_113:                             # %._crit_edge483
	movl	$10, %edi
	addq	$24, %rsp
	.cfi_def_cfa_offset 56
	popq	%rbx
	.cfi_def_cfa_offset 48
	popq	%r12
	.cfi_def_cfa_offset 40
	popq	%r13
	.cfi_def_cfa_offset 32
	popq	%r14
	.cfi_def_cfa_offset 24
	popq	%r15
	.cfi_def_cfa_offset 16
	popq	%rbp
	.cfi_def_cfa_offset 8
	jmp	putchar@PLT                     # TAILCALL
.LBB15_114:
	.cfi_def_cfa_offset 80
	addq	$24, %rsp
	.cfi_def_cfa_offset 56
	popq	%rbx
	.cfi_def_cfa_offset 48
	popq	%r12
	.cfi_def_cfa_offset 40
	popq	%r13
	.cfi_def_cfa_offset 32
	popq	%r14
	.cfi_def_cfa_offset 24
	popq	%r15
	.cfi_def_cfa_offset 16
	popq	%rbp
	.cfi_def_cfa_offset 8
	retq
.LBB15_115:
	.cfi_def_cfa_offset 80
	movl	$.L.str.65, %edi
	movl	$.L.str.104, %esi
	jmp	.LBB15_149
.LBB15_116:
	movl	$.L.str.65, %edi
	movl	$.L.str.105, %esi
	jmp	.LBB15_149
.LBB15_117:
	movl	$.L.str.65, %edi
	movl	$.L.str.73, %esi
	jmp	.LBB15_149
.LBB15_118:
	movl	$.L.str.65, %edi
	movl	$.L.str.101, %esi
	jmp	.LBB15_149
.LBB15_119:
	movl	$.L.str.65, %edi
	movl	$.L.str.102, %esi
	jmp	.LBB15_149
.LBB15_120:
	movl	$.L.str.65, %edi
	movl	$.L.str.103, %esi
	jmp	.LBB15_149
.LBB15_121:                             # %._crit_edge.thread
	movl	$.L.str.65, %edi
	movl	$.L.str.106, %esi
	jmp	.LBB15_149
.LBB15_122:
	movl	$.Lstr.49, %edi
	jmp	.LBB15_123
.LBB15_124:
	movl	$.L.str.65, %edi
	movl	$.L.str.70, %esi
	jmp	.LBB15_149
.LBB15_125:
	movl	$.L.str.65, %edi
	movl	$.L.str.72, %esi
	jmp	.LBB15_149
.LBB15_126:
	movl	$.L.str.65, %edi
	movl	$.L.str.71, %esi
	jmp	.LBB15_149
.LBB15_127:
	movl	$.L.str.65, %edi
	movl	$.L.str.81, %esi
	jmp	.LBB15_149
.LBB15_128:
	movl	$.L.str.65, %edi
	movl	$.L.str.83, %esi
	jmp	.LBB15_149
.LBB15_129:
	movl	$.L.str.65, %edi
	movl	$.L.str.82, %esi
	jmp	.LBB15_149
.LBB15_130:
	movl	$.L.str.65, %edi
	movl	$.L.str.74, %esi
	jmp	.LBB15_149
.LBB15_131:
	movl	$.L.str.65, %edi
	movl	$.L.str.76, %esi
	jmp	.LBB15_149
.LBB15_132:
	movl	$.L.str.65, %edi
	movl	$.L.str.75, %esi
	jmp	.LBB15_149
.LBB15_133:
	movl	$.L.str.65, %edi
	movl	$.L.str.67, %esi
	jmp	.LBB15_149
.LBB15_134:
	movl	$.L.str.65, %edi
	movl	$.L.str.69, %esi
	jmp	.LBB15_149
.LBB15_135:
	movl	$.L.str.65, %edi
	movl	$.L.str.68, %esi
	jmp	.LBB15_149
.LBB15_136:
	movl	$.L.str.65, %edi
	movl	$.L.str.86, %esi
	jmp	.LBB15_149
.LBB15_137:
	movl	$.L.str.65, %edi
	movl	$.L.str.85, %esi
	jmp	.LBB15_149
.LBB15_138:
	movl	$.L.str.65, %edi
	movl	$.L.str.84, %esi
	jmp	.LBB15_149
.LBB15_139:
	movl	$.L.str.65, %edi
	movl	$.L.str.77, %esi
	jmp	.LBB15_149
.LBB15_140:
	movl	$.L.str.65, %edi
	movl	$.L.str.80, %esi
	jmp	.LBB15_149
.LBB15_141:
	movl	$.L.str.65, %edi
	movl	$.L.str.79, %esi
	jmp	.LBB15_149
.LBB15_142:
	movl	$.L.str.65, %edi
	movl	$.L.str.78, %esi
	jmp	.LBB15_149
.LBB15_143:
	movl	$.L.str.65, %edi
	movl	$.L.str.96, %esi
	jmp	.LBB15_149
.LBB15_144:
	movl	$.Lstr.48, %edi
	callq	puts@PLT
	movl	$253, %edi
	callq	exit
.LBB15_145:
	movl	$.L.str.65, %edi
	movl	$.L.str.95, %esi
	jmp	.LBB15_149
.LBB15_146:
	movl	$.L.str.65, %edi
	movl	$.L.str.92, %esi
	jmp	.LBB15_149
.LBB15_147:
	movl	$.L.str.65, %edi
	movl	$.L.str.99, %esi
	jmp	.LBB15_149
.LBB15_148:
	movl	$.L.str.65, %edi
	movl	$.L.str.91, %esi
.LBB15_149:
	xorl	%eax, %eax
	callq	printf
	movl	$.Lstr.44, %edi
.LBB15_123:
	callq	puts@PLT
	callq	_Z10usage_helpv
.Lfunc_end15:
	.size	_Z25parseCommandLineArgumentsiPPc, .Lfunc_end15-_Z25parseCommandLineArgumentsiPPc
	.cfi_endproc
	.section	.rodata,"a",@progbits
	.p2align	3, 0x0
.LJTI15_0:
	.quad	.LBB15_122
	.quad	.LBB15_117
	.quad	.LBB15_6
	.quad	.LBB15_117
	.quad	.LBB15_117
	.quad	.LBB15_43
	.quad	.LBB15_117
	.quad	.LBB15_117
	.quad	.LBB15_80
	.quad	.LBB15_122
	.quad	.LBB15_49
	.quad	.LBB15_117
	.quad	.LBB15_117
	.quad	.LBB15_53
	.quad	.LBB15_65
	.quad	.LBB15_117
	.quad	.LBB15_61
	.quad	.LBB15_32
	.quad	.LBB15_25
	.quad	.LBB15_74
	.quad	.LBB15_117
	.quad	.LBB15_117
	.quad	.LBB15_117
	.quad	.LBB15_60
	.quad	.LBB15_117
	.quad	.LBB15_117
	.quad	.LBB15_117
	.quad	.LBB15_117
	.quad	.LBB15_117
	.quad	.LBB15_117
	.quad	.LBB15_117
	.quad	.LBB15_117
	.quad	.LBB15_117
	.quad	.LBB15_117
	.quad	.LBB15_6
	.quad	.LBB15_117
	.quad	.LBB15_117
	.quad	.LBB15_43
	.quad	.LBB15_117
	.quad	.LBB15_83
	.quad	.LBB15_77
	.quad	.LBB15_122
	.quad	.LBB15_49
	.quad	.LBB15_117
	.quad	.LBB15_117
	.quad	.LBB15_53
	.quad	.LBB15_65
	.quad	.LBB15_117
	.quad	.LBB15_61
	.quad	.LBB15_32
	.quad	.LBB15_25
	.quad	.LBB15_117
	.quad	.LBB15_117
	.quad	.LBB15_117
	.quad	.LBB15_117
	.quad	.LBB15_60
                                        # -- End function
	.text
	.globl	main                            # -- Begin function main
	.type	main,@function
main:                                   # @main
	.cfi_startproc
# %bb.0:
	pushq	%rbp
	.cfi_def_cfa_offset 16
	pushq	%r14
	.cfi_def_cfa_offset 24
	pushq	%rbx
	.cfi_def_cfa_offset 32
	.cfi_offset %rbx, -32
	.cfi_offset %r14, -24
	.cfi_offset %rbp, -16
	movq	%rsi, %r14
	movl	%edi, %ebp
	xorl	%edi, %edi
	callq	time
	movq	%rax, %rbx
	movl	%ebp, %edi
	movq	%r14, %rsi
	callq	_Z25parseCommandLineArgumentsiPPc
	cmpl	$0, numGPUs(%rip)
	jne	.LBB16_5
# %bb.1:
	callq	_Z8FindGPUsv
	testl	%eax, %eax
	je	.LBB16_12
# %bb.2:
	movl	numGPUs(%rip), %esi
	cmpl	$1, %esi
	jne	.LBB16_4
# %bb.3:
	movl	$.Lstr.50, %edi
	callq	puts@PLT
	jmp	.LBB16_5
.LBB16_4:
	movl	$.L.str.128, %edi
	xorl	%eax, %eax
	callq	printf
.LBB16_5:
	cmpb	$0, auto_phred_detect(%rip)
	je	.LBB16_9
# %bb.6:
	callq	_Z25Detect_FastQ_Format_PHREDv
	testb	%al, %al
	je	.LBB16_13
# %bb.7:
	cmpb	$0, verbose(%rip)
	je	.LBB16_9
# %bb.8:
	movswl	PHRED(%rip), %esi
	movl	$.L.str.129, %edi
	xorl	%eax, %eax
	callq	printf
.LBB16_9:
	callq	_Z9OpenFilesv
	callq	_Z8InitGPUsv
	movswl	mismatches(%rip), %esi
	movswl	PHRED(%rip), %edx
	movswl	MIN_BASE_QUAL(%rip), %ecx
	movswl	MIN_QUAL_AFTER_BAD(%rip), %r8d
	movl	$Adaptor, %edi
	callq	_Z18SetAdaptorSequencePKcssss
	callq	_Z20PreprocessReadsOnGPUv
	movl	$.L.str.131, %edi
	movl	%eax, %esi
	xorl	%eax, %eax
	callq	printf
	movl	hNumberOfReads(%rip), %edx
	movl	$.L.str.132, %edi
	movl	$input_filename, %esi
	xorl	%eax, %eax
	callq	printf
	movl	hReadsWritten(%rip), %edx
	movl	$.L.str.133, %edi
	movl	$output_filename, %esi
	xorl	%eax, %eax
	callq	printf
	cmpb	$0, FastQ_WARNING(%rip)
	je	.LBB16_11
# %bb.10:
	movl	$.L.str.134, %edi
	movl	$input_filename, %esi
	xorl	%eax, %eax
	callq	printf
.LBB16_11:
	callq	_Z10CloseFilesv
	callq	_Z8FreeGPUsv
	xorl	%edi, %edi
	callq	time
	movq	%rax, %rdi
	movq	%rbx, %rsi
	callq	difftime
	movl	$.L.str.135, %edi
	movb	$1, %al
	callq	printf
	xorl	%eax, %eax
	popq	%rbx
	.cfi_def_cfa_offset 24
	popq	%r14
	.cfi_def_cfa_offset 16
	popq	%rbp
	.cfi_def_cfa_offset 8
	retq
.LBB16_13:
	.cfi_def_cfa_offset 32
	movl	$.Lstr.51, %edi
	callq	puts@PLT
	movl	$32, %edi
	callq	exit
.LBB16_12:
	movl	$.Lstr.52, %edi
	callq	puts@PLT
	movl	$1, %edi
	callq	exit
.Lfunc_end16:
	.size	main, .Lfunc_end16-main
	.cfi_endproc
                                        # -- End function
	.p2align	4, 0x90                         # -- Begin function __hip_module_ctor
	.type	__hip_module_ctor,@function
__hip_module_ctor:                      # @__hip_module_ctor
	.cfi_startproc
# %bb.0:
	pushq	%rbx
	.cfi_def_cfa_offset 16
	.cfi_offset %rbx, -16
	movq	__hip_gpubin_handle(%rip), %rbx
	testq	%rbx, %rbx
	jne	.LBB17_2
# %bb.1:
	movl	$__hip_fatbin_wrapper, %edi
	callq	__hipRegisterFatBinary
	movq	%rax, %rbx
	movq	%rax, __hip_gpubin_handle(%rip)
.LBB17_2:
	subq	$32, %rsp
	.cfi_adjust_cfa_offset 32
	xorps	%xmm0, %xmm0
	movups	%xmm0, 16(%rsp)
	movups	%xmm0, (%rsp)
	movl	$_Z9Find_gRNAPcPsis, %esi
	movl	$.L__unnamed_1, %edx
	movl	$.L__unnamed_1, %ecx
	movq	%rbx, %rdi
	movl	$-1, %r8d
	xorl	%r9d, %r9d
	callq	__hipRegisterFunction
	xorps	%xmm0, %xmm0
	movups	%xmm0, 16(%rsp)
	movups	%xmm0, (%rsp)
	movl	$_Z13TrimmAdaptorsPcPsis, %esi
	movl	$.L__unnamed_2, %edx
	movl	$.L__unnamed_2, %ecx
	movq	%rbx, %rdi
	movl	$-1, %r8d
	xorl	%r9d, %r9d
	callq	__hipRegisterFunction
	xorps	%xmm0, %xmm0
	movups	%xmm0, 16(%rsp)
	movups	%xmm0, (%rsp)
	movl	$_Z10TrimmQualsPcPsis, %esi
	movl	$.L__unnamed_3, %edx
	movl	$.L__unnamed_3, %ecx
	movq	%rbx, %rdi
	movl	$-1, %r8d
	xorl	%r9d, %r9d
	callq	__hipRegisterFunction
	addq	$32, %rsp
	.cfi_adjust_cfa_offset -32
	movl	$ADAPTOR, %esi
	movl	$.L__unnamed_4, %edx
	movl	$.L__unnamed_4, %ecx
	movl	$100, %r9d
	movq	%rbx, %rdi
	xorl	%r8d, %r8d
	pushq	$0
	.cfi_adjust_cfa_offset 8
	pushq	$1
	.cfi_adjust_cfa_offset 8
	callq	__hipRegisterVar
	addq	$16, %rsp
	.cfi_adjust_cfa_offset -16
	movl	$ADAPTOR_LEN, %esi
	movl	$.L__unnamed_5, %edx
	movl	$.L__unnamed_5, %ecx
	movl	$2, %r9d
	movq	%rbx, %rdi
	xorl	%r8d, %r8d
	pushq	$0
	.cfi_adjust_cfa_offset 8
	pushq	$1
	.cfi_adjust_cfa_offset 8
	callq	__hipRegisterVar
	addq	$16, %rsp
	.cfi_adjust_cfa_offset -16
	movl	$MAX_MM, %esi
	movl	$.L__unnamed_6, %edx
	movl	$.L__unnamed_6, %ecx
	movl	$2, %r9d
	movq	%rbx, %rdi
	xorl	%r8d, %r8d
	pushq	$0
	.cfi_adjust_cfa_offset 8
	pushq	$1
	.cfi_adjust_cfa_offset 8
	callq	__hipRegisterVar
	addq	$16, %rsp
	.cfi_adjust_cfa_offset -16
	movl	$QUAL_PADDING, %esi
	movl	$.L__unnamed_7, %edx
	movl	$.L__unnamed_7, %ecx
	movl	$2, %r9d
	movq	%rbx, %rdi
	xorl	%r8d, %r8d
	pushq	$0
	.cfi_adjust_cfa_offset 8
	pushq	$1
	.cfi_adjust_cfa_offset 8
	callq	__hipRegisterVar
	addq	$16, %rsp
	.cfi_adjust_cfa_offset -16
	movl	$MIN_QUAL, %esi
	movl	$.L__unnamed_8, %edx
	movl	$.L__unnamed_8, %ecx
	movl	$2, %r9d
	movq	%rbx, %rdi
	xorl	%r8d, %r8d
	pushq	$0
	.cfi_adjust_cfa_offset 8
	pushq	$1
	.cfi_adjust_cfa_offset 8
	callq	__hipRegisterVar
	addq	$16, %rsp
	.cfi_adjust_cfa_offset -16
	movl	$MIN_AVERAGE_QUAL_AFTER_BAD, %esi
	movl	$.L__unnamed_9, %edx
	movl	$.L__unnamed_9, %ecx
	movl	$2, %r9d
	movq	%rbx, %rdi
	xorl	%r8d, %r8d
	pushq	$0
	.cfi_adjust_cfa_offset 8
	pushq	$1
	.cfi_adjust_cfa_offset 8
	callq	__hipRegisterVar
	addq	$16, %rsp
	.cfi_adjust_cfa_offset -16
	movl	$__hip_module_dtor, %edi
	popq	%rbx
	.cfi_def_cfa_offset 8
	jmp	atexit                          # TAILCALL
.Lfunc_end17:
	.size	__hip_module_ctor, .Lfunc_end17-__hip_module_ctor
	.cfi_endproc
                                        # -- End function
	.p2align	4, 0x90                         # -- Begin function __hip_module_dtor
	.type	__hip_module_dtor,@function
__hip_module_dtor:                      # @__hip_module_dtor
	.cfi_startproc
# %bb.0:
	movq	__hip_gpubin_handle(%rip), %rdi
	testq	%rdi, %rdi
	je	.LBB18_2
# %bb.1:
	pushq	%rax
	.cfi_def_cfa_offset 16
	callq	__hipUnregisterFatBinary
	movq	$0, __hip_gpubin_handle(%rip)
	addq	$8, %rsp
	.cfi_def_cfa_offset 8
.LBB18_2:
	retq
.Lfunc_end18:
	.size	__hip_module_dtor, .Lfunc_end18-__hip_module_dtor
	.cfi_endproc
                                        # -- End function
	.type	hNumberOfReads,@object          # @hNumberOfReads
	.bss
	.globl	hNumberOfReads
	.p2align	2, 0x0
hNumberOfReads:
	.long	0                               # 0x0
	.size	hNumberOfReads, 4

	.type	hReadsWritten,@object           # @hReadsWritten
	.globl	hReadsWritten
	.p2align	2, 0x0
hReadsWritten:
	.long	0                               # 0x0
	.size	hReadsWritten, 4

	.type	input_filename,@object          # @input_filename
	.data
	.globl	input_filename
	.p2align	4, 0x0
input_filename:
	.asciz	"/home/linux/cuda-workspace/PreprocessReads/test.txt\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
	.size	input_filename, 400

	.type	output_filename,@object         # @output_filename
	.globl	output_filename
	.p2align	4, 0x0
output_filename:
	.asciz	"/mnt/sdc/Sequences/out.txt\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
	.size	output_filename, 400

	.type	GZIP_PIPE,@object               # @GZIP_PIPE
	.globl	GZIP_PIPE
	.p2align	4, 0x0
GZIP_PIPE:
	.asciz	"gzip -> \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
	.size	GZIP_PIPE, 410

	.type	PIGZ_PIPE,@object               # @PIGZ_PIPE
	.globl	PIGZ_PIPE
	.p2align	4, 0x0
PIGZ_PIPE:
	.asciz	"pigz -> \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
	.size	PIGZ_PIPE, 410

	.type	inputFile,@object               # @inputFile
	.bss
	.globl	inputFile
	.p2align	3, 0x0
inputFile:
	.quad	0
	.size	inputFile, 8

	.type	templateFile,@object            # @templateFile
	.globl	templateFile
	.p2align	3, 0x0
templateFile:
	.quad	0
	.size	templateFile, 8

	.type	outputFile,@object              # @outputFile
	.globl	outputFile
	.p2align	3, 0x0
outputFile:
	.quad	0
	.size	outputFile, 8

	.type	overwrite_outputfile,@object    # @overwrite_outputfile
	.globl	overwrite_outputfile
overwrite_outputfile:
	.byte	0                               # 0x0
	.size	overwrite_outputfile, 1

	.type	write_gz_output,@object         # @write_gz_output
	.globl	write_gz_output
write_gz_output:
	.byte	0                               # 0x0
	.size	write_gz_output, 1

	.type	write_pigz_output,@object       # @write_pigz_output
	.globl	write_pigz_output
write_pigz_output:
	.byte	0                               # 0x0
	.size	write_pigz_output, 1

	.type	AdaptorTrimming,@object         # @AdaptorTrimming
	.data
	.globl	AdaptorTrimming
AdaptorTrimming:
	.byte	1                               # 0x1
	.size	AdaptorTrimming, 1

	.type	QualityTrimming,@object         # @QualityTrimming
	.globl	QualityTrimming
QualityTrimming:
	.byte	1                               # 0x1
	.size	QualityTrimming, 1

	.type	gRNATrimming,@object            # @gRNATrimming
	.bss
	.globl	gRNATrimming
gRNATrimming:
	.byte	0                               # 0x0
	.size	gRNATrimming, 1

	.type	gRNA_start,@object              # @gRNA_start
	.globl	gRNA_start
	.p2align	2, 0x0
gRNA_start:
	.long	0                               # 0x0
	.size	gRNA_start, 4

	.type	gRNA_length,@object             # @gRNA_length
	.globl	gRNA_length
	.p2align	2, 0x0
gRNA_length:
	.long	0                               # 0x0
	.size	gRNA_length, 4

	.type	verbose,@object                 # @verbose
	.globl	verbose
verbose:
	.byte	0                               # 0x0
	.size	verbose, 1

	.type	FastQ_WARNING,@object           # @FastQ_WARNING
	.globl	FastQ_WARNING
FastQ_WARNING:
	.byte	0                               # 0x0
	.size	FastQ_WARNING, 1

	.type	MAX_READ_LENGTH,@object         # @MAX_READ_LENGTH
	.data
	.globl	MAX_READ_LENGTH
	.p2align	1, 0x0
MAX_READ_LENGTH:
	.short	203                             # 0xcb
	.size	MAX_READ_LENGTH, 2

	.type	MIN_OUT_READ_LEN,@object        # @MIN_OUT_READ_LEN
	.globl	MIN_OUT_READ_LEN
	.p2align	1, 0x0
MIN_OUT_READ_LEN:
	.short	26                              # 0x1a
	.size	MIN_OUT_READ_LEN, 2

	.type	MIN_BASE_QUAL,@object           # @MIN_BASE_QUAL
	.globl	MIN_BASE_QUAL
	.p2align	1, 0x0
MIN_BASE_QUAL:
	.short	20                              # 0x14
	.size	MIN_BASE_QUAL, 2

	.type	MIN_QUAL_AFTER_BAD,@object      # @MIN_QUAL_AFTER_BAD
	.globl	MIN_QUAL_AFTER_BAD
	.p2align	1, 0x0
MIN_QUAL_AFTER_BAD:
	.short	25                              # 0x19
	.size	MIN_QUAL_AFTER_BAD, 2

	.type	PHRED,@object                   # @PHRED
	.globl	PHRED
	.p2align	1, 0x0
PHRED:
	.short	33                              # 0x21
	.size	PHRED, 2

	.type	auto_phred_detect,@object       # @auto_phred_detect
	.bss
	.globl	auto_phred_detect
auto_phred_detect:
	.byte	0                               # 0x0
	.size	auto_phred_detect, 1

	.type	MAX_READS_ON_GPU,@object        # @MAX_READS_ON_GPU
	.data
	.globl	MAX_READS_ON_GPU
	.p2align	2, 0x0
MAX_READS_ON_GPU:
	.long	10000000                        # 0x989680
	.size	MAX_READS_ON_GPU, 4

	.type	Adaptor,@object                 # @Adaptor
	.globl	Adaptor
	.p2align	4, 0x0
Adaptor:
	.asciz	"ATCTCGTATGCCGTCTTCTGCTT\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
	.size	Adaptor, 100

	.type	mismatches,@object              # @mismatches
	.globl	mismatches
	.p2align	1, 0x0
mismatches:
	.short	2                               # 0x2
	.size	mismatches, 2

	.type	numGPUs,@object                 # @numGPUs
	.bss
	.globl	numGPUs
	.p2align	2, 0x0
numGPUs:
	.long	0                               # 0x0
	.size	numGPUs, 4

	.type	device,@object                  # @device
	.globl	device
	.p2align	4, 0x0
device:
	.zero	16
	.size	device, 16

	.type	upload_stream,@object           # @upload_stream
	.globl	upload_stream
	.p2align	4, 0x0
upload_stream:
	.zero	32
	.size	upload_stream, 32

	.type	compute_stream,@object          # @compute_stream
	.globl	compute_stream
	.p2align	4, 0x0
compute_stream:
	.zero	32
	.size	compute_stream, 32

	.type	download_stream,@object         # @download_stream
	.globl	download_stream
	.p2align	4, 0x0
download_stream:
	.zero	32
	.size	download_stream, 32

	.type	dSequenceArray,@object          # @dSequenceArray
	.globl	dSequenceArray
	.p2align	4, 0x0
dSequenceArray:
	.zero	32
	.size	dSequenceArray, 32

	.type	dQualArray,@object              # @dQualArray
	.globl	dQualArray
	.p2align	4, 0x0
dQualArray:
	.zero	32
	.size	dQualArray, 32

	.type	dIntArray,@object               # @dIntArray
	.globl	dIntArray
	.p2align	4, 0x0
dIntArray:
	.zero	64
	.size	dIntArray, 64

	.type	QUAL_COPY_DONE,@object          # @QUAL_COPY_DONE
	.globl	QUAL_COPY_DONE
	.p2align	4, 0x0
QUAL_COPY_DONE:
	.zero	32
	.size	QUAL_COPY_DONE, 32

	.type	SEQ_COPY_DONE,@object           # @SEQ_COPY_DONE
	.globl	SEQ_COPY_DONE
	.p2align	4, 0x0
SEQ_COPY_DONE:
	.zero	32
	.size	SEQ_COPY_DONE, 32

	.type	TrimmQ_DONE,@object             # @TrimmQ_DONE
	.globl	TrimmQ_DONE
	.p2align	4, 0x0
TrimmQ_DONE:
	.zero	32
	.size	TrimmQ_DONE, 32

	.type	TrimmA_DONE,@object             # @TrimmA_DONE
	.globl	TrimmA_DONE
	.p2align	4, 0x0
TrimmA_DONE:
	.zero	32
	.size	TrimmA_DONE, 32

	.type	DTH_COPY_DONE,@object           # @DTH_COPY_DONE
	.globl	DTH_COPY_DONE
	.p2align	4, 0x0
DTH_COPY_DONE:
	.zero	32
	.size	DTH_COPY_DONE, 32

	.type	hReadLen,@object                # @hReadLen
	.globl	hReadLen
	.p2align	4, 0x0
hReadLen:
	.zero	64
	.size	hReadLen, 64

	.type	hReadSequence,@object           # @hReadSequence
	.globl	hReadSequence
	.p2align	4, 0x0
hReadSequence:
	.zero	64
	.size	hReadSequence, 64

	.type	hReadQualstr,@object            # @hReadQualstr
	.globl	hReadQualstr
	.p2align	4, 0x0
hReadQualstr:
	.zero	32
	.size	hReadQualstr, 32

	.type	Read,@object                    # @Read
	.globl	Read
Read:
	.zero	2000
	.size	Read, 2000

	.type	ADAPTOR,@object                 # @ADAPTOR
	.local	ADAPTOR
	.comm	ADAPTOR,100,16
	.type	ADAPTOR_LEN,@object             # @ADAPTOR_LEN
	.local	ADAPTOR_LEN
	.comm	ADAPTOR_LEN,2,2
	.type	MAX_MM,@object                  # @MAX_MM
	.local	MAX_MM
	.comm	MAX_MM,2,2
	.type	QUAL_PADDING,@object            # @QUAL_PADDING
	.local	QUAL_PADDING
	.comm	QUAL_PADDING,2,2
	.type	MIN_QUAL,@object                # @MIN_QUAL
	.local	MIN_QUAL
	.comm	MIN_QUAL,2,2
	.type	MIN_AVERAGE_QUAL_AFTER_BAD,@object # @MIN_AVERAGE_QUAL_AFTER_BAD
	.local	MIN_AVERAGE_QUAL_AFTER_BAD
	.comm	MIN_AVERAGE_QUAL_AFTER_BAD,2,2
	.type	.L.str,@object                  # @.str
	.section	.rodata.str1.1,"aMS",@progbits,1
.L.str:
	.asciz	"[%d] Setting Adaptor sequence %s, length %d on GPU \n"
	.size	.L.str, 53

	.type	.L.str.1,@object                # @.str.1
.L.str.1:
	.asciz	"Error %s at line %d in file %s\n"
	.size	.L.str.1, 32

	.type	.L.str.2,@object                # @.str.2
.L.str.2:
	.asciz	"/home/ubuntu/Datasets/stackv2/train-structured-repos-hip-sm89/zanton123/PreprocessReads/master/PreprocessReads.hip"
	.size	.L.str.2, 115

	.type	.L.str.3,@object                # @.str.3
.L.str.3:
	.asciz	"[%d] Setting mismatches %d, PHRED+%d on GPU \n"
	.size	.L.str.3, 46

	.type	.L.str.4,@object                # @.str.4
.L.str.4:
	.asciz	"[%d] Setting minimum base quality %d, average read quality after bad %d on GPU \n"
	.size	.L.str.4, 81

	.type	_Z9Find_gRNAPcPsis,@object      # @_Z9Find_gRNAPcPsis
	.section	.rodata,"a",@progbits
	.globl	_Z9Find_gRNAPcPsis
	.p2align	3, 0x0
_Z9Find_gRNAPcPsis:
	.quad	_Z24__device_stub__Find_gRNAPcPsis
	.size	_Z9Find_gRNAPcPsis, 8

	.type	_Z13TrimmAdaptorsPcPsis,@object # @_Z13TrimmAdaptorsPcPsis
	.globl	_Z13TrimmAdaptorsPcPsis
	.p2align	3, 0x0
_Z13TrimmAdaptorsPcPsis:
	.quad	_Z28__device_stub__TrimmAdaptorsPcPsis
	.size	_Z13TrimmAdaptorsPcPsis, 8

	.type	_Z10TrimmQualsPcPsis,@object    # @_Z10TrimmQualsPcPsis
	.globl	_Z10TrimmQualsPcPsis
	.p2align	3, 0x0
_Z10TrimmQualsPcPsis:
	.quad	_Z25__device_stub__TrimmQualsPcPsis
	.size	_Z10TrimmQualsPcPsis, 8

	.type	.L.str.6,@object                # @.str.6
	.section	.rodata.str1.1,"aMS",@progbits,1
.L.str.6:
	.asciz	"[%d] Initializing GPU\n"
	.size	.L.str.6, 23

	.type	.L.str.7,@object                # @.str.7
.L.str.7:
	.asciz	"[%d] Allocating pinned CPU memory for reads\n"
	.size	.L.str.7, 45

	.type	.L.str.8,@object                # @.str.8
.L.str.8:
	.asciz	"\nDevice %d: %s\n"
	.size	.L.str.8, 16

	.type	.L.str.9,@object                # @.str.9
.L.str.9:
	.asciz	"  CUDA Driver / Runtime Version:     %d.%d / %d.%d\n"
	.size	.L.str.9, 52

	.type	.L.str.10,@object               # @.str.10
.L.str.10:
	.asciz	"  CUDA Compute Capability:           %d.%d\n"
	.size	.L.str.10, 44

	.type	.L.str.11,@object               # @.str.11
.L.str.11:
	.asciz	"  PCI bus ID:                        %d:%d\n"
	.size	.L.str.11, 44

	.type	.L.str.12,@object               # @.str.12
.L.str.12:
	.asciz	"  Total amount of global memory:     %.0f MBytes (%llu bytes)\n"
	.size	.L.str.12, 63

	.type	.L.str.13,@object               # @.str.13
.L.str.13:
	.asciz	"  Number of Multiprocessors:         %d\n"
	.size	.L.str.13, 41

	.type	.L.str.14,@object               # @.str.14
.L.str.14:
	.asciz	"r"
	.size	.L.str.14, 2

	.type	.L.str.16,@object               # @.str.16
.L.str.16:
	.asciz	"ERROR opening input file: %s\n"
	.size	.L.str.16, 30

	.type	.L.str.18,@object               # @.str.18
.L.str.18:
	.asciz	"w"
	.size	.L.str.18, 2

	.type	.L.str.21,@object               # @.str.21
.L.str.21:
	.asciz	"ERROR opening output file: %s\n"
	.size	.L.str.21, 31

	.type	.L.str.24,@object               # @.str.24
.L.str.24:
	.asciz	"I/O > num_of_reads_to_write = %d\n"
	.size	.L.str.24, 34

	.type	.L.str.27,@object               # @.str.27
.L.str.27:
	.asciz	"ERROR opening input file %s\n"
	.size	.L.str.27, 29

	.type	.L.str.30,@object               # @.str.30
.L.str.30:
	.asciz	"[%d] TrimmQuals\n"
	.size	.L.str.30, 17

	.type	.L.str.31,@object               # @.str.31
.L.str.31:
	.asciz	"[%d] Find_gRNA\n"
	.size	.L.str.31, 16

	.type	.L.str.32,@object               # @.str.32
.L.str.32:
	.asciz	"[%d] TrimmAdaptors\n"
	.size	.L.str.32, 20

	.type	.L.str.33,@object               # @.str.33
.L.str.33:
	.asciz	"[%d] Memcpy DtoH %d reads\n"
	.size	.L.str.33, 27

	.type	.L.str.34,@object               # @.str.34
.L.str.34:
	.asciz	"[%d] > ReadsSentToGPU = %d\n"
	.size	.L.str.34, 28

	.type	.L.str.35,@object               # @.str.35
.L.str.35:
	.asciz	"[%d] Writing hReadLen[%d][%d]\n"
	.size	.L.str.35, 31

	.type	.L.str.65,@object               # @.str.65
.L.str.65:
	.asciz	"\nERROR %s\n"
	.size	.L.str.65, 11

	.type	.L.str.67,@object               # @.str.67
.L.str.67:
	.asciz	"option -i: input file name already specified."
	.size	.L.str.67, 46

	.type	.L.str.68,@object               # @.str.68
.L.str.68:
	.asciz	"option -i: input file path length exceeds limit."
	.size	.L.str.68, 49

	.type	.L.str.69,@object               # @.str.69
.L.str.69:
	.asciz	"option -i: INPUT file name missing."
	.size	.L.str.69, 36

	.type	.L.str.70,@object               # @.str.70
.L.str.70:
	.asciz	"option -o: output file name already specified."
	.size	.L.str.70, 47

	.type	.L.str.71,@object               # @.str.71
.L.str.71:
	.asciz	"option -o: output file path length exceeds limit."
	.size	.L.str.71, 50

	.type	.L.str.72,@object               # @.str.72
.L.str.72:
	.asciz	"option -o: OUTPUT file name missing."
	.size	.L.str.72, 37

	.type	.L.str.73,@object               # @.str.73
.L.str.73:
	.asciz	"invalid command line option encountered."
	.size	.L.str.73, 41

	.type	.L.str.74,@object               # @.str.74
.L.str.74:
	.asciz	"option -len: minimum read length to include in output file is already specified."
	.size	.L.str.74, 81

	.type	.L.str.75,@object               # @.str.75
.L.str.75:
	.asciz	"option -len: encountered invalid minimum read length to include in output file."
	.size	.L.str.75, 80

	.type	.L.str.76,@object               # @.str.76
.L.str.76:
	.asciz	"option -len: expected minimum output read length not found."
	.size	.L.str.76, 60

	.type	.L.str.77,@object               # @.str.77
.L.str.77:
	.asciz	"option -a: adaptor sequence already specified."
	.size	.L.str.77, 47

	.type	.L.str.78,@object               # @.str.78
.L.str.78:
	.asciz	"option -a: adaptor sequence length exceeds limit."
	.size	.L.str.78, 50

	.type	.L.str.79,@object               # @.str.79
.L.str.79:
	.asciz	"option -a: adaptor sequence length too short."
	.size	.L.str.79, 46

	.type	.L.str.80,@object               # @.str.80
.L.str.80:
	.asciz	"option -a: expected adaptor sequence."
	.size	.L.str.80, 38

	.type	.L.str.81,@object               # @.str.81
.L.str.81:
	.asciz	"option -mm: number of mismatches is already specified."
	.size	.L.str.81, 55

	.type	.L.str.82,@object               # @.str.82
.L.str.82:
	.asciz	"option -mm: number of mismatches exceeds limit."
	.size	.L.str.82, 48

	.type	.L.str.83,@object               # @.str.83
.L.str.83:
	.asciz	"option -mm: expected number of mismatches not found."
	.size	.L.str.83, 53

	.type	.L.str.84,@object               # @.str.84
.L.str.84:
	.asciz	"option -dev: number of CUDA devices exceeds maximum."
	.size	.L.str.84, 53

	.type	.L.str.85,@object               # @.str.85
.L.str.85:
	.asciz	"option -dev: invalid device number."
	.size	.L.str.85, 36

	.type	.L.str.86,@object               # @.str.86
.L.str.86:
	.asciz	"option -dev: expected CUDA device number not found."
	.size	.L.str.86, 52

	.type	.L.str.87,@object               # @.str.87
.L.str.87:
	.asciz	"-Pigz"
	.size	.L.str.87, 6

	.type	.L.str.88,@object               # @.str.88
.L.str.88:
	.asciz	"-pigz"
	.size	.L.str.88, 6

	.type	.L.str.89,@object               # @.str.89
.L.str.89:
	.asciz	"AUTO"
	.size	.L.str.89, 5

	.type	.L.str.90,@object               # @.str.90
.L.str.90:
	.asciz	"auto"
	.size	.L.str.90, 5

	.type	.L.str.91,@object               # @.str.91
.L.str.91:
	.asciz	"option -Phred: invalid phred base."
	.size	.L.str.91, 35

	.type	.L.str.92,@object               # @.str.92
.L.str.92:
	.asciz	"option -phred: expected number or AUTO not found."
	.size	.L.str.92, 50

	.type	.L.str.93,@object               # @.str.93
.L.str.93:
	.asciz	"-Qmin"
	.size	.L.str.93, 6

	.type	.L.str.94,@object               # @.str.94
.L.str.94:
	.asciz	"-qmin"
	.size	.L.str.94, 6

	.type	.L.str.95,@object               # @.str.95
.L.str.95:
	.asciz	"option -qmin: outside 10 to 64 limit."
	.size	.L.str.95, 38

	.type	.L.str.96,@object               # @.str.96
.L.str.96:
	.asciz	"option -qmin: expected number not found."
	.size	.L.str.96, 41

	.type	.L.str.97,@object               # @.str.97
.L.str.97:
	.asciz	"-Qualab"
	.size	.L.str.97, 8

	.type	.L.str.98,@object               # @.str.98
.L.str.98:
	.asciz	"-qualab"
	.size	.L.str.98, 8

	.type	.L.str.99,@object               # @.str.99
.L.str.99:
	.asciz	"option -qualab: outside 10 to 64 limit."
	.size	.L.str.99, 40

	.type	.L.str.101,@object              # @.str.101
.L.str.101:
	.asciz	"option /T: algorithm selection is invalid."
	.size	.L.str.101, 43

	.type	.L.str.102,@object              # @.str.102
.L.str.102:
	.asciz	"option /gRNA: expected start position relative to adaptor 5' not found."
	.size	.L.str.102, 72

	.type	.L.str.103,@object              # @.str.103
.L.str.103:
	.asciz	"option /gRNA: expected gRNA length not found."
	.size	.L.str.103, 46

	.type	.L.str.104,@object              # @.str.104
.L.str.104:
	.asciz	"option /g: algorithm selection is invalid."
	.size	.L.str.104, 43

	.type	.L.str.105,@object              # @.str.105
.L.str.105:
	.asciz	"parsing command line options."
	.size	.L.str.105, 30

	.type	.L.str.106,@object              # @.str.106
.L.str.106:
	.asciz	"missing required command line options."
	.size	.L.str.106, 39

	.type	.L.str.109,@object              # @.str.109
.L.str.109:
	.asciz	"\tInput file name  : %s\n"
	.size	.L.str.109, 24

	.type	.L.str.110,@object              # @.str.110
.L.str.110:
	.asciz	"\tOutput file name : %s\n"
	.size	.L.str.110, 24

	.type	.L.str.111,@object              # @.str.111
.L.str.111:
	.asciz	"\tAdaptor sequence : %s\n"
	.size	.L.str.111, 24

	.type	.L.str.112,@object              # @.str.112
.L.str.112:
	.asciz	"\tMismatches = %d\n"
	.size	.L.str.112, 18

	.type	.L.str.113,@object              # @.str.113
.L.str.113:
	.asciz	"\tTrimming: "
	.size	.L.str.113, 12

	.type	.L.str.114,@object              # @.str.114
.L.str.114:
	.asciz	"Quality "
	.size	.L.str.114, 9

	.type	.L.str.115,@object              # @.str.115
.L.str.115:
	.asciz	"Adaptors "
	.size	.L.str.115, 10

	.type	.L.str.116,@object              # @.str.116
.L.str.116:
	.asciz	"Find gRNA"
	.size	.L.str.116, 10

	.type	.L.str.117,@object              # @.str.117
.L.str.117:
	.asciz	"\tMinimum accepted base quality = %d; average quality of read after bad base = %d\n"
	.size	.L.str.117, 82

	.type	.L.str.118,@object              # @.str.118
.L.str.118:
	.asciz	"\tFastQ Quality Encoding: "
	.size	.L.str.118, 26

	.type	.L.str.119,@object              # @.str.119
.L.str.119:
	.asciz	"PHRED+%d\n"
	.size	.L.str.119, 10

	.type	.L.str.121,@object              # @.str.121
.L.str.121:
	.asciz	"\tMAX_READ_LENGTH  : %d\n"
	.size	.L.str.121, 24

	.type	.L.str.122,@object              # @.str.122
.L.str.122:
	.asciz	"\tMinimum read length for output = %d\n"
	.size	.L.str.122, 38

	.type	.L.str.124,@object              # @.str.124
.L.str.124:
	.asciz	"\nUsing CUDA devices: "
	.size	.L.str.124, 22

	.type	.L.str.125,@object              # @.str.125
.L.str.125:
	.asciz	"[%d]"
	.size	.L.str.125, 5

	.type	.L.str.128,@object              # @.str.128
.L.str.128:
	.asciz	"\n%d CUDA devices with at least compute capability 3.5 and 6 GB memory found.\n"
	.size	.L.str.128, 78

	.type	.L.str.129,@object              # @.str.129
.L.str.129:
	.asciz	"<AUTO DETECTION> FastQ Quality Encoding: PHRED+%d\n"
	.size	.L.str.129, 51

	.type	.L.str.131,@object              # @.str.131
.L.str.131:
	.asciz	"\nReads processed: %d\n"
	.size	.L.str.131, 22

	.type	.L.str.132,@object              # @.str.132
.L.str.132:
	.asciz	"Reads in input file %s : %d\n"
	.size	.L.str.132, 29

	.type	.L.str.133,@object              # @.str.133
.L.str.133:
	.asciz	"Reads written to output file %s : %d\n"
	.size	.L.str.133, 38

	.type	.L.str.134,@object              # @.str.134
.L.str.134:
	.asciz	"Encountered potential issues with the FastQ file format in %s\n"
	.size	.L.str.134, 63

	.type	.L.str.135,@object              # @.str.135
.L.str.135:
	.asciz	"\nTotal time elapsed: %.0lf seconds\n"
	.size	.L.str.135, 36

	.type	.L__unnamed_1,@object           # @0
.L__unnamed_1:
	.asciz	"_Z9Find_gRNAPcPsis"
	.size	.L__unnamed_1, 19

	.type	.L__unnamed_2,@object           # @1
.L__unnamed_2:
	.asciz	"_Z13TrimmAdaptorsPcPsis"
	.size	.L__unnamed_2, 24

	.type	.L__unnamed_3,@object           # @2
.L__unnamed_3:
	.asciz	"_Z10TrimmQualsPcPsis"
	.size	.L__unnamed_3, 21

	.type	.L__unnamed_4,@object           # @3
.L__unnamed_4:
	.asciz	"ADAPTOR"
	.size	.L__unnamed_4, 8

	.type	.L__unnamed_5,@object           # @4
.L__unnamed_5:
	.asciz	"ADAPTOR_LEN"
	.size	.L__unnamed_5, 12

	.type	.L__unnamed_6,@object           # @5
.L__unnamed_6:
	.asciz	"MAX_MM"
	.size	.L__unnamed_6, 7

	.type	.L__unnamed_7,@object           # @6
.L__unnamed_7:
	.asciz	"QUAL_PADDING"
	.size	.L__unnamed_7, 13

	.type	.L__unnamed_8,@object           # @7
.L__unnamed_8:
	.asciz	"MIN_QUAL"
	.size	.L__unnamed_8, 9

	.type	.L__unnamed_9,@object           # @8
.L__unnamed_9:
	.asciz	"MIN_AVERAGE_QUAL_AFTER_BAD"
	.size	.L__unnamed_9, 27

	.type	__hip_fatbin_wrapper,@object    # @__hip_fatbin_wrapper
	.section	.hipFatBinSegment,"a",@progbits
	.p2align	3, 0x0
__hip_fatbin_wrapper:
	.long	1212764230                      # 0x48495046
	.long	1                               # 0x1
	.quad	__hip_fatbin
	.quad	0
	.size	__hip_fatbin_wrapper, 24

	.type	__hip_gpubin_handle,@object     # @__hip_gpubin_handle
	.local	__hip_gpubin_handle
	.comm	__hip_gpubin_handle,8,8
	.section	.init_array,"aw",@init_array
	.p2align	3, 0x0
	.quad	__hip_module_ctor
	.type	__hip_cuid_,@object             # @__hip_cuid_
	.bss
	.globl	__hip_cuid_
__hip_cuid_:
	.byte	0                               # 0x0
	.size	__hip_cuid_, 1

	.type	.Lstr,@object                   # @str
	.section	.rodata.str1.1,"aMS",@progbits,1
.Lstr:
	.asciz	"ERROR output file exists already. To overwrite run with option -f"
	.size	.Lstr, 66

	.type	.Lstr.1,@object                 # @str.1
.Lstr.1:
	.asciz	"Option -pigz: could not open pipe ... falling back on libz.\n\tMake sure pigz is installed with: sudo apt-get install pigz"
	.size	.Lstr.1, 121

	.type	.Lstr.2,@object                 # @str.2
.Lstr.2:
	.asciz	"Option -gz: could not open pipe ... falling back to uncompressed output."
	.size	.Lstr.2, 73

	.type	.Lstr.3,@object                 # @str.3
.Lstr.3:
	.asciz	"ERROR opening second handle to input file."
	.size	.Lstr.3, 43

	.type	.Lstr.4,@object                 # @str.4
.Lstr.4:
	.asciz	"Warning: Encountered unusual line identifiers in FastQ file format."
	.size	.Lstr.4, 68

	.type	.Lstr.10,@object                # @str.10
.Lstr.10:
	.asciz	"ERROR parsing input file for writing trimmed output!"
	.size	.Lstr.10, 53

	.type	.Lstr.13,@object                # @str.13
.Lstr.13:
	.asciz	"ERROR parsing input!"
	.size	.Lstr.13, 21

	.type	.Lstr.14,@object                # @str.14
.Lstr.14:
	.asciz	"\nPreprocessing reads on GPU"
	.size	.Lstr.14, 28

	.type	.Lstr.15,@object                # @str.15
.Lstr.15:
	.asciz	"\nPreprocessReads multi-GPU version"
	.size	.Lstr.15, 35

	.type	.Lstr.16,@object                # @str.16
.Lstr.16:
	.asciz	"\tsupports up to 4 NVIDIA GPUs with compute capability greater than 3.5 and at least 6 GB memory."
	.size	.Lstr.16, 97

	.type	.Lstr.17,@object                # @str.17
.Lstr.17:
	.asciz	"\tcompiled for minimum CUDA API 6.5 (build 20210107)."
	.size	.Lstr.17, 53

	.type	.Lstr.18,@object                # @str.18
.Lstr.18:
	.asciz	"\nProgram Options:\n"
	.size	.Lstr.18, 19

	.type	.Lstr.19,@object                # @str.19
.Lstr.19:
	.asciz	"\t-i, -I ....... specify the path for the input file [required]"
	.size	.Lstr.19, 63

	.type	.Lstr.20,@object                # @str.20
.Lstr.20:
	.asciz	"\t-o, -O ....... specify the path for the output file [required]"
	.size	.Lstr.20, 64

	.type	.Lstr.21,@object                # @str.21
.Lstr.21:
	.asciz	"\t-len, -Len ... specify the minimum length for reads written to the output file"
	.size	.Lstr.21, 80

	.type	.Lstr.22,@object                # @str.22
.Lstr.22:
	.asciz	"\t-f ........... over write output file if it exists"
	.size	.Lstr.22, 52

	.type	.Lstr.23,@object                # @str.23
.Lstr.23:
	.asciz	"\t-gz .......... write output to file in compressed format (.gz)"
	.size	.Lstr.23, 64

	.type	.Lstr.24,@object                # @str.24
.Lstr.24:
	.asciz	"\t-pigz ........ write output to file in compressed format (.gz) using multithreaded compression"
	.size	.Lstr.24, 96

	.type	.Lstr.25,@object                # @str.25
.Lstr.25:
	.asciz	"\t-v, -V ....... verbose, prints details on processing to screen"
	.size	.Lstr.25, 64

	.type	.Lstr.26,@object                # @str.26
.Lstr.26:
	.asciz	"\t-a, -A ....... adaptor sequence, can contain Ns that will match any base in the read"
	.size	.Lstr.26, 86

	.type	.Lstr.27,@object                # @str.27
.Lstr.27:
	.asciz	"\t-mm, -MM ..... number of mismatches allowed in adaptor search (not including Ns)"
	.size	.Lstr.27, 82

	.type	.Lstr.28,@object                # @str.28
.Lstr.28:
	.asciz	"\t-Phred ....... sets the base of the qualities PHRED values [default 33], use AUTO for autodetection"
	.size	.Lstr.28, 101

	.type	.Lstr.29,@object                # @str.29
.Lstr.29:
	.asciz	"\t-Qmin ........ sets the minimum acceptable quality score for a good base [default 20]"
	.size	.Lstr.29, 87

	.type	.Lstr.30,@object                # @str.30
.Lstr.30:
	.asciz	"\t-Qualab ...... sets the minimum average base quality score for remainder of the read after a bad base [default 25]"
	.size	.Lstr.30, 116

	.type	.Lstr.31,@object                # @str.31
.Lstr.31:
	.asciz	"\t-dev, -Dev ... specify CUDA device to use (can be used repeatedly for selecting multiple GPUs,"
	.size	.Lstr.31, 96

	.type	.Lstr.32,@object                # @str.32
.Lstr.32:
	.asciz	"\t               if not specified an automatic search for GPUs with compute capability 3.5 and 6 GB memory is performed)"
	.size	.Lstr.32, 120

	.type	.Lstr.33,@object                # @str.33
.Lstr.33:
	.asciz	"\nAlgorithm selection:\n"
	.size	.Lstr.33, 23

	.type	.Lstr.34,@object                # @str.34
.Lstr.34:
	.asciz	"\t/TA .......... select adaptor trimming only (can be also used before option /gRNA to avoid quality trimming)"
	.size	.Lstr.34, 110

	.type	.Lstr.35,@object                # @str.35
.Lstr.35:
	.asciz	"\t/TQ .......... select quality trimming only"
	.size	.Lstr.35, 45

	.type	.Lstr.36,@object                # @str.36
.Lstr.36:
	.asciz	"\t/TAQ ......... select quality and adaptor trimming [default]"
	.size	.Lstr.36, 62

	.type	.Lstr.37,@object                # @str.37
.Lstr.37:
	.asciz	"\t/gRNA ........ select gRNA recovery, followed by start relative to start of adaptor sequence and length of gRNA to be retrieved"
	.size	.Lstr.37, 129

	.type	.Lstr.38,@object                # @str.38
.Lstr.38:
	.asciz	"\t               ( /gRNA 12 20 will retrieve 20 nucleotide read sequence starting 12 positions after the 5' end match of adaptor)"
	.size	.Lstr.38, 129

	.type	.Lstr.39,@object                # @str.39
.Lstr.39:
	.asciz	"\nProgrammer options variables:"
	.size	.Lstr.39, 31

	.type	.Lstr.40,@object                # @str.40
.Lstr.40:
	.asciz	"\t-G ........... set MAX_READS_ON_GPU variable"
	.size	.Lstr.40, 46

	.type	.Lstr.41,@object                # @str.41
.Lstr.41:
	.asciz	"\t-R ........... set MAX_READ_LENGTH variable"
	.size	.Lstr.41, 45

	.type	.Lstr.42,@object                # @str.42
.Lstr.42:
	.asciz	"\nexample usage:"
	.size	.Lstr.42, 16

	.type	.Lstr.43,@object                # @str.43
.Lstr.43:
	.asciz	"\tPreprocessReads -dev 0 -dev 1 -i infile.fastq -o outfilename.fastq -len 26 -a ATTAGATCGATGCTA -mm 2\n"
	.size	.Lstr.43, 102

	.type	.Lstr.44,@object                # @str.44
.Lstr.44:
	.asciz	"\nUsage ----------------------------------------------"
	.size	.Lstr.44, 54

	.type	.Lstr.45,@object                # @str.45
.Lstr.45:
	.asciz	"Setting parameters:"
	.size	.Lstr.45, 20

	.type	.Lstr.46,@object                # @str.46
.Lstr.46:
	.asciz	"<AUTO DETECTION>"
	.size	.Lstr.46, 17

	.type	.Lstr.47,@object                # @str.47
.Lstr.47:
	.asciz	"\tForce overwrite output file if it exists."
	.size	.Lstr.47, 43

	.type	.Lstr.48,@object                # @str.48
.Lstr.48:
	.asciz	"ERROR: encountered identical input and output file paths!"
	.size	.Lstr.48, 58

	.type	.Lstr.49,@object                # @str.49
.Lstr.49:
	.asciz	"\nHELP ----------------------------------------------"
	.size	.Lstr.49, 53

	.type	.Lstr.50,@object                # @str.50
.Lstr.50:
	.asciz	"\nOne CUDA device with at least compute capability 3.5 and 6 GB memory found."
	.size	.Lstr.50, 77

	.type	.Lstr.51,@object                # @str.51
.Lstr.51:
	.asciz	"\nERROR: Unable to detect FastQ format version."
	.size	.Lstr.51, 47

	.type	.Lstr.52,@object                # @str.52
.Lstr.52:
	.asciz	"\nERROR: No suitable CUDA devices found ... exiting"
	.size	.Lstr.52, 51

	.ident	"AMD clang version 18.0.0git (https://github.com/RadeonOpenCompute/llvm-project roc-6.3.2 25012 e5bf7e55c91490b07c49d8960fa7983d864936c4)"
	.section	".note.GNU-stack","",@progbits
	.addrsig
	.addrsig_sym _Z24__device_stub__Find_gRNAPcPsis
	.addrsig_sym _Z28__device_stub__TrimmAdaptorsPcPsis
	.addrsig_sym _Z25__device_stub__TrimmQualsPcPsis
	.addrsig_sym __hip_module_ctor
	.addrsig_sym __hip_module_dtor
	.addrsig_sym input_filename
	.addrsig_sym output_filename
	.addrsig_sym GZIP_PIPE
	.addrsig_sym PIGZ_PIPE
	.addrsig_sym Adaptor
	.addrsig_sym upload_stream
	.addrsig_sym compute_stream
	.addrsig_sym download_stream
	.addrsig_sym dSequenceArray
	.addrsig_sym dQualArray
	.addrsig_sym dIntArray
	.addrsig_sym QUAL_COPY_DONE
	.addrsig_sym SEQ_COPY_DONE
	.addrsig_sym TrimmQ_DONE
	.addrsig_sym TrimmA_DONE
	.addrsig_sym DTH_COPY_DONE
	.addrsig_sym hReadLen
	.addrsig_sym hReadSequence
	.addrsig_sym hReadQualstr
	.addrsig_sym Read
	.addrsig_sym ADAPTOR
	.addrsig_sym ADAPTOR_LEN
	.addrsig_sym MAX_MM
	.addrsig_sym QUAL_PADDING
	.addrsig_sym MIN_QUAL
	.addrsig_sym MIN_AVERAGE_QUAL_AFTER_BAD
	.addrsig_sym _Z9Find_gRNAPcPsis
	.addrsig_sym _Z13TrimmAdaptorsPcPsis
	.addrsig_sym _Z10TrimmQualsPcPsis
	.addrsig_sym __hip_fatbin
	.addrsig_sym __hip_fatbin_wrapper
	.addrsig_sym __hip_cuid_

	.text
	.amdgcn_target "amdgcn-amd-amdhsa--gfx1100"
	.protected	_Z9Find_gRNAPcPsis      ; -- Begin function _Z9Find_gRNAPcPsis
	.globl	_Z9Find_gRNAPcPsis
	.p2align	8
	.type	_Z9Find_gRNAPcPsis,@function
_Z9Find_gRNAPcPsis:                     ; @_Z9Find_gRNAPcPsis
; %bb.0:
	s_clause 0x1
	s_load_b32 s2, s[0:1], 0x24
	s_load_b64 s[10:11], s[0:1], 0x10
	s_add_u32 s12, s0, 24
	s_addc_u32 s13, s1, 0
	s_mov_b32 s4, exec_lo
	s_waitcnt lgkmcnt(0)
	s_and_b32 s17, s2, 0xffff
	s_ashr_i32 s3, s10, 31
	v_mad_u64_u32 v[1:2], null, s15, s17, v[0:1]
	v_mov_b32_e32 v2, 0
	s_mov_b32 s2, s10
	s_delay_alu instid0(VALU_DEP_1) | instid1(SALU_CYCLE_1)
	v_cmpx_gt_i64_e64 s[2:3], v[1:2]
	s_cbranch_execz .LBB0_50
; %bb.1:                                ; %.lr.ph116
	s_getpc_b64 s[4:5]
	s_add_u32 s4, s4, ADAPTOR_LEN@rel32@lo+4
	s_addc_u32 s5, s5, ADAPTOR_LEN@rel32@hi+12
	global_load_u16 v6, v2, s[4:5]
	s_mov_b32 s4, s11
	s_waitcnt vmcnt(0)
	v_readfirstlane_b32 s5, v6
	v_and_b32_e32 v9, 0xffff, v6
	s_delay_alu instid0(VALU_DEP_2)
	s_sext_i32_i16 s14, s5
	s_bfe_i64 s[8:9], s[4:5], 0x100000
	s_cmp_gt_i32 s14, 0
	s_cselect_b32 s15, -1, 0
	s_getpc_b64 s[4:5]
	s_add_u32 s4, s4, MAX_MM@rel32@lo+4
	s_addc_u32 s5, s5, MAX_MM@rel32@hi+12
	global_load_i16 v8, v2, s[4:5]
	s_load_b128 s[4:7], s[0:1], 0x0
	s_load_b32 s0, s[12:13], 0x0
	s_sext_i32_i16 s1, s11
	s_mov_b32 s12, 0
	s_waitcnt lgkmcnt(0)
	v_mad_u64_u32 v[3:4], null, s1, v1, s[4:5]
	s_add_i32 s1, s14, -1
	s_cmp_gt_i32 s14, 1
	s_mul_i32 s17, s0, s17
	s_cselect_b32 s13, -1, 0
	s_add_i32 s16, s14, -2
	s_cmp_gt_i32 s14, 2
	s_delay_alu instid0(VALU_DEP_1)
	v_mov_b32_e32 v0, v4
	s_mul_i32 s0, s9, s17
	s_mul_hi_u32 s10, s8, s17
	s_cselect_b32 s18, -1, 0
	s_add_i32 s19, s10, s0
	v_mad_u64_u32 v[4:5], null, s9, v1, v[0:1]
	v_mov_b32_e32 v0, v1
	s_mul_i32 s20, s8, s17
	s_delay_alu instid0(VALU_DEP_2)
	v_dual_mov_b32 v1, v2 :: v_dual_mov_b32 v10, v4
.LBB0_2:                                ; =>This Loop Header: Depth=1
                                        ;     Child Loop BB0_4 Depth 2
                                        ;       Child Loop BB0_6 Depth 3
                                        ;     Child Loop BB0_25 Depth 2
                                        ;     Child Loop BB0_39 Depth 2
	s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_2) | instid1(VALU_DEP_2)
	v_lshlrev_b64 v[4:5], 1, v[0:1]
	v_mov_b32_e32 v13, 0
	s_mov_b32 s21, exec_lo
	v_add_co_u32 v4, vcc_lo, s6, v4
	s_delay_alu instid0(VALU_DEP_3) | instskip(SKIP_4) | instid1(VALU_DEP_1)
	v_add_co_ci_u32_e32 v5, vcc_lo, s7, v5, vcc_lo
	global_load_i16 v11, v[4:5], off
	global_store_b16 v[4:5], v13, off
	s_waitcnt vmcnt(0)
	v_subrev_nc_u32_e32 v12, s14, v11
	v_cmpx_lt_i32_e32 -1, v12
	s_cbranch_execz .LBB0_21
; %bb.3:                                ; %.preheader.preheader
                                        ;   in Loop: Header=BB0_2 Depth=1
	v_mov_b32_e32 v6, 0
	s_mov_b32 s22, 0
                                        ; implicit-def: $sgpr23
                                        ; implicit-def: $sgpr24
.LBB0_4:                                ; %.preheader
                                        ;   Parent Loop BB0_2 Depth=1
                                        ; =>  This Loop Header: Depth=2
                                        ;       Child Loop BB0_6 Depth 3
	s_delay_alu instid0(VALU_DEP_1)
	v_dual_mov_b32 v14, v6 :: v_dual_mov_b32 v13, 0
	s_and_not1_b32 vcc_lo, exec_lo, s15
	s_cbranch_vccnz .LBB0_15
; %bb.5:                                ; %.lr.ph.preheader
                                        ;   in Loop: Header=BB0_4 Depth=2
	s_delay_alu instid0(VALU_DEP_1)
	v_bfe_i32 v6, v14, 0, 16
	v_mov_b32_e32 v13, 0
	v_mov_b32_e32 v15, v9
	s_mov_b32 s25, 0
	s_getpc_b64 s[10:11]
	s_add_u32 s10, s10, ADAPTOR@rel32@lo+4
	s_addc_u32 s11, s11, ADAPTOR@rel32@hi+12
	v_ashrrev_i32_e32 v7, 31, v6
	v_add_co_u32 v6, vcc_lo, v3, v6
	s_delay_alu instid0(VALU_DEP_2)
	v_add_co_ci_u32_e32 v7, vcc_lo, v10, v7, vcc_lo
.LBB0_6:                                ; %.lr.ph
                                        ;   Parent Loop BB0_2 Depth=1
                                        ;     Parent Loop BB0_4 Depth=2
                                        ; =>    This Inner Loop Header: Depth=3
	global_load_u8 v16, v2, s[10:11]
	s_mov_b32 s0, -1
	s_waitcnt vmcnt(0)
	v_cmp_eq_u16_e32 vcc_lo, 0x4e, v16
	s_cbranch_vccnz .LBB0_10
; %bb.7:                                ;   in Loop: Header=BB0_6 Depth=3
	global_load_u8 v17, v[6:7], off
	s_mov_b32 s27, exec_lo
	s_waitcnt vmcnt(0)
	v_cmp_eq_u16_e64 s26, v17, v16
	v_cmpx_ne_u16_e64 v17, v16
; %bb.8:                                ;   in Loop: Header=BB0_6 Depth=3
	v_add_nc_u16 v13, v13, 1
	s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_1)
	s_and_not1_b32 s26, s26, exec_lo
	v_cmp_le_i16_e32 vcc_lo, v13, v8
	s_and_b32 s28, vcc_lo, exec_lo
	s_delay_alu instid0(SALU_CYCLE_1)
	s_or_b32 s26, s26, s28
; %bb.9:                                ; %Flow189
                                        ;   in Loop: Header=BB0_6 Depth=3
	s_or_b32 exec_lo, exec_lo, s27
	s_branch .LBB0_11
.LBB0_10:                               ;   in Loop: Header=BB0_6 Depth=3
	s_mov_b32 s26, -1
.LBB0_11:                               ; %Flow188
                                        ;   in Loop: Header=BB0_6 Depth=3
	s_delay_alu instid0(SALU_CYCLE_1)
	s_and_saveexec_b32 s27, s26
; %bb.12:                               ;   in Loop: Header=BB0_6 Depth=3
	v_add_nc_u32_e32 v15, -1, v15
	v_add_co_u32 v6, s0, v6, 1
	s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_3)
	v_add_co_ci_u32_e64 v7, s0, 0, v7, s0
	v_cmp_eq_u32_e32 vcc_lo, 0, v15
	s_add_u32 s10, s10, 1
	s_addc_u32 s11, s11, 0
	s_or_not1_b32 s0, vcc_lo, exec_lo
; %bb.13:                               ; %Flow190
                                        ;   in Loop: Header=BB0_6 Depth=3
	s_or_b32 exec_lo, exec_lo, s27
	s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)
	s_and_b32 s0, exec_lo, s0
	s_or_b32 s25, s0, s25
	s_delay_alu instid0(SALU_CYCLE_1)
	s_and_not1_b32 exec_lo, exec_lo, s25
	s_cbranch_execnz .LBB0_6
; %bb.14:                               ; %Flow191
                                        ;   in Loop: Header=BB0_4 Depth=2
	s_or_b32 exec_lo, exec_lo, s25
.LBB0_15:                               ; %._crit_edge
                                        ;   in Loop: Header=BB0_4 Depth=2
	s_mov_b32 s0, -1
	s_or_b32 s24, s24, exec_lo
	s_mov_b32 s10, exec_lo
                                        ; implicit-def: $vgpr6
	v_cmpx_gt_i16_e64 v13, v8
; %bb.16:                               ;   in Loop: Header=BB0_4 Depth=2
	v_add_nc_u16 v6, v14, 1
	s_and_not1_b32 s24, s24, exec_lo
	s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
	v_bfe_i32 v7, v6, 0, 16
	v_cmp_lt_i32_e32 vcc_lo, v12, v7
	s_or_not1_b32 s0, vcc_lo, exec_lo
; %bb.17:                               ; %Flow193
                                        ;   in Loop: Header=BB0_4 Depth=2
	s_or_b32 exec_lo, exec_lo, s10
	s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)
	s_and_b32 s0, exec_lo, s0
	s_or_b32 s22, s0, s22
	s_and_not1_b32 s0, s23, exec_lo
	s_and_b32 s10, s24, exec_lo
	s_delay_alu instid0(SALU_CYCLE_1)
	s_or_b32 s23, s0, s10
	s_and_not1_b32 exec_lo, exec_lo, s22
	s_cbranch_execnz .LBB0_4
; %bb.18:                               ; %loop.exit.guard
                                        ;   in Loop: Header=BB0_2 Depth=1
	s_or_b32 exec_lo, exec_lo, s22
	s_and_saveexec_b32 s0, s23
	s_delay_alu instid0(SALU_CYCLE_1)
	s_xor_b32 s0, exec_lo, s0
	s_cbranch_execz .LBB0_20
; %bb.19:                               ;   in Loop: Header=BB0_2 Depth=1
	global_store_b16 v[4:5], v14, off
.LBB0_20:                               ; %Flow186
                                        ;   in Loop: Header=BB0_2 Depth=1
	s_or_b32 exec_lo, exec_lo, s0
.LBB0_21:                               ; %Flow194
                                        ;   in Loop: Header=BB0_2 Depth=1
	s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)
	s_or_b32 exec_lo, exec_lo, s21
	s_mov_b32 s0, exec_lo
	v_cmpx_gt_i16_e64 v13, v8
	s_cbranch_execz .LBB0_49
; %bb.22:                               ;   in Loop: Header=BB0_2 Depth=1
	v_mad_u64_u32 v[6:7], null, v0, s8, s[4:5]
	v_mul_lo_u32 v12, v0, s9
	v_mul_lo_u32 v14, v1, s8
	v_sub_nc_u16 v13, v11, s14
	s_mov_b32 s21, -1
	s_mov_b32 s10, 0
	s_mov_b32 s11, exec_lo
	s_delay_alu instid0(VALU_DEP_2)
	v_add3_u32 v12, v14, v7, v12
                                        ; implicit-def: $vgpr7
	v_cmpx_le_i32_e64 s1, v11
	s_cbranch_execz .LBB0_35
; %bb.23:                               ; %.preheader83
                                        ;   in Loop: Header=BB0_2 Depth=1
	v_add_nc_u16 v7, v13, 1
	v_mov_b32_e32 v14, 0
	s_and_not1_b32 vcc_lo, exec_lo, s13
	s_cbranch_vccnz .LBB0_34
; %bb.24:                               ; %.lr.ph103
                                        ;   in Loop: Header=BB0_2 Depth=1
	s_delay_alu instid0(VALU_DEP_2)
	v_bfe_i32 v15, v7, 0, 16
	v_mov_b32_e32 v14, 0
	s_mov_b32 s23, 0
	s_mov_b32 s21, 0
.LBB0_25:                               ;   Parent Loop BB0_2 Depth=1
                                        ; =>  This Inner Loop Header: Depth=2
	s_delay_alu instid0(SALU_CYCLE_1)
	s_sext_i32_i16 s22, s21
	s_getpc_b64 s[24:25]
	s_add_u32 s24, s24, ADAPTOR@rel32@lo+4
	s_addc_u32 s25, s25, ADAPTOR@rel32@hi+12
	s_ashr_i32 s26, s22, 31
	s_add_u32 s24, s22, s24
	s_addc_u32 s25, s26, s25
	s_mov_b32 s22, -1
	global_load_u8 v16, v2, s[24:25]
	s_waitcnt vmcnt(0)
	v_cmp_eq_u16_e32 vcc_lo, 0x4e, v16
	s_cbranch_vccnz .LBB0_29
; %bb.26:                               ;   in Loop: Header=BB0_25 Depth=2
	v_add_nc_u32_e32 v17, s23, v15
	s_mov_b32 s23, exec_lo
	s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(VALU_DEP_2)
	v_ashrrev_i32_e32 v18, 31, v17
	v_add_co_u32 v17, vcc_lo, v6, v17
	v_add_co_ci_u32_e32 v18, vcc_lo, v12, v18, vcc_lo
	global_load_u8 v17, v[17:18], off
	s_waitcnt vmcnt(0)
	v_cmp_eq_u16_e64 s24, v17, v16
	v_cmpx_ne_u16_e64 v17, v16
; %bb.27:                               ;   in Loop: Header=BB0_25 Depth=2
	v_add_nc_u16 v14, v14, 1
	s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_1)
	s_and_not1_b32 s24, s24, exec_lo
	v_cmp_lt_i16_e32 vcc_lo, v14, v8
	s_and_b32 s25, vcc_lo, exec_lo
	s_delay_alu instid0(SALU_CYCLE_1)
	s_or_b32 s24, s24, s25
; %bb.28:                               ; %Flow173
                                        ;   in Loop: Header=BB0_25 Depth=2
	s_or_b32 exec_lo, exec_lo, s23
	s_branch .LBB0_30
.LBB0_29:                               ;   in Loop: Header=BB0_25 Depth=2
	s_mov_b32 s24, -1
.LBB0_30:                               ; %Flow
                                        ;   in Loop: Header=BB0_25 Depth=2
                                        ; implicit-def: $sgpr23
	s_delay_alu instid0(SALU_CYCLE_1)
	s_and_saveexec_b32 s25, s24
; %bb.31:                               ;   in Loop: Header=BB0_25 Depth=2
	s_and_b32 s21, 0xffff, s21
	s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)
	s_add_i32 s21, s21, 1
	s_sext_i32_i16 s23, s21
	s_delay_alu instid0(SALU_CYCLE_1) | instskip(SKIP_1) | instid1(SALU_CYCLE_1)
	s_cmp_le_i32 s1, s23
	s_cselect_b32 s22, -1, 0
	s_or_not1_b32 s22, s22, exec_lo
; %bb.32:                               ; %Flow174
                                        ;   in Loop: Header=BB0_25 Depth=2
	s_or_b32 exec_lo, exec_lo, s25
	s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)
	s_and_b32 s22, exec_lo, s22
	s_or_b32 s10, s22, s10
	s_delay_alu instid0(SALU_CYCLE_1)
	s_and_not1_b32 exec_lo, exec_lo, s10
	s_cbranch_execnz .LBB0_25
; %bb.33:                               ; %Flow175
                                        ;   in Loop: Header=BB0_2 Depth=1
	s_or_b32 exec_lo, exec_lo, s10
.LBB0_34:                               ; %._crit_edge104
                                        ;   in Loop: Header=BB0_2 Depth=1
	s_delay_alu instid0(VALU_DEP_1)
	v_cmp_ge_i16_e32 vcc_lo, v14, v8
	s_mov_b32 s10, exec_lo
	s_or_not1_b32 s21, vcc_lo, exec_lo
.LBB0_35:                               ; %Flow182
                                        ;   in Loop: Header=BB0_2 Depth=1
	s_or_b32 exec_lo, exec_lo, s11
	s_and_saveexec_b32 s11, s21
	s_cbranch_execz .LBB0_47
; %bb.36:                               ;   in Loop: Header=BB0_2 Depth=1
	s_mov_b32 s22, 0
	s_mov_b32 s21, exec_lo
                                        ; implicit-def: $vgpr7
	v_cmpx_le_i32_e64 s16, v11
	s_cbranch_execz .LBB0_46
; %bb.37:                               ; %.preheader82
                                        ;   in Loop: Header=BB0_2 Depth=1
	v_add_nc_u16 v7, v13, 2
	v_mov_b32_e32 v13, 1
	s_and_not1_b32 vcc_lo, exec_lo, s18
	s_cbranch_vccnz .LBB0_45
; %bb.38:                               ; %.lr.ph109.preheader
                                        ;   in Loop: Header=BB0_2 Depth=1
	s_delay_alu instid0(VALU_DEP_2)
	v_bfe_i32 v11, v7, 0, 16
	s_mov_b32 s23, 0
	s_mov_b32 s24, 0
.LBB0_39:                               ; %.lr.ph109
                                        ;   Parent Loop BB0_2 Depth=1
                                        ; =>  This Inner Loop Header: Depth=2
	s_sext_i32_i16 s25, s23
	s_getpc_b64 s[26:27]
	s_add_u32 s26, s26, ADAPTOR@rel32@lo+4
	s_addc_u32 s27, s27, ADAPTOR@rel32@hi+12
	s_ashr_i32 s28, s25, 31
	s_add_u32 s26, s25, s26
	s_addc_u32 s27, s28, s27
	s_mov_b32 s25, -1
	global_load_u8 v13, v2, s[26:27]
	s_mov_b32 s27, -1
                                        ; implicit-def: $sgpr26
	s_waitcnt vmcnt(0)
	v_cmp_eq_u16_e32 vcc_lo, 0x4e, v13
	s_cbranch_vccnz .LBB0_41
; %bb.40:                               ;   in Loop: Header=BB0_39 Depth=2
	v_add_nc_u32_e32 v14, s24, v11
	s_mov_b32 s26, 2
	s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(VALU_DEP_2)
	v_ashrrev_i32_e32 v15, 31, v14
	v_add_co_u32 v14, vcc_lo, v6, v14
	v_add_co_ci_u32_e32 v15, vcc_lo, v12, v15, vcc_lo
	global_load_u8 v14, v[14:15], off
	s_waitcnt vmcnt(0)
	v_cmp_eq_u16_e32 vcc_lo, v14, v13
	s_or_not1_b32 s27, vcc_lo, exec_lo
.LBB0_41:                               ; %Flow178
                                        ;   in Loop: Header=BB0_39 Depth=2
	v_mov_b32_e32 v13, s26
                                        ; implicit-def: $sgpr24
	s_and_saveexec_b32 s26, s27
; %bb.42:                               ;   in Loop: Header=BB0_39 Depth=2
	s_and_b32 s23, 0xffff, s23
	v_mov_b32_e32 v13, 1
	s_add_i32 s23, s23, 1
	s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)
	s_sext_i32_i16 s24, s23
	s_cmp_le_i32 s16, s24
	s_cselect_b32 s25, -1, 0
	s_delay_alu instid0(SALU_CYCLE_1)
	s_or_not1_b32 s25, s25, exec_lo
; %bb.43:                               ; %Flow179
                                        ;   in Loop: Header=BB0_39 Depth=2
	s_or_b32 exec_lo, exec_lo, s26
	s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)
	s_and_b32 s25, exec_lo, s25
	s_or_b32 s22, s25, s22
	s_delay_alu instid0(SALU_CYCLE_1)
	s_and_not1_b32 exec_lo, exec_lo, s22
	s_cbranch_execnz .LBB0_39
; %bb.44:                               ; %Flow180
                                        ;   in Loop: Header=BB0_2 Depth=1
	s_or_b32 exec_lo, exec_lo, s22
.LBB0_45:                               ; %._crit_edge110
                                        ;   in Loop: Header=BB0_2 Depth=1
	s_delay_alu instid0(VALU_DEP_1)
	v_cmp_lt_i32_e32 vcc_lo, v13, v8
	s_and_b32 s22, vcc_lo, exec_lo
.LBB0_46:                               ; %Flow184
                                        ;   in Loop: Header=BB0_2 Depth=1
	s_or_b32 exec_lo, exec_lo, s21
	s_delay_alu instid0(SALU_CYCLE_1) | instskip(SKIP_1) | instid1(SALU_CYCLE_1)
	s_and_not1_b32 s10, s10, exec_lo
	s_and_b32 s21, s22, exec_lo
	s_or_b32 s10, s10, s21
.LBB0_47:                               ; %Flow183
                                        ;   in Loop: Header=BB0_2 Depth=1
	s_or_b32 exec_lo, exec_lo, s11
	s_delay_alu instid0(SALU_CYCLE_1)
	s_and_b32 exec_lo, exec_lo, s10
	s_cbranch_execz .LBB0_49
; %bb.48:                               ; %.sink.split
                                        ;   in Loop: Header=BB0_2 Depth=1
	global_store_b16 v[4:5], v7, off
.LBB0_49:                               ;   in Loop: Header=BB0_2 Depth=1
	s_or_b32 exec_lo, exec_lo, s0
	v_add_co_u32 v0, vcc_lo, v0, s17
	v_add_co_ci_u32_e32 v1, vcc_lo, 0, v1, vcc_lo
	v_add_co_u32 v3, s0, v3, s20
	s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_3)
	v_add_co_ci_u32_e64 v10, s0, s19, v10, s0
	v_cmp_le_i64_e32 vcc_lo, s[2:3], v[0:1]
	s_or_b32 s12, vcc_lo, s12
	s_delay_alu instid0(SALU_CYCLE_1)
	s_and_not1_b32 exec_lo, exec_lo, s12
	s_cbranch_execnz .LBB0_2
.LBB0_50:                               ; %Flow196
	s_nop 0
	s_sendmsg sendmsg(MSG_DEALLOC_VGPRS)
	s_endpgm
	.section	.rodata,"a",@progbits
	.p2align	6, 0x0
	.amdhsa_kernel _Z9Find_gRNAPcPsis
		.amdhsa_group_segment_fixed_size 0
		.amdhsa_private_segment_fixed_size 0
		.amdhsa_kernarg_size 280
		.amdhsa_user_sgpr_count 15
		.amdhsa_user_sgpr_dispatch_ptr 0
		.amdhsa_user_sgpr_queue_ptr 0
		.amdhsa_user_sgpr_kernarg_segment_ptr 1
		.amdhsa_user_sgpr_dispatch_id 0
		.amdhsa_user_sgpr_private_segment_size 0
		.amdhsa_wavefront_size32 1
		.amdhsa_uses_dynamic_stack 0
		.amdhsa_enable_private_segment 0
		.amdhsa_system_sgpr_workgroup_id_x 1
		.amdhsa_system_sgpr_workgroup_id_y 0
		.amdhsa_system_sgpr_workgroup_id_z 0
		.amdhsa_system_sgpr_workgroup_info 0
		.amdhsa_system_vgpr_workitem_id 0
		.amdhsa_next_free_vgpr 19
		.amdhsa_next_free_sgpr 29
		.amdhsa_float_round_mode_32 0
		.amdhsa_float_round_mode_16_64 0
		.amdhsa_float_denorm_mode_32 3
		.amdhsa_float_denorm_mode_16_64 3
		.amdhsa_dx10_clamp 1
		.amdhsa_ieee_mode 1
		.amdhsa_fp16_overflow 0
		.amdhsa_workgroup_processor_mode 1
		.amdhsa_memory_ordered 1
		.amdhsa_forward_progress 0
		.amdhsa_shared_vgpr_count 0
		.amdhsa_exception_fp_ieee_invalid_op 0
		.amdhsa_exception_fp_denorm_src 0
		.amdhsa_exception_fp_ieee_div_zero 0
		.amdhsa_exception_fp_ieee_overflow 0
		.amdhsa_exception_fp_ieee_underflow 0
		.amdhsa_exception_fp_ieee_inexact 0
		.amdhsa_exception_int_div_zero 0
	.end_amdhsa_kernel
	.text
.Lfunc_end0:
	.size	_Z9Find_gRNAPcPsis, .Lfunc_end0-_Z9Find_gRNAPcPsis
                                        ; -- End function
	.section	.AMDGPU.csdata,"",@progbits
; Kernel info:
; codeLenInByte = 1548
; NumSgprs: 31
; NumVgprs: 19
; ScratchSize: 0
; MemoryBound: 0
; FloatMode: 240
; IeeeMode: 1
; LDSByteSize: 0 bytes/workgroup (compile time only)
; SGPRBlocks: 3
; VGPRBlocks: 2
; NumSGPRsForWavesPerEU: 31
; NumVGPRsForWavesPerEU: 19
; Occupancy: 16
; WaveLimiterHint : 1
; COMPUTE_PGM_RSRC2:SCRATCH_EN: 0
; COMPUTE_PGM_RSRC2:USER_SGPR: 15
; COMPUTE_PGM_RSRC2:TRAP_HANDLER: 0
; COMPUTE_PGM_RSRC2:TGID_X_EN: 1
; COMPUTE_PGM_RSRC2:TGID_Y_EN: 0
; COMPUTE_PGM_RSRC2:TGID_Z_EN: 0
; COMPUTE_PGM_RSRC2:TIDIG_COMP_CNT: 0
	.text
	.protected	_Z13TrimmAdaptorsPcPsis ; -- Begin function _Z13TrimmAdaptorsPcPsis
	.globl	_Z13TrimmAdaptorsPcPsis
	.p2align	8
	.type	_Z13TrimmAdaptorsPcPsis,@function
_Z13TrimmAdaptorsPcPsis:                ; @_Z13TrimmAdaptorsPcPsis
; %bb.0:
	s_clause 0x1
	s_load_b32 s2, s[0:1], 0x24
	s_load_b64 s[10:11], s[0:1], 0x10
	s_add_u32 s12, s0, 24
	s_addc_u32 s13, s1, 0
	s_mov_b32 s4, exec_lo
	s_waitcnt lgkmcnt(0)
	s_and_b32 s17, s2, 0xffff
	s_ashr_i32 s3, s10, 31
	v_mad_u64_u32 v[1:2], null, s15, s17, v[0:1]
	v_mov_b32_e32 v2, 0
	s_mov_b32 s2, s10
	s_delay_alu instid0(VALU_DEP_1) | instid1(SALU_CYCLE_1)
	v_cmpx_gt_i64_e64 s[2:3], v[1:2]
	s_cbranch_execz .LBB1_50
; %bb.1:                                ; %.lr.ph114
	s_getpc_b64 s[4:5]
	s_add_u32 s4, s4, ADAPTOR_LEN@rel32@lo+4
	s_addc_u32 s5, s5, ADAPTOR_LEN@rel32@hi+12
	global_load_u16 v6, v2, s[4:5]
	s_mov_b32 s4, s11
	s_waitcnt vmcnt(0)
	v_readfirstlane_b32 s5, v6
	v_and_b32_e32 v9, 0xffff, v6
	s_delay_alu instid0(VALU_DEP_2)
	s_sext_i32_i16 s14, s5
	s_bfe_i64 s[8:9], s[4:5], 0x100000
	s_cmp_gt_i32 s14, 0
	s_cselect_b32 s15, -1, 0
	s_getpc_b64 s[4:5]
	s_add_u32 s4, s4, MAX_MM@rel32@lo+4
	s_addc_u32 s5, s5, MAX_MM@rel32@hi+12
	global_load_i16 v8, v2, s[4:5]
	s_load_b128 s[4:7], s[0:1], 0x0
	s_load_b32 s0, s[12:13], 0x0
	s_sext_i32_i16 s1, s11
	s_mov_b32 s12, 0
	s_waitcnt lgkmcnt(0)
	v_mad_u64_u32 v[3:4], null, s1, v1, s[4:5]
	s_add_i32 s1, s14, -1
	s_cmp_gt_i32 s14, 1
	s_mul_i32 s17, s0, s17
	s_cselect_b32 s13, -1, 0
	s_add_i32 s16, s14, -2
	s_cmp_gt_i32 s14, 2
	s_delay_alu instid0(VALU_DEP_1)
	v_mov_b32_e32 v0, v4
	s_mul_i32 s0, s9, s17
	s_mul_hi_u32 s10, s8, s17
	s_cselect_b32 s18, -1, 0
	s_add_i32 s19, s10, s0
	v_mad_u64_u32 v[4:5], null, s9, v1, v[0:1]
	v_mov_b32_e32 v0, v1
	s_mul_i32 s20, s8, s17
	s_delay_alu instid0(VALU_DEP_2)
	v_dual_mov_b32 v1, v2 :: v_dual_mov_b32 v10, v4
.LBB1_2:                                ; =>This Loop Header: Depth=1
                                        ;     Child Loop BB1_4 Depth 2
                                        ;       Child Loop BB1_6 Depth 3
                                        ;     Child Loop BB1_25 Depth 2
                                        ;     Child Loop BB1_39 Depth 2
	s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_2) | instid1(VALU_DEP_2)
	v_lshlrev_b64 v[4:5], 1, v[0:1]
	v_mov_b32_e32 v13, 0
	s_mov_b32 s21, exec_lo
	v_add_co_u32 v4, vcc_lo, s6, v4
	s_delay_alu instid0(VALU_DEP_3) | instskip(SKIP_3) | instid1(VALU_DEP_1)
	v_add_co_ci_u32_e32 v5, vcc_lo, s7, v5, vcc_lo
	global_load_i16 v11, v[4:5], off
	s_waitcnt vmcnt(0)
	v_subrev_nc_u32_e32 v12, s14, v11
	v_cmpx_lt_i32_e32 -1, v12
	s_cbranch_execz .LBB1_21
; %bb.3:                                ; %.preheader.preheader
                                        ;   in Loop: Header=BB1_2 Depth=1
	v_mov_b32_e32 v6, 0
	s_mov_b32 s22, 0
                                        ; implicit-def: $sgpr23
                                        ; implicit-def: $sgpr24
.LBB1_4:                                ; %.preheader
                                        ;   Parent Loop BB1_2 Depth=1
                                        ; =>  This Loop Header: Depth=2
                                        ;       Child Loop BB1_6 Depth 3
	s_delay_alu instid0(VALU_DEP_1)
	v_dual_mov_b32 v14, v6 :: v_dual_mov_b32 v13, 0
	s_and_not1_b32 vcc_lo, exec_lo, s15
	s_cbranch_vccnz .LBB1_15
; %bb.5:                                ; %.lr.ph.preheader
                                        ;   in Loop: Header=BB1_4 Depth=2
	s_delay_alu instid0(VALU_DEP_1)
	v_bfe_i32 v6, v14, 0, 16
	v_mov_b32_e32 v13, 0
	v_mov_b32_e32 v15, v9
	s_mov_b32 s25, 0
	s_getpc_b64 s[10:11]
	s_add_u32 s10, s10, ADAPTOR@rel32@lo+4
	s_addc_u32 s11, s11, ADAPTOR@rel32@hi+12
	v_ashrrev_i32_e32 v7, 31, v6
	v_add_co_u32 v6, vcc_lo, v3, v6
	s_delay_alu instid0(VALU_DEP_2)
	v_add_co_ci_u32_e32 v7, vcc_lo, v10, v7, vcc_lo
.LBB1_6:                                ; %.lr.ph
                                        ;   Parent Loop BB1_2 Depth=1
                                        ;     Parent Loop BB1_4 Depth=2
                                        ; =>    This Inner Loop Header: Depth=3
	global_load_u8 v16, v2, s[10:11]
	s_mov_b32 s0, -1
	s_waitcnt vmcnt(0)
	v_cmp_eq_u16_e32 vcc_lo, 0x4e, v16
	s_cbranch_vccnz .LBB1_10
; %bb.7:                                ;   in Loop: Header=BB1_6 Depth=3
	global_load_u8 v17, v[6:7], off
	s_mov_b32 s27, exec_lo
	s_waitcnt vmcnt(0)
	v_cmp_eq_u16_e64 s26, v17, v16
	v_cmpx_ne_u16_e64 v17, v16
; %bb.8:                                ;   in Loop: Header=BB1_6 Depth=3
	v_add_nc_u16 v13, v13, 1
	s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_1)
	s_and_not1_b32 s26, s26, exec_lo
	v_cmp_le_i16_e32 vcc_lo, v13, v8
	s_and_b32 s28, vcc_lo, exec_lo
	s_delay_alu instid0(SALU_CYCLE_1)
	s_or_b32 s26, s26, s28
; %bb.9:                                ; %Flow187
                                        ;   in Loop: Header=BB1_6 Depth=3
	s_or_b32 exec_lo, exec_lo, s27
	s_branch .LBB1_11
.LBB1_10:                               ;   in Loop: Header=BB1_6 Depth=3
	s_mov_b32 s26, -1
.LBB1_11:                               ; %Flow186
                                        ;   in Loop: Header=BB1_6 Depth=3
	s_delay_alu instid0(SALU_CYCLE_1)
	s_and_saveexec_b32 s27, s26
; %bb.12:                               ;   in Loop: Header=BB1_6 Depth=3
	v_add_nc_u32_e32 v15, -1, v15
	v_add_co_u32 v6, s0, v6, 1
	s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_3)
	v_add_co_ci_u32_e64 v7, s0, 0, v7, s0
	v_cmp_eq_u32_e32 vcc_lo, 0, v15
	s_add_u32 s10, s10, 1
	s_addc_u32 s11, s11, 0
	s_or_not1_b32 s0, vcc_lo, exec_lo
; %bb.13:                               ; %Flow188
                                        ;   in Loop: Header=BB1_6 Depth=3
	s_or_b32 exec_lo, exec_lo, s27
	s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)
	s_and_b32 s0, exec_lo, s0
	s_or_b32 s25, s0, s25
	s_delay_alu instid0(SALU_CYCLE_1)
	s_and_not1_b32 exec_lo, exec_lo, s25
	s_cbranch_execnz .LBB1_6
; %bb.14:                               ; %Flow189
                                        ;   in Loop: Header=BB1_4 Depth=2
	s_or_b32 exec_lo, exec_lo, s25
.LBB1_15:                               ; %._crit_edge
                                        ;   in Loop: Header=BB1_4 Depth=2
	s_mov_b32 s0, -1
	s_or_b32 s24, s24, exec_lo
	s_mov_b32 s10, exec_lo
                                        ; implicit-def: $vgpr6
	v_cmpx_gt_i16_e64 v13, v8
; %bb.16:                               ;   in Loop: Header=BB1_4 Depth=2
	v_add_nc_u16 v6, v14, 1
	s_and_not1_b32 s24, s24, exec_lo
	s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
	v_bfe_i32 v7, v6, 0, 16
	v_cmp_lt_i32_e32 vcc_lo, v12, v7
	s_or_not1_b32 s0, vcc_lo, exec_lo
; %bb.17:                               ; %Flow191
                                        ;   in Loop: Header=BB1_4 Depth=2
	s_or_b32 exec_lo, exec_lo, s10
	s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)
	s_and_b32 s0, exec_lo, s0
	s_or_b32 s22, s0, s22
	s_and_not1_b32 s0, s23, exec_lo
	s_and_b32 s10, s24, exec_lo
	s_delay_alu instid0(SALU_CYCLE_1)
	s_or_b32 s23, s0, s10
	s_and_not1_b32 exec_lo, exec_lo, s22
	s_cbranch_execnz .LBB1_4
; %bb.18:                               ; %loop.exit.guard
                                        ;   in Loop: Header=BB1_2 Depth=1
	s_or_b32 exec_lo, exec_lo, s22
	s_and_saveexec_b32 s0, s23
	s_delay_alu instid0(SALU_CYCLE_1)
	s_xor_b32 s0, exec_lo, s0
	s_cbranch_execz .LBB1_20
; %bb.19:                               ;   in Loop: Header=BB1_2 Depth=1
	global_store_b16 v[4:5], v14, off
.LBB1_20:                               ; %Flow184
                                        ;   in Loop: Header=BB1_2 Depth=1
	s_or_b32 exec_lo, exec_lo, s0
.LBB1_21:                               ; %Flow192
                                        ;   in Loop: Header=BB1_2 Depth=1
	s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)
	s_or_b32 exec_lo, exec_lo, s21
	s_mov_b32 s0, exec_lo
	v_cmpx_gt_i16_e64 v13, v8
	s_cbranch_execz .LBB1_49
; %bb.22:                               ;   in Loop: Header=BB1_2 Depth=1
	v_mad_u64_u32 v[6:7], null, v0, s8, s[4:5]
	v_mul_lo_u32 v12, v0, s9
	v_mul_lo_u32 v14, v1, s8
	v_sub_nc_u16 v13, v11, s14
	s_mov_b32 s21, -1
	s_mov_b32 s10, 0
	s_mov_b32 s11, exec_lo
	s_delay_alu instid0(VALU_DEP_2)
	v_add3_u32 v12, v14, v7, v12
                                        ; implicit-def: $vgpr7
	v_cmpx_le_i32_e64 s1, v11
	s_cbranch_execz .LBB1_35
; %bb.23:                               ; %.preheader81
                                        ;   in Loop: Header=BB1_2 Depth=1
	v_add_nc_u16 v7, v13, 1
	v_mov_b32_e32 v14, 0
	s_and_not1_b32 vcc_lo, exec_lo, s13
	s_cbranch_vccnz .LBB1_34
; %bb.24:                               ; %.lr.ph101
                                        ;   in Loop: Header=BB1_2 Depth=1
	s_delay_alu instid0(VALU_DEP_2)
	v_bfe_i32 v15, v7, 0, 16
	v_mov_b32_e32 v14, 0
	s_mov_b32 s23, 0
	s_mov_b32 s21, 0
.LBB1_25:                               ;   Parent Loop BB1_2 Depth=1
                                        ; =>  This Inner Loop Header: Depth=2
	s_delay_alu instid0(SALU_CYCLE_1)
	s_sext_i32_i16 s22, s21
	s_getpc_b64 s[24:25]
	s_add_u32 s24, s24, ADAPTOR@rel32@lo+4
	s_addc_u32 s25, s25, ADAPTOR@rel32@hi+12
	s_ashr_i32 s26, s22, 31
	s_add_u32 s24, s22, s24
	s_addc_u32 s25, s26, s25
	s_mov_b32 s22, -1
	global_load_u8 v16, v2, s[24:25]
	s_waitcnt vmcnt(0)
	v_cmp_eq_u16_e32 vcc_lo, 0x4e, v16
	s_cbranch_vccnz .LBB1_29
; %bb.26:                               ;   in Loop: Header=BB1_25 Depth=2
	v_add_nc_u32_e32 v17, s23, v15
	s_mov_b32 s23, exec_lo
	s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(VALU_DEP_2)
	v_ashrrev_i32_e32 v18, 31, v17
	v_add_co_u32 v17, vcc_lo, v6, v17
	v_add_co_ci_u32_e32 v18, vcc_lo, v12, v18, vcc_lo
	global_load_u8 v17, v[17:18], off
	s_waitcnt vmcnt(0)
	v_cmp_eq_u16_e64 s24, v17, v16
	v_cmpx_ne_u16_e64 v17, v16
; %bb.27:                               ;   in Loop: Header=BB1_25 Depth=2
	v_add_nc_u16 v14, v14, 1
	s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_1)
	s_and_not1_b32 s24, s24, exec_lo
	v_cmp_lt_i16_e32 vcc_lo, v14, v8
	s_and_b32 s25, vcc_lo, exec_lo
	s_delay_alu instid0(SALU_CYCLE_1)
	s_or_b32 s24, s24, s25
; %bb.28:                               ; %Flow171
                                        ;   in Loop: Header=BB1_25 Depth=2
	s_or_b32 exec_lo, exec_lo, s23
	s_branch .LBB1_30
.LBB1_29:                               ;   in Loop: Header=BB1_25 Depth=2
	s_mov_b32 s24, -1
.LBB1_30:                               ; %Flow
                                        ;   in Loop: Header=BB1_25 Depth=2
                                        ; implicit-def: $sgpr23
	s_delay_alu instid0(SALU_CYCLE_1)
	s_and_saveexec_b32 s25, s24
; %bb.31:                               ;   in Loop: Header=BB1_25 Depth=2
	s_and_b32 s21, 0xffff, s21
	s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)
	s_add_i32 s21, s21, 1
	s_sext_i32_i16 s23, s21
	s_delay_alu instid0(SALU_CYCLE_1) | instskip(SKIP_1) | instid1(SALU_CYCLE_1)
	s_cmp_le_i32 s1, s23
	s_cselect_b32 s22, -1, 0
	s_or_not1_b32 s22, s22, exec_lo
; %bb.32:                               ; %Flow172
                                        ;   in Loop: Header=BB1_25 Depth=2
	s_or_b32 exec_lo, exec_lo, s25
	s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)
	s_and_b32 s22, exec_lo, s22
	s_or_b32 s10, s22, s10
	s_delay_alu instid0(SALU_CYCLE_1)
	s_and_not1_b32 exec_lo, exec_lo, s10
	s_cbranch_execnz .LBB1_25
; %bb.33:                               ; %Flow173
                                        ;   in Loop: Header=BB1_2 Depth=1
	s_or_b32 exec_lo, exec_lo, s10
.LBB1_34:                               ; %._crit_edge102
                                        ;   in Loop: Header=BB1_2 Depth=1
	s_delay_alu instid0(VALU_DEP_1)
	v_cmp_ge_i16_e32 vcc_lo, v14, v8
	s_mov_b32 s10, exec_lo
	s_or_not1_b32 s21, vcc_lo, exec_lo
.LBB1_35:                               ; %Flow180
                                        ;   in Loop: Header=BB1_2 Depth=1
	s_or_b32 exec_lo, exec_lo, s11
	s_and_saveexec_b32 s11, s21
	s_cbranch_execz .LBB1_47
; %bb.36:                               ;   in Loop: Header=BB1_2 Depth=1
	s_mov_b32 s22, 0
	s_mov_b32 s21, exec_lo
                                        ; implicit-def: $vgpr7
	v_cmpx_le_i32_e64 s16, v11
	s_cbranch_execz .LBB1_46
; %bb.37:                               ; %.preheader80
                                        ;   in Loop: Header=BB1_2 Depth=1
	v_add_nc_u16 v7, v13, 2
	v_mov_b32_e32 v13, 1
	s_and_not1_b32 vcc_lo, exec_lo, s18
	s_cbranch_vccnz .LBB1_45
; %bb.38:                               ; %.lr.ph107.preheader
                                        ;   in Loop: Header=BB1_2 Depth=1
	s_delay_alu instid0(VALU_DEP_2)
	v_bfe_i32 v11, v7, 0, 16
	s_mov_b32 s23, 0
	s_mov_b32 s24, 0
.LBB1_39:                               ; %.lr.ph107
                                        ;   Parent Loop BB1_2 Depth=1
                                        ; =>  This Inner Loop Header: Depth=2
	s_sext_i32_i16 s25, s23
	s_getpc_b64 s[26:27]
	s_add_u32 s26, s26, ADAPTOR@rel32@lo+4
	s_addc_u32 s27, s27, ADAPTOR@rel32@hi+12
	s_ashr_i32 s28, s25, 31
	s_add_u32 s26, s25, s26
	s_addc_u32 s27, s28, s27
	s_mov_b32 s25, -1
	global_load_u8 v13, v2, s[26:27]
	s_mov_b32 s27, -1
                                        ; implicit-def: $sgpr26
	s_waitcnt vmcnt(0)
	v_cmp_eq_u16_e32 vcc_lo, 0x4e, v13
	s_cbranch_vccnz .LBB1_41
; %bb.40:                               ;   in Loop: Header=BB1_39 Depth=2
	v_add_nc_u32_e32 v14, s24, v11
	s_mov_b32 s26, 2
	s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(VALU_DEP_2)
	v_ashrrev_i32_e32 v15, 31, v14
	v_add_co_u32 v14, vcc_lo, v6, v14
	v_add_co_ci_u32_e32 v15, vcc_lo, v12, v15, vcc_lo
	global_load_u8 v14, v[14:15], off
	s_waitcnt vmcnt(0)
	v_cmp_eq_u16_e32 vcc_lo, v14, v13
	s_or_not1_b32 s27, vcc_lo, exec_lo
.LBB1_41:                               ; %Flow176
                                        ;   in Loop: Header=BB1_39 Depth=2
	v_mov_b32_e32 v13, s26
                                        ; implicit-def: $sgpr24
	s_and_saveexec_b32 s26, s27
; %bb.42:                               ;   in Loop: Header=BB1_39 Depth=2
	s_and_b32 s23, 0xffff, s23
	v_mov_b32_e32 v13, 1
	s_add_i32 s23, s23, 1
	s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)
	s_sext_i32_i16 s24, s23
	s_cmp_le_i32 s16, s24
	s_cselect_b32 s25, -1, 0
	s_delay_alu instid0(SALU_CYCLE_1)
	s_or_not1_b32 s25, s25, exec_lo
; %bb.43:                               ; %Flow177
                                        ;   in Loop: Header=BB1_39 Depth=2
	s_or_b32 exec_lo, exec_lo, s26
	s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)
	s_and_b32 s25, exec_lo, s25
	s_or_b32 s22, s25, s22
	s_delay_alu instid0(SALU_CYCLE_1)
	s_and_not1_b32 exec_lo, exec_lo, s22
	s_cbranch_execnz .LBB1_39
; %bb.44:                               ; %Flow178
                                        ;   in Loop: Header=BB1_2 Depth=1
	s_or_b32 exec_lo, exec_lo, s22
.LBB1_45:                               ; %._crit_edge108
                                        ;   in Loop: Header=BB1_2 Depth=1
	s_delay_alu instid0(VALU_DEP_1)
	v_cmp_lt_i32_e32 vcc_lo, v13, v8
	s_and_b32 s22, vcc_lo, exec_lo
.LBB1_46:                               ; %Flow182
                                        ;   in Loop: Header=BB1_2 Depth=1
	s_or_b32 exec_lo, exec_lo, s21
	s_delay_alu instid0(SALU_CYCLE_1) | instskip(SKIP_1) | instid1(SALU_CYCLE_1)
	s_and_not1_b32 s10, s10, exec_lo
	s_and_b32 s21, s22, exec_lo
	s_or_b32 s10, s10, s21
.LBB1_47:                               ; %Flow181
                                        ;   in Loop: Header=BB1_2 Depth=1
	s_or_b32 exec_lo, exec_lo, s11
	s_delay_alu instid0(SALU_CYCLE_1)
	s_and_b32 exec_lo, exec_lo, s10
	s_cbranch_execz .LBB1_49
; %bb.48:                               ; %.sink.split
                                        ;   in Loop: Header=BB1_2 Depth=1
	global_store_b16 v[4:5], v7, off
.LBB1_49:                               ;   in Loop: Header=BB1_2 Depth=1
	s_or_b32 exec_lo, exec_lo, s0
	v_add_co_u32 v0, vcc_lo, v0, s17
	v_add_co_ci_u32_e32 v1, vcc_lo, 0, v1, vcc_lo
	v_add_co_u32 v3, s0, v3, s20
	s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_3)
	v_add_co_ci_u32_e64 v10, s0, s19, v10, s0
	v_cmp_le_i64_e32 vcc_lo, s[2:3], v[0:1]
	s_or_b32 s12, vcc_lo, s12
	s_delay_alu instid0(SALU_CYCLE_1)
	s_and_not1_b32 exec_lo, exec_lo, s12
	s_cbranch_execnz .LBB1_2
.LBB1_50:                               ; %Flow194
	s_nop 0
	s_sendmsg sendmsg(MSG_DEALLOC_VGPRS)
	s_endpgm
	.section	.rodata,"a",@progbits
	.p2align	6, 0x0
	.amdhsa_kernel _Z13TrimmAdaptorsPcPsis
		.amdhsa_group_segment_fixed_size 0
		.amdhsa_private_segment_fixed_size 0
		.amdhsa_kernarg_size 280
		.amdhsa_user_sgpr_count 15
		.amdhsa_user_sgpr_dispatch_ptr 0
		.amdhsa_user_sgpr_queue_ptr 0
		.amdhsa_user_sgpr_kernarg_segment_ptr 1
		.amdhsa_user_sgpr_dispatch_id 0
		.amdhsa_user_sgpr_private_segment_size 0
		.amdhsa_wavefront_size32 1
		.amdhsa_uses_dynamic_stack 0
		.amdhsa_enable_private_segment 0
		.amdhsa_system_sgpr_workgroup_id_x 1
		.amdhsa_system_sgpr_workgroup_id_y 0
		.amdhsa_system_sgpr_workgroup_id_z 0
		.amdhsa_system_sgpr_workgroup_info 0
		.amdhsa_system_vgpr_workitem_id 0
		.amdhsa_next_free_vgpr 19
		.amdhsa_next_free_sgpr 29
		.amdhsa_float_round_mode_32 0
		.amdhsa_float_round_mode_16_64 0
		.amdhsa_float_denorm_mode_32 3
		.amdhsa_float_denorm_mode_16_64 3
		.amdhsa_dx10_clamp 1
		.amdhsa_ieee_mode 1
		.amdhsa_fp16_overflow 0
		.amdhsa_workgroup_processor_mode 1
		.amdhsa_memory_ordered 1
		.amdhsa_forward_progress 0
		.amdhsa_shared_vgpr_count 0
		.amdhsa_exception_fp_ieee_invalid_op 0
		.amdhsa_exception_fp_denorm_src 0
		.amdhsa_exception_fp_ieee_div_zero 0
		.amdhsa_exception_fp_ieee_overflow 0
		.amdhsa_exception_fp_ieee_underflow 0
		.amdhsa_exception_fp_ieee_inexact 0
		.amdhsa_exception_int_div_zero 0
	.end_amdhsa_kernel
	.text
.Lfunc_end1:
	.size	_Z13TrimmAdaptorsPcPsis, .Lfunc_end1-_Z13TrimmAdaptorsPcPsis
                                        ; -- End function
	.section	.AMDGPU.csdata,"",@progbits
; Kernel info:
; codeLenInByte = 1540
; NumSgprs: 31
; NumVgprs: 19
; ScratchSize: 0
; MemoryBound: 0
; FloatMode: 240
; IeeeMode: 1
; LDSByteSize: 0 bytes/workgroup (compile time only)
; SGPRBlocks: 3
; VGPRBlocks: 2
; NumSGPRsForWavesPerEU: 31
; NumVGPRsForWavesPerEU: 19
; Occupancy: 16
; WaveLimiterHint : 1
; COMPUTE_PGM_RSRC2:SCRATCH_EN: 0
; COMPUTE_PGM_RSRC2:USER_SGPR: 15
; COMPUTE_PGM_RSRC2:TRAP_HANDLER: 0
; COMPUTE_PGM_RSRC2:TGID_X_EN: 1
; COMPUTE_PGM_RSRC2:TGID_Y_EN: 0
; COMPUTE_PGM_RSRC2:TGID_Z_EN: 0
; COMPUTE_PGM_RSRC2:TIDIG_COMP_CNT: 0
	.text
	.protected	_Z10TrimmQualsPcPsis    ; -- Begin function _Z10TrimmQualsPcPsis
	.globl	_Z10TrimmQualsPcPsis
	.p2align	8
	.type	_Z10TrimmQualsPcPsis,@function
_Z10TrimmQualsPcPsis:                   ; @_Z10TrimmQualsPcPsis
; %bb.0:
	s_clause 0x1
	s_load_b32 s4, s[0:1], 0x24
	s_load_b64 s[6:7], s[0:1], 0x10
	s_add_u32 s2, s0, 24
	s_addc_u32 s3, s1, 0
	s_waitcnt lgkmcnt(0)
	s_and_b32 s8, s4, 0xffff
	s_ashr_i32 s5, s6, 31
	v_mad_u64_u32 v[1:2], null, s15, s8, v[0:1]
	v_mov_b32_e32 v2, 0
	s_mov_b32 s4, s6
	s_mov_b32 s6, exec_lo
	s_delay_alu instid0(VALU_DEP_1)
	v_cmpx_gt_i64_e64 s[4:5], v[1:2]
	s_cbranch_execz .LBB2_16
; %bb.1:                                ; %.lr.ph47
	s_getpc_b64 s[10:11]
	s_add_u32 s10, s10, QUAL_PADDING@rel32@lo+4
	s_addc_u32 s11, s11, QUAL_PADDING@rel32@hi+12
	s_getpc_b64 s[12:13]
	s_add_u32 s12, s12, MIN_QUAL@rel32@lo+4
	s_addc_u32 s13, s13, MIN_QUAL@rel32@hi+12
	global_load_u16 v0, v2, s[10:11]
	s_getpc_b64 s[10:11]
	s_add_u32 s10, s10, MIN_AVERAGE_QUAL_AFTER_BAD@rel32@lo+4
	s_addc_u32 s11, s11, MIN_AVERAGE_QUAL_AFTER_BAD@rel32@hi+12
	s_clause 0x1
	global_load_i16 v3, v2, s[12:13]
	global_load_i16 v7, v2, s[10:11]
	s_load_b32 s9, s[2:3], 0x0
	s_load_b128 s[0:3], s[0:1], 0x0
	s_mov_b32 s6, s7
	s_delay_alu instid0(SALU_CYCLE_1)
	s_bfe_i64 s[6:7], s[6:7], 0x100000
	s_waitcnt lgkmcnt(0)
	s_mul_i32 s8, s9, s8
	s_mov_b32 s9, 0
	s_waitcnt vmcnt(2)
	v_bfe_i32 v4, v0, 0, 16
	s_waitcnt vmcnt(1)
	s_delay_alu instid0(VALU_DEP_1)
	v_add_nc_u32_e32 v8, v4, v3
.LBB2_2:                                ; =>This Loop Header: Depth=1
                                        ;     Child Loop BB2_4 Depth 2
                                        ;       Child Loop BB2_7 Depth 3
	v_lshlrev_b64 v[3:4], 1, v[1:2]
	s_mov_b32 s10, exec_lo
	s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_2)
	v_add_co_u32 v3, vcc_lo, s2, v3
	v_add_co_ci_u32_e32 v4, vcc_lo, s3, v4, vcc_lo
	global_load_u16 v9, v[3:4], off
	s_waitcnt vmcnt(0)
	v_cmpx_lt_i16_e32 0, v9
	s_cbranch_execz .LBB2_15
; %bb.3:                                ; %.lr.ph44
                                        ;   in Loop: Header=BB2_2 Depth=1
	v_mad_u64_u32 v[5:6], null, v1, s6, s[0:1]
	v_mul_lo_u32 v10, v1, s7
	v_mul_lo_u32 v11, v2, s6
	v_and_b32_e32 v9, 0xffff, v9
	s_mov_b32 s11, 0
	s_mov_b32 s15, 0
                                        ; implicit-def: $sgpr12
                                        ; implicit-def: $sgpr13
	s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_2)
	v_add3_u32 v6, v11, v6, v10
	v_add_nc_u32_e32 v10, 1, v9
.LBB2_4:                                ;   Parent Loop BB2_2 Depth=1
                                        ; =>  This Loop Header: Depth=2
                                        ;       Child Loop BB2_7 Depth 3
	v_add_co_u32 v11, vcc_lo, v5, s15
	s_delay_alu instid0(VALU_DEP_3)
	v_add_co_ci_u32_e32 v12, vcc_lo, 0, v6, vcc_lo
	s_add_i32 s14, s15, 1
	s_mov_b32 s16, -1
	s_mov_b32 s18, -1
	global_load_i8 v11, v[11:12], off
	s_mov_b32 s17, exec_lo
                                        ; implicit-def: $sgpr19
	s_waitcnt vmcnt(0)
	v_cmpx_ge_i32_e64 v8, v11
	s_cbranch_execz .LBB2_10
; %bb.5:                                ; %.preheader
                                        ;   in Loop: Header=BB2_4 Depth=2
	v_mov_b32_e32 v11, 0
	s_mov_b32 s18, exec_lo
	v_cmpx_lt_u32_e64 s14, v9
	s_cbranch_execz .LBB2_9
; %bb.6:                                ; %.lr.ph.preheader
                                        ;   in Loop: Header=BB2_4 Depth=2
	v_dual_mov_b32 v12, s14 :: v_dual_mov_b32 v11, 0
	s_mov_b32 s19, 0
.LBB2_7:                                ; %.lr.ph
                                        ;   Parent Loop BB2_2 Depth=1
                                        ;     Parent Loop BB2_4 Depth=2
                                        ; =>    This Inner Loop Header: Depth=3
	s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(VALU_DEP_3)
	v_bfe_i32 v13, v12, 0, 16
	v_add_nc_u16 v12, v12, 1
	v_sub_nc_u16 v11, v11, v0
	s_delay_alu instid0(VALU_DEP_3) | instskip(SKIP_1) | instid1(VALU_DEP_2)
	v_ashrrev_i32_e32 v14, 31, v13
	v_add_co_u32 v13, vcc_lo, v5, v13
	v_add_co_ci_u32_e32 v14, vcc_lo, v6, v14, vcc_lo
	v_cmp_ge_i16_e32 vcc_lo, v12, v9
	global_load_i8 v13, v[13:14], off
	s_or_b32 s19, vcc_lo, s19
	s_waitcnt vmcnt(0)
	v_add_nc_u16 v11, v11, v13
	s_and_not1_b32 exec_lo, exec_lo, s19
	s_cbranch_execnz .LBB2_7
; %bb.8:                                ; %Flow65
                                        ;   in Loop: Header=BB2_4 Depth=2
	s_or_b32 exec_lo, exec_lo, s19
.LBB2_9:                                ; %Flow66
                                        ;   in Loop: Header=BB2_4 Depth=2
	s_delay_alu instid0(SALU_CYCLE_1) | instskip(SKIP_3) | instid1(VALU_DEP_2)
	s_or_b32 exec_lo, exec_lo, s18
	v_subrev_nc_u32_e32 v12, s15, v10
	v_bfe_i32 v11, v11, 0, 16
	s_mov_b32 s19, -1
	v_mul_lo_u32 v12, v12, v7
	s_delay_alu instid0(VALU_DEP_1)
	v_cmp_le_i32_e32 vcc_lo, v12, v11
	s_or_not1_b32 s18, vcc_lo, exec_lo
.LBB2_10:                               ; %Flow67
                                        ;   in Loop: Header=BB2_4 Depth=2
	s_or_b32 exec_lo, exec_lo, s17
	v_mov_b32_e32 v11, s15
	s_and_not1_b32 s13, s13, exec_lo
	s_and_b32 s17, s19, exec_lo
	s_delay_alu instid0(SALU_CYCLE_1)
	s_or_b32 s13, s13, s17
	s_and_saveexec_b32 s17, s18
; %bb.11:                               ; %.critedge
                                        ;   in Loop: Header=BB2_4 Depth=2
	v_cmp_eq_u32_e32 vcc_lo, s14, v9
	v_mov_b32_e32 v11, s15
	s_and_not1_b32 s13, s13, exec_lo
	s_or_not1_b32 s16, vcc_lo, exec_lo
; %bb.12:                               ; %Flow68
                                        ;   in Loop: Header=BB2_4 Depth=2
	s_or_b32 exec_lo, exec_lo, s17
	s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)
	s_and_b32 s15, exec_lo, s16
	s_or_b32 s11, s15, s11
	s_and_not1_b32 s12, s12, exec_lo
	s_and_b32 s15, s13, exec_lo
	s_delay_alu instid0(SALU_CYCLE_1)
	s_or_b32 s12, s12, s15
	s_mov_b32 s15, s14
	s_and_not1_b32 exec_lo, exec_lo, s11
	s_cbranch_execnz .LBB2_4
; %bb.13:                               ; %loop.exit.guard
                                        ;   in Loop: Header=BB2_2 Depth=1
	s_or_b32 exec_lo, exec_lo, s11
	s_and_saveexec_b32 s11, s12
	s_delay_alu instid0(SALU_CYCLE_1)
	s_xor_b32 s11, exec_lo, s11
	s_cbranch_execz .LBB2_15
; %bb.14:                               ;   in Loop: Header=BB2_2 Depth=1
	global_store_b16 v[3:4], v11, off
.LBB2_15:                               ; %Flow69
                                        ;   in Loop: Header=BB2_2 Depth=1
	s_or_b32 exec_lo, exec_lo, s10
	v_add_co_u32 v1, vcc_lo, v1, s8
	v_add_co_ci_u32_e32 v2, vcc_lo, 0, v2, vcc_lo
	s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(SALU_CYCLE_1)
	v_cmp_le_i64_e32 vcc_lo, s[4:5], v[1:2]
	s_or_b32 s9, vcc_lo, s9
	s_and_not1_b32 exec_lo, exec_lo, s9
	s_cbranch_execnz .LBB2_2
.LBB2_16:                               ; %Flow71
	s_nop 0
	s_sendmsg sendmsg(MSG_DEALLOC_VGPRS)
	s_endpgm
	.section	.rodata,"a",@progbits
	.p2align	6, 0x0
	.amdhsa_kernel _Z10TrimmQualsPcPsis
		.amdhsa_group_segment_fixed_size 0
		.amdhsa_private_segment_fixed_size 0
		.amdhsa_kernarg_size 280
		.amdhsa_user_sgpr_count 15
		.amdhsa_user_sgpr_dispatch_ptr 0
		.amdhsa_user_sgpr_queue_ptr 0
		.amdhsa_user_sgpr_kernarg_segment_ptr 1
		.amdhsa_user_sgpr_dispatch_id 0
		.amdhsa_user_sgpr_private_segment_size 0
		.amdhsa_wavefront_size32 1
		.amdhsa_uses_dynamic_stack 0
		.amdhsa_enable_private_segment 0
		.amdhsa_system_sgpr_workgroup_id_x 1
		.amdhsa_system_sgpr_workgroup_id_y 0
		.amdhsa_system_sgpr_workgroup_id_z 0
		.amdhsa_system_sgpr_workgroup_info 0
		.amdhsa_system_vgpr_workitem_id 0
		.amdhsa_next_free_vgpr 15
		.amdhsa_next_free_sgpr 20
		.amdhsa_float_round_mode_32 0
		.amdhsa_float_round_mode_16_64 0
		.amdhsa_float_denorm_mode_32 3
		.amdhsa_float_denorm_mode_16_64 3
		.amdhsa_dx10_clamp 1
		.amdhsa_ieee_mode 1
		.amdhsa_fp16_overflow 0
		.amdhsa_workgroup_processor_mode 1
		.amdhsa_memory_ordered 1
		.amdhsa_forward_progress 0
		.amdhsa_shared_vgpr_count 0
		.amdhsa_exception_fp_ieee_invalid_op 0
		.amdhsa_exception_fp_denorm_src 0
		.amdhsa_exception_fp_ieee_div_zero 0
		.amdhsa_exception_fp_ieee_overflow 0
		.amdhsa_exception_fp_ieee_underflow 0
		.amdhsa_exception_fp_ieee_inexact 0
		.amdhsa_exception_int_div_zero 0
	.end_amdhsa_kernel
	.text
.Lfunc_end2:
	.size	_Z10TrimmQualsPcPsis, .Lfunc_end2-_Z10TrimmQualsPcPsis
                                        ; -- End function
	.section	.AMDGPU.csdata,"",@progbits
; Kernel info:
; codeLenInByte = 724
; NumSgprs: 22
; NumVgprs: 15
; ScratchSize: 0
; MemoryBound: 0
; FloatMode: 240
; IeeeMode: 1
; LDSByteSize: 0 bytes/workgroup (compile time only)
; SGPRBlocks: 2
; VGPRBlocks: 1
; NumSGPRsForWavesPerEU: 22
; NumVGPRsForWavesPerEU: 15
; Occupancy: 16
; WaveLimiterHint : 0
; COMPUTE_PGM_RSRC2:SCRATCH_EN: 0
; COMPUTE_PGM_RSRC2:USER_SGPR: 15
; COMPUTE_PGM_RSRC2:TRAP_HANDLER: 0
; COMPUTE_PGM_RSRC2:TGID_X_EN: 1
; COMPUTE_PGM_RSRC2:TGID_Y_EN: 0
; COMPUTE_PGM_RSRC2:TGID_Z_EN: 0
; COMPUTE_PGM_RSRC2:TIDIG_COMP_CNT: 0
	.text
	.p2alignl 7, 3214868480
	.fill 96, 4, 3214868480
	.protected	ADAPTOR                 ; @ADAPTOR
	.type	ADAPTOR,@object
	.section	.bss,"aw",@nobits
	.globl	ADAPTOR
	.p2align	4, 0x0
ADAPTOR:
	.zero	100
	.size	ADAPTOR, 100

	.protected	ADAPTOR_LEN             ; @ADAPTOR_LEN
	.type	ADAPTOR_LEN,@object
	.globl	ADAPTOR_LEN
	.p2align	1, 0x0
ADAPTOR_LEN:
	.short	0                               ; 0x0
	.size	ADAPTOR_LEN, 2

	.protected	MAX_MM                  ; @MAX_MM
	.type	MAX_MM,@object
	.data
	.globl	MAX_MM
	.p2align	1, 0x0
MAX_MM:
	.short	2                               ; 0x2
	.size	MAX_MM, 2

	.protected	QUAL_PADDING            ; @QUAL_PADDING
	.type	QUAL_PADDING,@object
	.globl	QUAL_PADDING
	.p2align	1, 0x0
QUAL_PADDING:
	.short	33                              ; 0x21
	.size	QUAL_PADDING, 2

	.protected	MIN_QUAL                ; @MIN_QUAL
	.type	MIN_QUAL,@object
	.globl	MIN_QUAL
	.p2align	1, 0x0
MIN_QUAL:
	.short	20                              ; 0x14
	.size	MIN_QUAL, 2

	.protected	MIN_AVERAGE_QUAL_AFTER_BAD ; @MIN_AVERAGE_QUAL_AFTER_BAD
	.type	MIN_AVERAGE_QUAL_AFTER_BAD,@object
	.globl	MIN_AVERAGE_QUAL_AFTER_BAD
	.p2align	1, 0x0
MIN_AVERAGE_QUAL_AFTER_BAD:
	.short	25                              ; 0x19
	.size	MIN_AVERAGE_QUAL_AFTER_BAD, 2

	.type	__hip_cuid_,@object             ; @__hip_cuid_
	.section	.bss,"aw",@nobits
	.globl	__hip_cuid_
__hip_cuid_:
	.byte	0                               ; 0x0
	.size	__hip_cuid_, 1

	.ident	"AMD clang version 18.0.0git (https://github.com/RadeonOpenCompute/llvm-project roc-6.3.2 25012 e5bf7e55c91490b07c49d8960fa7983d864936c4)"
	.section	".note.GNU-stack","",@progbits
	.addrsig
	.addrsig_sym ADAPTOR
	.addrsig_sym ADAPTOR_LEN
	.addrsig_sym MAX_MM
	.addrsig_sym QUAL_PADDING
	.addrsig_sym MIN_QUAL
	.addrsig_sym MIN_AVERAGE_QUAL_AFTER_BAD
	.addrsig_sym __hip_cuid_
	.amdgpu_metadata
---
amdhsa.kernels:
  - .args:
      - .address_space:  global
        .offset:         0
        .size:           8
        .value_kind:     global_buffer
      - .address_space:  global
        .offset:         8
        .size:           8
        .value_kind:     global_buffer
      - .offset:         16
        .size:           4
        .value_kind:     by_value
      - .offset:         20
        .size:           2
        .value_kind:     by_value
      - .offset:         24
        .size:           4
        .value_kind:     hidden_block_count_x
      - .offset:         28
        .size:           4
        .value_kind:     hidden_block_count_y
      - .offset:         32
        .size:           4
        .value_kind:     hidden_block_count_z
      - .offset:         36
        .size:           2
        .value_kind:     hidden_group_size_x
      - .offset:         38
        .size:           2
        .value_kind:     hidden_group_size_y
      - .offset:         40
        .size:           2
        .value_kind:     hidden_group_size_z
      - .offset:         42
        .size:           2
        .value_kind:     hidden_remainder_x
      - .offset:         44
        .size:           2
        .value_kind:     hidden_remainder_y
      - .offset:         46
        .size:           2
        .value_kind:     hidden_remainder_z
      - .offset:         64
        .size:           8
        .value_kind:     hidden_global_offset_x
      - .offset:         72
        .size:           8
        .value_kind:     hidden_global_offset_y
      - .offset:         80
        .size:           8
        .value_kind:     hidden_global_offset_z
      - .offset:         88
        .size:           2
        .value_kind:     hidden_grid_dims
    .group_segment_fixed_size: 0
    .kernarg_segment_align: 8
    .kernarg_segment_size: 280
    .language:       OpenCL C
    .language_version:
      - 2
      - 0
    .max_flat_workgroup_size: 1024
    .name:           _Z9Find_gRNAPcPsis
    .private_segment_fixed_size: 0
    .sgpr_count:     31
    .sgpr_spill_count: 0
    .symbol:         _Z9Find_gRNAPcPsis.kd
    .uniform_work_group_size: 1
    .uses_dynamic_stack: false
    .vgpr_count:     19
    .vgpr_spill_count: 0
    .wavefront_size: 32
    .workgroup_processor_mode: 1
  - .args:
      - .address_space:  global
        .offset:         0
        .size:           8
        .value_kind:     global_buffer
      - .address_space:  global
        .offset:         8
        .size:           8
        .value_kind:     global_buffer
      - .offset:         16
        .size:           4
        .value_kind:     by_value
      - .offset:         20
        .size:           2
        .value_kind:     by_value
      - .offset:         24
        .size:           4
        .value_kind:     hidden_block_count_x
      - .offset:         28
        .size:           4
        .value_kind:     hidden_block_count_y
      - .offset:         32
        .size:           4
        .value_kind:     hidden_block_count_z
      - .offset:         36
        .size:           2
        .value_kind:     hidden_group_size_x
      - .offset:         38
        .size:           2
        .value_kind:     hidden_group_size_y
      - .offset:         40
        .size:           2
        .value_kind:     hidden_group_size_z
      - .offset:         42
        .size:           2
        .value_kind:     hidden_remainder_x
      - .offset:         44
        .size:           2
        .value_kind:     hidden_remainder_y
      - .offset:         46
        .size:           2
        .value_kind:     hidden_remainder_z
      - .offset:         64
        .size:           8
        .value_kind:     hidden_global_offset_x
      - .offset:         72
        .size:           8
        .value_kind:     hidden_global_offset_y
      - .offset:         80
        .size:           8
        .value_kind:     hidden_global_offset_z
      - .offset:         88
        .size:           2
        .value_kind:     hidden_grid_dims
    .group_segment_fixed_size: 0
    .kernarg_segment_align: 8
    .kernarg_segment_size: 280
    .language:       OpenCL C
    .language_version:
      - 2
      - 0
    .max_flat_workgroup_size: 1024
    .name:           _Z13TrimmAdaptorsPcPsis
    .private_segment_fixed_size: 0
    .sgpr_count:     31
    .sgpr_spill_count: 0
    .symbol:         _Z13TrimmAdaptorsPcPsis.kd
    .uniform_work_group_size: 1
    .uses_dynamic_stack: false
    .vgpr_count:     19
    .vgpr_spill_count: 0
    .wavefront_size: 32
    .workgroup_processor_mode: 1
  - .args:
      - .address_space:  global
        .offset:         0
        .size:           8
        .value_kind:     global_buffer
      - .address_space:  global
        .offset:         8
        .size:           8
        .value_kind:     global_buffer
      - .offset:         16
        .size:           4
        .value_kind:     by_value
      - .offset:         20
        .size:           2
        .value_kind:     by_value
      - .offset:         24
        .size:           4
        .value_kind:     hidden_block_count_x
      - .offset:         28
        .size:           4
        .value_kind:     hidden_block_count_y
      - .offset:         32
        .size:           4
        .value_kind:     hidden_block_count_z
      - .offset:         36
        .size:           2
        .value_kind:     hidden_group_size_x
      - .offset:         38
        .size:           2
        .value_kind:     hidden_group_size_y
      - .offset:         40
        .size:           2
        .value_kind:     hidden_group_size_z
      - .offset:         42
        .size:           2
        .value_kind:     hidden_remainder_x
      - .offset:         44
        .size:           2
        .value_kind:     hidden_remainder_y
      - .offset:         46
        .size:           2
        .value_kind:     hidden_remainder_z
      - .offset:         64
        .size:           8
        .value_kind:     hidden_global_offset_x
      - .offset:         72
        .size:           8
        .value_kind:     hidden_global_offset_y
      - .offset:         80
        .size:           8
        .value_kind:     hidden_global_offset_z
      - .offset:         88
        .size:           2
        .value_kind:     hidden_grid_dims
    .group_segment_fixed_size: 0
    .kernarg_segment_align: 8
    .kernarg_segment_size: 280
    .language:       OpenCL C
    .language_version:
      - 2
      - 0
    .max_flat_workgroup_size: 1024
    .name:           _Z10TrimmQualsPcPsis
    .private_segment_fixed_size: 0
    .sgpr_count:     22
    .sgpr_spill_count: 0
    .symbol:         _Z10TrimmQualsPcPsis.kd
    .uniform_work_group_size: 1
    .uses_dynamic_stack: false
    .vgpr_count:     15
    .vgpr_spill_count: 0
    .wavefront_size: 32
    .workgroup_processor_mode: 1
amdhsa.target:   amdgcn-amd-amdhsa--gfx1100
amdhsa.version:
  - 1
  - 2
...

	.end_amdgpu_metadata
