void processQueryFile(AlignmentArgs_t * AAs) { ///// // Open files, and initialize structures // The compressed genome and index structures are read only and shared amonst threads via AAs. ///// // Open the query file. openQueryFile(AAs); // Open the genome file. char *gfilePtr; FSIZE gfileSize; FDES gfp = openForRead(AAs->gfileName, &gfileSize, &gfilePtr, TRUE); // Read in the .nib2 file header. BaseSequences_t * BSs = loadBaseSequences(gfilePtr); normalizeBaseSequences(BSs); if (AAs->verbose) fprintf(stderr, "Read in %d reference sequences from %s.\n", BSs->curCount, AAs->gfileName); AAs->BSs = BSs; AAs->basePtr = BSs->basePtr; AAs->maxROff = baseSequencesMaxROff(BSs); // Open the output alignment file. // We have no idea how much output we will generate. // It will be all written sequentially. // So, no fancy memory mapped IO for this output. // Just do formatted ouput. AAs->outFile = openForPrint(AAs->ofileName); #ifdef QUERYSTATS if (AAs->queryStats) { AAs->qsFile = openForPrint(AAs->qsfileName); } #endif // Some of the file formats have headers. outputFileHeader(AAs); // Open the index file. // This is harder as it requires putting all pointers to various pieces back together. char *xfilePtr; FSIZE xfileSize; FDES xfp = openForRead(AAs->xfileName, &xfileSize, &xfilePtr, TRUE); // Start by getting the wordLen and totalCount from the file Header. UINT *xuintPtr = (UINT *)xfilePtr; int version = xuintPtr[0]; if (version != CURRENT_INDEX_FILE_VERSION) fatalError("Index file version is out of date.\nPlease remake index file and try again."); AAs->wordLen = xuintPtr[1]; int fileMaxHits = xuintPtr[2]; if (fileMaxHits < AAs->maxHits) { fprintf(stderr, "WARNING: Index file made with maxHits of %d, while %d specified for this query run.\n" "Mimimum of two (%d) will be used.\n", fileMaxHits, AAs->maxHits, fileMaxHits); AAs->maxHits = fileMaxHits; } // Now we can recalculate the hash table size. UINT HTsize = iexp(4, AAs->wordLen); // Now we will walk through the various structures, assigning pointers of right type to right spots. FSIZE sizeofUINT = sizeof(UINT); FSIZE inputSize; // Space for four numbers in header. inputSize = 4*sizeofUINT; FSIZE startingOffBase = inputSize; // Space for reference starting Offsets array. inputSize += sizeofUINT * (HTsize + 1); FSIZE referenceBase = inputSize; // We've calculated all the offsets, now get the pointers. AAs->startingOffs = (ROFF *)(xfilePtr + startingOffBase); AAs->ROAPtr = (ROFF *)(xfilePtr + referenceBase); #ifdef DEBUG fprintf(stderr, "Number of Hash Tables entries is %u, and ROA has %u entries.\n", HTsize, (UINT)((xfileSize-inputSize)/sizeof(ROFF))); fprintf(stderr, "Hash Table sizes are as follows: offs=%zd, refs=%zd.\n", sizeof(UINT)*(HTsize + 1), xfileSize-inputSize); fprintf(stderr, "The index pointers are: xfilePtr=%p, sOffsPtr=%p, and refPtr=%p\n", xfilePtr, startingOffs, refs); #endif // Read in first query to get an estimate of the size of the queries in the file. QueryState_t * QS = makeQueryState(AAs); readNextQuery(AAs, QS); calcNewMaxQueryLength(QS); QOFF maxQueryLength = QS->maxQueryLength; initializeQueries(QS); // Create extra threads. // We will use the main thread as well, so only need to spawn one less than requested. int numthreads = AAs->numThreads - 1; pthread_t * threads = NULL; if (numthreads > 0) { // Keep the thread count to something the machine can handle. int nprocs = get_nprocs(); if (numthreads + 1 > nprocs) { fprintf(stderr, "Warning. Requested number of threads (%d) is greater than number of processors." " %d threads will be used.\n", AAs->numThreads, nprocs); numthreads = nprocs - 1; } // Do the storage allocation for threads. // We allocate the thread local storage here as well to avoid malloc contention while spawning threads. threads = (pthread_t *)malloc(numthreads * sizeof(pthread_t)); for (int i=0; i<numthreads; i++) { QueryState_t * QS = makeQueryState(AAs); // Set in an initial value for maxQueryLength based on first query read. QS->maxQueryLength = maxQueryLength; initializeQueries(QS); pthread_t * thread = threads+i; int err = pthread_create(thread, NULL, &processQueries, QS); // If we fail to create the thread for any reason, bail from trying to make more. if (err != 0) { fprintf(stderr, "Warning. Thread creation resulted in error %d. %d threads will be used.\n", err, i+1); numthreads = i; // Deallocate the unused thread local structures. finalizeQueries(QS); disposeQueryState(QS); break; } } } // Now also do work in this thread. // This won't return until the query file is exhausted. processQueries(QS); // Wait for all the rest of the threads (if any) to finish. for (int i=0; i<numthreads; i++) { pthread_join(threads[i], NULL); } if (threads != NULL) free(threads); // Free resources. // First close files. closeQueryFile(AAs); closeForRead(gfp, gfileSize, gfilePtr); closeForRead(xfp, xfileSize, xfilePtr); closeForPrint(AAs->outFile); #ifdef QUERYSTATS if (AAs->queryStats) { closeForPrint(AAs->qsFile); } #endif // Free allocated structures. disposeBaseSequences(BSs); }
// ============================================= /// @brief Do random printf tests - glibc vc ours /// We use random width, an random optional precision /// @param[in] flag: 'f' or 'F' or 'e' or 'E' /// @param[in] longf: add 'l' to format string /// @return void MEMSPACE void random_tests(int flag, char *size) { int snum; int inum; long lnum; long long llnum; double dnum, scale; int width,prec; int exp10; int shift; int precf; double sign; int digits; int dotf; int signind; char *signop = "+- 0"; char format[1024]; char tmp[1024]; memset(format,0,128); if(drand48() >= .5) sign = 1.0; else sign = -1.0; if(drand48() >= .5) precf = 1; else precf = 0; if(drand48() >= .5) dotf = 1; else dotf = 0; signind = drand48() * 3.99999; //printf("num:%ld\n",num); // With f we limit the exponent to +/-2 ** sizeof(long long) if(flag == 'e' || flag == 'f' ) { /* * Single mantissa 24bits base10 digits 7.22 * exponent 8bits base10 exponent 37 * Double mantissa 53bits base10 digits 15.95 * exponent 11bits base10 exponent 307 */ // We only test exponent to +/- digits * 2 // If we test numbers greater then (10 ** digits) we start getting // roundoff/truncation errors // // Glibc printf uses extended precision functions (ie. > double size) if(sizeof(double) == 8) { digits = 16; } else if(sizeof(double) == 4) { digits = 7; } else { fprintf(stderr,"Unexpected size of double:%d\n",(int)sizeof(double)); exit(1); } width = drand48() * 2.0 * digits; prec = drand48() * 2.0 * digits; if(precf || dotf) snprintf(format,sizeof(format)-1, "%%%c%d.%d%c", signop[signind], width, prec, flag); else snprintf(format,sizeof(format)-1, "%%%c%d%c", signop[signind], width, flag); exp10 = ((drand48() * 2.0) - 1.0) * (double) (digits * 2); scale = iexp(10.0, exp10); dnum = ( sign * drand48() * scale); tp(format, dnum); } else /* ASSUME integer or long arguments */ { if(strcmp(size,"short") == 0) { width = drand48() * (double)(sizeof(short) * 8)/3.321928095; prec = drand48() * (double)(sizeof(short) * 8)/3.321928095; shift = drand48() * (double) sizeof(int) * 8; scale = pow(2.0, shift); inum = (int) ( sign * drand48() * scale); if(precf || dotf) snprintf(format,sizeof(format)-1, "%%%c%d.%dh%c", signop[signind], width, prec, flag); else snprintf(format,sizeof(format)-1, "%%%c%dh%c", signop[signind], width, flag); tp(format, inum); } else if(strcmp(size,"int") == 0) { width = drand48() * (double)(sizeof(int) * 8)/3.321928095; prec = drand48() * (double)(sizeof(int) * 8)/3.321928095; shift = drand48() * (double) sizeof(int) * 8; scale = pow(2.0, shift); inum = (int) ( sign * drand48() * scale); if(precf || dotf) snprintf(format,sizeof(format)-1, "%%%c%d.%d%c", signop[signind], width, prec, flag); else snprintf(format,sizeof(format)-1, "%%%c%d%c", signop[signind], width, flag); tp(format, inum); } else if(strcmp(size,"long") == 0) { width = drand48() * (double)(sizeof(long) * 8)/3.321928095; prec = drand48() * (double)(sizeof(long) * 8)/3.321928095; shift = drand48() * (double) sizeof(long) * 8; scale = pow(2.0, shift); lnum = (long) ( sign * drand48() * scale); if(precf || dotf) snprintf(format,sizeof(format)-1, "%%%c%d.%dl%c", signop[signind], width, prec, flag); else snprintf(format,sizeof(format)-1, "%%%c%dl%c", signop[signind], width, flag); tp(format, lnum); } else if(strcmp(size,"long long") == 0) { width = drand48() * (double)(sizeof(long long) * 8)/3.321928095; prec = drand48() * (double)(sizeof(long long) * 8)/3.321928095; shift = drand48() * (double) sizeof(long long) * 8; scale = pow(2.0, shift); llnum = (long) ( sign * drand48() * scale); if(precf || dotf) snprintf(format,sizeof(format)-1, "%%%c%d.%dll%c", signop[signind], width, prec, flag); else snprintf(format,sizeof(format)-1, "%%%c%dll%c", signop[signind], width, flag); tp(format, llnum); } else { fprintf(stderr,"random_tests: bad size[%s]\n", size); exit(1); } } }