Ejemplo n.º 1
0
int GBASamples::build_sample(uint32_t pointer)
{	// Do nothing if sample already exists
	for (int i=samples_list.size()-1; i >= 0; --i)
		if (samples_list[i] == pointer) return i;

	// Read sample data
	if (fseek(inGBA, pointer, SEEK_SET)) throw -1;

	struct
	{
		uint32_t loop;
		uint32_t pitch;
		uint32_t loop_pos;
		uint32_t len;
	}
	hdr;
	fread(&hdr, 4, 4, inGBA);

	//Now we should make sure the data is coherent, and reject
	//the samples if errors are suspected

	//Detect invalid samples
	bool loop_en;
    bool bdpcm_en = false;

	if (hdr.loop == 0x40000000)
		loop_en = true;
	else if (hdr.loop == 0x00000000)
		loop_en = false;
	else if (hdr.loop == 0x1)
	{
		bdpcm_en = true;    // Detect compressed samples
	    loop_en = false;
	}
	else
		throw -1;			// Invalid loop -> return error

	// Compute SF2 base note and fine tune from GBA pitch
	// GBA pitch is 1024 * Mid_C frequency
	double delta_note = 12 * log2(sf2->default_sample_rate * 1024.0 / hdr.pitch);
	double int_delta_note = round(delta_note);
	unsigned int pitch_correction = int((int_delta_note - delta_note) * 100);
	unsigned int original_pitch = 60 + (int)int_delta_note;

	// Detect Golden Sun samples
	if (goldensun_synth && hdr.len == 0 && hdr.loop_pos == 0)
	{
		if (fgetc(inGBA) != 0x80) throw -1;
		uint8_t type = fgetc(inGBA);
		switch (type)
		{
			case 0:		// Square wave
			{
				std::string name = "Square @0x" + hex(pointer);
				uint8_t duty_cycle = fgetc(inGBA);
				uint8_t change_speed = fgetc(inGBA);
				if (change_speed == 0)
				{	// Square wave with constant duty cycle
					unsigned int base_pointer = 128 + 64 * (duty_cycle >> 2);
					sf2->add_new_sample(goldensun_synth, UNSIGNED_8, name.c_str(), base_pointer, 64, true, 0, original_pitch, pitch_correction);
				}
				else
				{	// Sqaure wave with variable duty cycle, not exact, but sounds close enough
					sf2->add_new_sample(goldensun_synth, UNSIGNED_8, name.c_str(), 128, 8192, true, 0, original_pitch, pitch_correction);
				}
			}	break;

			case 1:		// Saw wave
			{
				std::string name = "Saw @0x" + hex(pointer);
				sf2->add_new_sample(goldensun_synth, UNSIGNED_8, name.c_str(), 0, 64, true, 0, original_pitch, pitch_correction);
			}	break;

			case 2:		// Triangle wave
			{
				std::string name = "Triangle @0x" + hex(pointer);
				sf2->add_new_sample(goldensun_synth, UNSIGNED_8, name.c_str(), 64, 64, true, 0, original_pitch, pitch_correction);
			}	break;

			default :
				throw -1;
		}
Ejemplo n.º 2
0
static EF_Error ef_internal_video_load_texture_gd_image(gdImage *image,
							GLuint id,
							int build_mipmaps)
{
    GLint pixel_format;
    GLint component_format;
    GLsizei size;
    uint8_t *data;
    
    int width = gdImageSX(image);
    int height = gdImageSY(image);
    int widthLog2 = ceil(log2(width));
    int heightLog2 = ceil(log2(height));
    int sizeLog2 = widthLog2 > heightLog2 ? widthLog2 : heightLog2;
    size = 1;
    for(int i = 0; i < sizeLog2; i++)
	size *= 2;
    
    pixel_format = GL_RGBA;
    
    component_format = GL_UNSIGNED_BYTE;
    
    data = malloc(size*size*4);
    for(int y = 0; y < size; y++) {
	for(int x = 0; x < size; x++) {
	    if((y < height) && (x < width)) {
		int color = gdImageGetPixel(image, x, y);
		data[(x + y*size)*4] = gdImageRed(image, color);
		data[(x + y*size)*4+1] = gdImageGreen(image, color);
		data[(x + y*size)*4+2] = gdImageBlue(image, color);
		int alpha = (127 - gdImageAlpha(image, color)) * 2;
		data[(x + y*size)*4+3] = alpha;
	    } else {
		data[(x + y*size)*4] = 0x00;
		data[(x + y*size)*4+1] = 0x00;
		data[(x + y*size)*4+2] = 0x00;
		data[(x + y*size)*4+3] = 0x00;
	    }
	}
    }
    
    glBindTexture(GL_TEXTURE_2D, id);
    
    glPixelStorei(GL_UNPACK_ROW_LENGTH, size);
    glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, size);
    
    if(build_mipmaps) {
	gluBuild2DMipmaps(GL_TEXTURE_2D,
			  pixel_format,
			  size, size,
			  pixel_format,
			  component_format,
			  data);
    } else {
	glTexImage2D(GL_TEXTURE_2D,
		     0,
		     pixel_format,
		     size, size,
		     0,
		     pixel_format,
		     component_format,
		     data);
    }
    
    free(data);

    glBindTexture(GL_TEXTURE_2D, 0);
}
Ejemplo n.º 3
0
/* the function called by each thread is "mainLoop" */
void*
mainLoop(void* arg)
{
  loopArg *loopA = (loopArg*)arg;
  istream* testSStream = loopA->inpt;
  ostream* pstatStream = loopA->outpt;
  int id = loopA->id;
  double log600 = log2(600.0);
  PrintStack printStack;
  for( ;  ; )
    {
      InputTree     correct;  
      InputTree*    cuse;

      /* first lock to read in the material */
      pthread_mutex_lock(&readlock);
      if( !*testSStream ) {
	pthread_mutex_unlock(&readlock);
	break;
      }
      *testSStream >> correct;
      if( !*testSStream ){
	pthread_mutex_unlock(&readlock);
	break;
      }
      totWords += correct.length()+1;
      int locCount = sentenceCount++;
      list<ECString>  wtList;
      correct.make(wtList);
      SentRep sr( wtList );  // used in precision calc

      ExtPos extPos;
      if(params.extPosIfstream)
	extPos.read(params.extPosIfstream,sr);
      pthread_mutex_unlock(&readlock);

      cuse = &correct;
      int len = correct.length();
      if(len > params.maxSentLen) continue;
      //cerr << "Len = " << len << endl;
      /*
	if( !params.field().in(sentenceCount) )
	{
	sentenceCount++;
	continue;
	}
	if(sentenceCount < -1)
	{
	sentenceCount++;
	continue;
	}
	sentenceCount++;
      */
      vector<ECString> poslist;
      correct.makePosList(poslist);
      ScoreTree sc;
      sc.setEquivInts(poslist);
      MeChart*	chart = new MeChart( sr,extPos,id );
       
      chart->parse( );
      Item* topS = chart->topS();
      if(!topS)
	{
	  cerr << "Parse failed" << endl;
	  cerr << correct << endl;
	  error(" could not parse "); 
	  delete chart;
	  continue;
	}
       
      // compute the outside probabilities on the items so that we can
      // skip doing detailed computations on the really bad ones 

      chart->set_Alphas();

      Bst& bst = chart->findMapParse();
      if( bst.empty()) error( "mapProbs did not return answer");
      float bestF = -1;
      int i;
      int numVersions = 0;
      Link diffs(0);
      //cerr << "Need num diff: " << Bchart::Nth << endl;
      printStruct printS;
      printS.sentenceCount = locCount;
      printS.numDiff = 0;
      for(numVersions = 0 ; ; numVersions++)
	{
	  short pos = 0;
	  Val* val = bst.next(numVersions);
	  if(!val)
	    {
	      //cerr << "Breaking" << endl;
	      break;
	    }
	  InputTree*  mapparse = inputTreeFromBsts(val,pos,sr);
	  bool isU;
	  int dummy = 0;
	  diffs.is_unique(mapparse, isU, dummy);
	  // cerr << "V " << isU << " " << numVersions << *mapparse << endl;
	  if(isU)
	    {
	      printS.probs.push_back(val->prob());
	      printS.trees.push_back(mapparse);
	      printS.numDiff++;
	    }
	  else
	    {
	      delete mapparse;
	    }
	  if(printS.numDiff >= Bchart::Nth) break;
	  if(numVersions > 20000) break;
	}

      ParseStats* locPst = new ParseStats[Bchart::Nth];
      ParseStats bestPs;
      for(i = 0 ; i <printS.numDiff ; i++)
	{
	  InputTree *mapparse = printS.trees[i];
	  assert(mapparse);
	  sc.trips.clear();
	  ParseStats pSt;
	  sc.recordGold(cuse,pSt);
	  sc.precisionRecall(mapparse,pSt);
	  float newF = pSt.fMeasure();
	  cerr << printS.sentenceCount << "\t" << newF << endl;
	  if(newF > bestF)
	    {
	      bestF = newF;
	      bestPs = pSt;
	    }
	  if(histPoints[i])
	    {
	      locPst[i] += bestPs;
	    }
	}
      if(printS.numDiff < Bchart::Nth)
	{
	  for(i = printS.numDiff ; i < Bchart::Nth ; i++)
	    {
	      if(histPoints[i]) locPst[i] += bestPs;
	    }
	}

      pthread_mutex_lock(&scorelock);
      for(i = 0 ; i < Bchart::Nth ; i++) totPst[i]+=locPst[i];
      pthread_mutex_unlock(&scorelock);

      int numPrinted;

      /* put the sentence with which we just finished at the end of the printStack*/
      printStack.push_back(printS);
      PrintStack::iterator psi = printStack.begin();
      /* now look at each item from the front of the print stack
	 to see if it should be printed now */
      pthread_mutex_lock(&writelock);
      for( numPrinted =0; psi != printStack.end(); numPrinted++ )
	{
	  printStruct& pstr=(*psi);
	  if(pstr.sentenceCount != printCount) break;
	  *pstatStream << pstr.sentenceCount << "\t" << pstr.numDiff << "\n";
	  printCount++;
	  for(i = 0 ; i < pstr.numDiff ; i++)
	    {
	      InputTree*  mapparse = pstr.trees[i];
	      assert(mapparse);
	      double logP =log2(pstr.probs[i]);
	      logP -= (sr.length()*log600);
	      *pstatStream <<  logP << "\n";
	      if(Bchart::prettyPrint) *pstatStream << *mapparse << "\n\n";
	      else
		{
		  mapparse->printproper(*pstatStream);
		  *pstatStream << "\n";
		}
	      delete mapparse;
	    }
	  *pstatStream << endl;
	  psi++;
	}
      pthread_mutex_unlock(&writelock);
      for(i = 0 ; i < numPrinted ; i++) printStack.pop_front();
      if(Feature::isLM)
	{
	  double lgram = log2(bst.sum());
	  lgram -= (sr.length()*log600);
	  double pgram = pow(2,lgram);
	  double iptri = chart->triGram();;
	  double ltri = (log2(iptri)-sr.length()*log600);
	  double ptri = pow(2.0,ltri);
	  double pcomb1 = (0.667 * pgram)+(0.333 * ptri);
	  double lcom1 = log2(pcomb1);
	  totGram -= lgram;
	  totTri -= ltri;
	  totMix -= lcom1;
	  if(locCount%10 == 9)
	    {
	      cerr << locCount << "\t";
	      cerr << pow(2.0,totGram/(double)totWords);
	      cerr <<"\t" <<  pow(2.0,totTri/(double)totWords);
	      cerr << "\t" << pow(2.0,totMix/(double)(totWords));
	      cerr << endl;
	    }
	}
      if(locCount%50 == 1)
	{
	  cerr << sentenceCount << "\t";
	  for(int i = 0 ; i < Bchart::Nth ; i++)
	    if(histPoints[i])
	      {
		cerr << i << " " << totPst[i].fMeasure() << "\t";
	      }
	  cerr << endl;
	}

      delete chart;
      delete [] locPst;
    }
  return 0;
}
Ejemplo n.º 4
0
int ms_pack_text
   (DATA_HDR	*hdr0,		/* ptr to initial data hdr.		*/
    BS		*init_bs,	/* ptr to onetime blockettes.		*/
    char	*data,		/* ptr to data buffer.			*/
    int		num_samples,	/* number of data samples.		*/
    int		*n_blocks,	/* # miniSEED blocks (returned).	*/
    char	**pp_ms,	/* ptr **miniSEED (returned).		*/
    int		ms_len,		/* miniSEED buffer len (if supplied).	*/
    char	*p_errmsg)	/* ptr to error msg buffer.		*/
{
    DATA_HDR *hdr;		/* data header used for writing miniSEED*/
    char *p_ms;			/* ptr to current miniSEED block.	*/
    void *p_packed;		/* ptr to packed output data.		*/
    char errmsg[256];		/* error msg buffer.			*/
    int ipt;			/* index of data to pack.		*/
    int nblks_malloced;		/* # of miniSEED output blocks malloced.*/
    int num_blocks;		/* # of miniSEED block created.		*/
    int samples_remaining;	/* # samples left to cvt to miniseed.	*/
    int nsamples;		/* # of samples in miniSEED block.	*/
    int max_bytes;		/* max # of data bytes in record.	*/
    int nbytes;			/* # of bytes packed into record.	*/
    int seconds, usecs;		/* seconds and usecs for time calcs.	*/
    int pad;			/* flag to indicate padding of frames.	*/
    int blksize = hdr0->blksize;/* output blksize.			*/

    /* Initialization.							*/
    *n_blocks = 0;

    /* Check for invalid arguments.					*/
    if (num_samples <= 0) return(MS_ERROR);
    if (blksize < 128 ||
	(blksize != (int)pow(2.0,rint(log2((double)blksize))))) {
	sprintf (errmsg, "Warning: invalid blksize: %d\n", blksize);
	if (p_errmsg) strcpy(p_errmsg, errmsg);
	else fprintf (stderr, "%s", errmsg);
	return (MS_ERROR);
    }

    /* If *pp_ms != NULL, assume that the caller is providing sufficient*/
    /* memory to hold all of the resulting miniSEED records.		*/
    /* If it is NULL, we allocate the space, and set it to point to the	*/
    /* allocated miniSEED records.					*/
    /* If we allocated the space for the miniSEED, the caller is	*/
    /* responsible for freeing the space.				*/
    if (*pp_ms) nblks_malloced = -1;
    else nblks_malloced = 0;

    /* Create a copy of the initial data_hdr for our use.		*/
    /* We will update this each time we create a miniSEED block.	*/
    hdr = dup_data_hdr (hdr0);
    if (hdr == NULL) {
	return (MS_ERROR);
    }

    /* Start compressor.						*/
    num_blocks = 0;
    samples_remaining = num_samples;
    ipt = 0;
    pad = 1;

    while (samples_remaining) {
	/* Check for available space.					*/
	/* Allocate more space for Mini-SEED blocks if necessary.	*/
	if (nblks_malloced < 0) {
	    if (ms_len < blksize) {
		*n_blocks = num_blocks;
		free_data_hdr (hdr);
		return (num_samples - samples_remaining);
	    }
	    ms_len -= blksize;
	}
	if (nblks_malloced >= 0 && num_blocks == nblks_malloced) {
	    *pp_ms = (*pp_ms == NULL) ?
		(char *)malloc((nblks_malloced+MALLOC_INCREMENT)*blksize) :
		(char *)realloc(*pp_ms,(nblks_malloced+MALLOC_INCREMENT)*blksize);
	    if (*pp_ms == NULL) {
		sprintf (errmsg, "Error mallocing miniSEED buffer\n");
		if (p_errmsg) strcpy(p_errmsg, errmsg);
		else fprintf (stderr, "%s", errmsg);
		free_data_hdr (hdr);
		return (QLIB2_MALLOC_ERROR);
	    }
	    nblks_malloced += MALLOC_INCREMENT;
	}

	/* Initialize the next fixed data header.			*/
	p_ms = *pp_ms + (num_blocks * blksize);
	if (init_miniseed_hdr ((SDR_HDR *)p_ms, hdr, init_bs) < 0) {
	    sprintf (errmsg, "Error: initializing MiniSEED header");
	    if (p_errmsg) strcpy(p_errmsg, errmsg);
	    else fprintf (stderr, "%s", errmsg);
	    free_data_hdr (hdr);
	    if (nblks_malloced > 0) free(*pp_ms);
	    return (MS_ERROR);
	}
	init_bs = NULL;
	p_packed = (void *)(p_ms + hdr->first_data);
	max_bytes = blksize + 1 - hdr->first_data;

	/* Pack the rest of the miniSEED record with text lines.	*/
	pack_text ((char *)p_packed, (char *)&data[ipt], samples_remaining, 
		   max_bytes, pad, hdr->data_wordorder, &nbytes, &nsamples);

	/* End of data or Mini-SEED block is full.			*/
	/* Update Mini-SEED header with:				*/
	/*	final sample count.					*/
	/* Update hdr for the next record.				*/
	hdr->num_samples = nsamples;
	update_miniseed_hdr ((SDR_HDR *)p_ms, hdr);
	ms_pack_update_hdr (hdr, 1, nsamples, (void *)&data[ipt]);
	ipt += nsamples;
	samples_remaining -= nsamples;
	++num_blocks;
	hdr->num_samples = 0;
    }

    /* Cleanup.								*/
    free_data_hdr (hdr);
    *n_blocks = num_blocks;
    ms_pack_update_return_hdr (hdr0, num_blocks, num_samples, (void *)data);
    return(num_samples);
}
Ejemplo n.º 5
0
void HRTFPanner::pan(double desiredAzimuth, double elevation, const AudioBus* inputBus, AudioBus* outputBus, size_t framesToProcess)
{
    unsigned numInputChannels = inputBus ? inputBus->numberOfChannels() : 0;

    bool isInputGood = inputBus &&  numInputChannels >= 1 && numInputChannels <= 2;
    ASSERT(isInputGood);

    bool isOutputGood = outputBus && outputBus->numberOfChannels() == 2 && framesToProcess <= outputBus->length();
    ASSERT(isOutputGood);

    if (!isInputGood || !isOutputGood) {
        if (outputBus)
            outputBus->zero();
        return;
    }

    HRTFDatabase* database = m_databaseLoader->database();
    ASSERT(database);
    if (!database) {
        outputBus->zero();
        return;
    }

    // IRCAM HRTF azimuths values from the loaded database is reversed from the panner's notion of azimuth.
    double azimuth = -desiredAzimuth;

    bool isAzimuthGood = azimuth >= -180.0 && azimuth <= 180.0;
    ASSERT(isAzimuthGood);
    if (!isAzimuthGood) {
        outputBus->zero();
        return;
    }

    // Normally, we'll just be dealing with mono sources.
    // If we have a stereo input, implement stereo panning with left source processed by left HRTF, and right source by right HRTF.
    const AudioChannel* inputChannelL = inputBus->channelByType(AudioBus::ChannelLeft);
    const AudioChannel* inputChannelR = numInputChannels > 1 ? inputBus->channelByType(AudioBus::ChannelRight) : 0;

    // Get source and destination pointers.
    const float* sourceL = inputChannelL->data();
    const float* sourceR = numInputChannels > 1 ? inputChannelR->data() : sourceL;
    float* destinationL = outputBus->channelByType(AudioBus::ChannelLeft)->mutableData();
    float* destinationR = outputBus->channelByType(AudioBus::ChannelRight)->mutableData();

    double azimuthBlend;
    int desiredAzimuthIndex = calculateDesiredAzimuthIndexAndBlend(azimuth, azimuthBlend);

    // Initially snap azimuth and elevation values to first values encountered.
    if (m_azimuthIndex1 == UninitializedAzimuth) {
        m_azimuthIndex1 = desiredAzimuthIndex;
        m_elevation1 = elevation;
    }
    if (m_azimuthIndex2 == UninitializedAzimuth) {
        m_azimuthIndex2 = desiredAzimuthIndex;
        m_elevation2 = elevation;
    }

    // Cross-fade / transition over a period of around 45 milliseconds.
    // This is an empirical value tuned to be a reasonable trade-off between
    // smoothness and speed.
    const double fadeFrames = sampleRate() <= 48000 ? 2048 : 4096;

    // Check for azimuth and elevation changes, initiating a cross-fade if needed.
    if (!m_crossfadeX && m_crossfadeSelection == CrossfadeSelection1) {
        if (desiredAzimuthIndex != m_azimuthIndex1 || elevation != m_elevation1) {
            // Cross-fade from 1 -> 2
            m_crossfadeIncr = 1 / fadeFrames;
            m_azimuthIndex2 = desiredAzimuthIndex;
            m_elevation2 = elevation;
        }
    }
    if (m_crossfadeX == 1 && m_crossfadeSelection == CrossfadeSelection2) {
        if (desiredAzimuthIndex != m_azimuthIndex2 || elevation != m_elevation2) {
            // Cross-fade from 2 -> 1
            m_crossfadeIncr = -1 / fadeFrames;
            m_azimuthIndex1 = desiredAzimuthIndex;
            m_elevation1 = elevation;
        }
    }

    // This algorithm currently requires that we process in power-of-two size chunks at least RenderingQuantum.
    ASSERT(1UL << static_cast<int>(log2(framesToProcess)) == framesToProcess);
    ASSERT(framesToProcess >= RenderingQuantum);

    const unsigned framesPerSegment = RenderingQuantum;
    const unsigned numberOfSegments = framesToProcess / framesPerSegment;

    for (unsigned segment = 0; segment < numberOfSegments; ++segment) {
        // Get the HRTFKernels and interpolated delays.
        HRTFKernel* kernelL1;
        HRTFKernel* kernelR1;
        HRTFKernel* kernelL2;
        HRTFKernel* kernelR2;
        double frameDelayL1;
        double frameDelayR1;
        double frameDelayL2;
        double frameDelayR2;
        database->getKernelsFromAzimuthElevation(azimuthBlend, m_azimuthIndex1, m_elevation1, kernelL1, kernelR1, frameDelayL1, frameDelayR1);
        database->getKernelsFromAzimuthElevation(azimuthBlend, m_azimuthIndex2, m_elevation2, kernelL2, kernelR2, frameDelayL2, frameDelayR2);

        bool areKernelsGood = kernelL1 && kernelR1 && kernelL2 && kernelR2;
        ASSERT(areKernelsGood);
        if (!areKernelsGood) {
            outputBus->zero();
            return;
        }

        ASSERT(frameDelayL1 / sampleRate() < MaxDelayTimeSeconds && frameDelayR1 / sampleRate() < MaxDelayTimeSeconds);
        ASSERT(frameDelayL2 / sampleRate() < MaxDelayTimeSeconds && frameDelayR2 / sampleRate() < MaxDelayTimeSeconds);

        // Crossfade inter-aural delays based on transitions.
        double frameDelayL = (1 - m_crossfadeX) * frameDelayL1 + m_crossfadeX * frameDelayL2;
        double frameDelayR = (1 - m_crossfadeX) * frameDelayR1 + m_crossfadeX * frameDelayR2;

        // Calculate the source and destination pointers for the current segment.
        unsigned offset = segment * framesPerSegment;
        const float* segmentSourceL = sourceL + offset;
        const float* segmentSourceR = sourceR + offset;
        float* segmentDestinationL = destinationL + offset;
        float* segmentDestinationR = destinationR + offset;

        // First run through delay lines for inter-aural time difference.
        m_delayLineL.setDelayFrames(frameDelayL);
        m_delayLineR.setDelayFrames(frameDelayR);
        m_delayLineL.process(segmentSourceL, segmentDestinationL, framesPerSegment);
        m_delayLineR.process(segmentSourceR, segmentDestinationR, framesPerSegment);

        bool needsCrossfading = m_crossfadeIncr;
        
        // Have the convolvers render directly to the final destination if we're not cross-fading.
        float* convolutionDestinationL1 = needsCrossfading ? m_tempL1.data() : segmentDestinationL;
        float* convolutionDestinationR1 = needsCrossfading ? m_tempR1.data() : segmentDestinationR;
        float* convolutionDestinationL2 = needsCrossfading ? m_tempL2.data() : segmentDestinationL;
        float* convolutionDestinationR2 = needsCrossfading ? m_tempR2.data() : segmentDestinationR;

        // Now do the convolutions.
        // Note that we avoid doing convolutions on both sets of convolvers if we're not currently cross-fading.
        
        if (m_crossfadeSelection == CrossfadeSelection1 || needsCrossfading) {
            m_convolverL1.process(kernelL1->fftFrame(), segmentDestinationL, convolutionDestinationL1, framesPerSegment);
            m_convolverR1.process(kernelR1->fftFrame(), segmentDestinationR, convolutionDestinationR1, framesPerSegment);
        }

        if (m_crossfadeSelection == CrossfadeSelection2 || needsCrossfading) {
            m_convolverL2.process(kernelL2->fftFrame(), segmentDestinationL, convolutionDestinationL2, framesPerSegment);
            m_convolverR2.process(kernelR2->fftFrame(), segmentDestinationR, convolutionDestinationR2, framesPerSegment);
        }
        
        if (needsCrossfading) {
            // Apply linear cross-fade.
            float x = m_crossfadeX;
            float incr = m_crossfadeIncr;
            for (unsigned i = 0; i < framesPerSegment; ++i) {
                segmentDestinationL[i] = (1 - x) * convolutionDestinationL1[i] + x * convolutionDestinationL2[i];
                segmentDestinationR[i] = (1 - x) * convolutionDestinationR1[i] + x * convolutionDestinationR2[i];
                x += incr;
            }
            // Update cross-fade value from local.
            m_crossfadeX = x;

            if (m_crossfadeIncr > 0 && fabs(m_crossfadeX - 1) < m_crossfadeIncr) {
                // We've fully made the crossfade transition from 1 -> 2.
                m_crossfadeSelection = CrossfadeSelection2;
                m_crossfadeX = 1;
                m_crossfadeIncr = 0;
            } else if (m_crossfadeIncr < 0 && fabs(m_crossfadeX) < -m_crossfadeIncr) {
                // We've fully made the crossfade transition from 2 -> 1.
                m_crossfadeSelection = CrossfadeSelection1;
                m_crossfadeX = 0;
                m_crossfadeIncr = 0;
            }
        }
    }
}
Ejemplo n.º 6
0
void TreeConstruction(particle_t* SPH, node_t* node){
	//node関連の変数セット
	int num_node = 0;
	//host.num_group = 0;
	struct{
		double x, y, z;
	}max, min, half_length;
	//rootのデータをセット
	min.x = 1.0e+30;
	min.y = 1.0e+30;
	min.z = 1.0e+30;
	max.x = - min.x;
	max.y = - min.y;
	max.z = - min.z;
	
	for(int i = 0 ; i < N_SPHP ; ++ i){
		if(SPH[i].r.x < min.x) min.x = SPH[i].r.x;
		if(SPH[i].r.y < min.y) min.y = SPH[i].r.y;
		if(SPH[i].r.z < min.z) min.z = SPH[i].r.z;
		if(SPH[i].r.x > max.x) max.x = SPH[i].r.x;
		if(SPH[i].r.y > max.y) max.y = SPH[i].r.y;
		if(SPH[i].r.z > max.z) max.z = SPH[i].r.z;
	}
	
	half_length.x = (max.x - min.x) / 2.0;
	half_length.y = (max.y - min.y) / 2.0;
	half_length.z = (max.z - min.z) / 2.0;

	if(N_DIM == 1){
		node[0].half_length = half_length.x;
	}else if(N_DIM == 2){
		if(half_length.x > half_length.y){
			node[0].half_length = half_length.x;
		}else{
			node[0].half_length = half_length.y;
		}
	}else if(N_DIM == 3){
		if(half_length.x > half_length.y){
			node[0].half_length = half_length.x;
		}else{
			node[0].half_length = half_length.y;
		}
		if(node[0].half_length < half_length.z) node[0].half_length = half_length.z;
	}

	node[0].center.x = (max.x + min.x) / 2.0;
	node[0].center.y = (max.y + min.y) / 2.0;
	node[0].center.z = (max.z + min.z) / 2.0;
	node[0].num_particle = N_SPHP;
	node[0].head_particle = 0;
	//================
	//Morton key生成からのソート
	//================
	ulli grid_size = 1 << 20;//多分20分割くらい
	for(int i = 0 ; i < N_SPHP ; ++ i){
		struct{
			ulli x, y, z;
		} grid_address;
		
		grid_address.x = (ulli)((SPH[i].r.x - min.x) / (max.x - min.x) * grid_size - 1.0 / grid_size);
		grid_address.y = (ulli)((SPH[i].r.y - min.y) / (max.y - min.y) * grid_size - 1.0 / grid_size);
		grid_address.z = (ulli)((SPH[i].r.z - min.z) / (max.z - min.z) * grid_size - 1.0 / grid_size);
		SPH[i].zkey = zorder3d(grid_address.x, grid_address.y, grid_address.z);
	}
	qsort(SPH, N_SPHP, sizeof(particle_t), (int(*)(const void*, const void*))keycmp);
	//================
	//tree作る
	//================
	for(int node_id = 0 ; node_id <= num_node ; ++ node_id){
		if(node[node_id].num_particle <= N_LEAF){//ノードの粒子数が<=N_LEAF個だったら…
			//まぁやるべきことは特に無い。。。と。
		}else{//nodeに複数の粒子が入ってたら…
			//branchを作る
			node_t branch[8];
			//nodeに入っているbranchの中の一番小さいidをセット
			node[node_id].head_branch = num_node + 1;
			//more ptrをセット?
			//node[node_id].more = &node[node[node_id].head_branch];
			//branchのデータを初期化
			for(int b = 0 ; b < 8 ; ++ b){
				branch[b].num_particle  = 0;
				branch[b].mass          = 0;
				branch[b].mass_center.x = 0;
				branch[b].mass_center.y = 0;
				branch[b].mass_center.z = 0;
			}
			//tree level取得
			short int level = log2(node[0].half_length / node[node_id].half_length + 0.01);
			//nodeの中の全粒子を各branchに振り分ける
			for (int i = node[node_id].head_particle ; i < node[node_id].head_particle + node[node_id].num_particle ; ++ i){
				//Morton keyから出す。。。
				int branch_id = GetBranchId(SPH[i].zkey, level + 1);
				++ branch[branch_id].num_particle;//所属branchの粒子数をインクリメント
			}
			//branchの重心・質量に関する情報を計算。
			branch[0].head_particle = node[node_id].head_particle;
			for (int b = 1 ; b < 8 ; ++ b) branch[b].head_particle = branch[b-1].head_particle + branch[b-1].num_particle;
			for (int b = 0 ; b < 8 ; ++ b){
				branch[b].half_length = node[node_id].half_length / 2.0;
				for(int i = branch[b].head_particle ; i < branch[b].head_particle + branch[b].num_particle ; ++ i){
					branch[b].mass += SPH[i].m;
					branch[b].mass_center.x += SPH[i].m * SPH[i].r.x;
					branch[b].mass_center.y += SPH[i].m * SPH[i].r.y;
					branch[b].mass_center.z += SPH[i].m * SPH[i].r.z;
				}
				branch[b].mass_center.x /= branch[b].mass;
				branch[b].mass_center.y /= branch[b].mass;
				branch[b].mass_center.z /= branch[b].mass;
			}
			//各branchのサイズに関する情報を計算。泥臭いけどまぁいいや。
			#if N_DIM == 1
				branch[0].center.x = node[node_id].center.x - branch[0].half_length;
				branch[0].center.y = 0;
				branch[0].center.z = 0;

				branch[1].center.x = node[node_id].center.x + branch[1].half_length;
				branch[1].center.y = 0;
				branch[1].center.z = 0;
			#elif N_DIM == 2
				branch[0].center.x = node[node_id].center.x - branch[0].half_length;
				branch[0].center.y = node[node_id].center.y - branch[0].half_length;
				branch[0].center.z = 0;
				
				branch[1].center.x = node[node_id].center.x + branch[1].half_length;
				branch[1].center.y = node[node_id].center.y - branch[1].half_length;
				branch[1].center.z = 0;

				branch[2].center.x = node[node_id].center.x - branch[2].half_length;
				branch[2].center.y = node[node_id].center.y + branch[2].half_length;
				branch[2].center.z = 0;
			
				branch[3].center.x = node[node_id].center.x + branch[3].half_length;
				branch[3].center.y = node[node_id].center.y + branch[3].half_length;
				branch[3].center.z = 0;

			#else
				branch[0].center.x = node[node_id].center.x - branch[0].half_length;
				branch[0].center.y = node[node_id].center.y - branch[0].half_length;
				branch[0].center.z = node[node_id].center.z - branch[0].half_length;

				branch[1].center.x = node[node_id].center.x + branch[1].half_length;
				branch[1].center.y = node[node_id].center.y - branch[1].half_length;
				branch[1].center.z = node[node_id].center.z - branch[1].half_length;

				branch[2].center.x = node[node_id].center.x - branch[2].half_length;
				branch[2].center.y = node[node_id].center.y + branch[2].half_length;
				branch[2].center.z = node[node_id].center.z - branch[2].half_length;

				branch[3].center.x = node[node_id].center.x + branch[3].half_length;
				branch[3].center.y = node[node_id].center.y + branch[3].half_length;
				branch[3].center.z = node[node_id].center.z - branch[3].half_length;
				
				branch[4].center.x = node[node_id].center.x - branch[4].half_length;
				branch[4].center.y = node[node_id].center.y - branch[4].half_length;
				branch[4].center.z = node[node_id].center.z + branch[4].half_length;
				
				branch[5].center.x = node[node_id].center.x + branch[5].half_length;
				branch[5].center.y = node[node_id].center.y - branch[5].half_length;
				branch[5].center.z = node[node_id].center.z + branch[5].half_length;

				branch[6].center.x = node[node_id].center.x - branch[6].half_length;
				branch[6].center.y = node[node_id].center.y + branch[6].half_length;
				branch[6].center.z = node[node_id].center.z + branch[6].half_length;
			
				branch[7].center.x = node[node_id].center.x + branch[7].half_length;
				branch[7].center.y = node[node_id].center.y + branch[7].half_length;
				branch[7].center.z = node[node_id].center.z + branch[7].half_length;
			#endif
			//作成したbranchの情報をbranch classからnode classにコピー。
			node[node_id].num_branch = 0;
			for(int b = 0 ; b < 8 ; ++ b){
				if(branch[b].num_particle != 0){//empty cellだったらコピーしない
					++ node[node_id].num_branch;//node内のbranch数上げる
					int branch_id = num_node + node[node_id].num_branch;//branchのarray id取得
					node[branch_id] = branch[b];
				}
			}
			//ノードの総数を上げる
			num_node += node[node_id].num_branch;
		}
	}
}
Ejemplo n.º 7
0
void Genome::genomeLoad(){//allocate and load Genome
    
    time_t rawtime;
    time ( &rawtime );
    *(P->inOut->logStdOut) << timeMonthDayTime(rawtime) << " ..... Loading genome\n" <<flush;           

    uint *shmNG=NULL, *shmNSA=NULL;   //pointers to shm stored values , *shmSG, *shmSSA
    uint64 shmSize=0;//, shmStartG=0; shmStartSA=0;
    
    uint L=200,K=6;    
    
    Parameters *P1 = new Parameters;
    
    ifstream parFile((P->genomeDir+("/genomeParameters.txt")).c_str());
    if (parFile.good()) {
        P->inOut->logMain << "Reading genome generation parameters:\n";
        P1->inOut = P->inOut;
        P1->scanAllLines(parFile,3,-1);
        parFile.close();
    } else {
        ostringstream errOut;
        errOut << "EXITING because of FATAL ERROR: could not open genome file "<< P->genomeDir+("/genomeParameters.txt") << endl;
        errOut << "SOLUTION: check that the path to genome files, specified in --genomeDir is correct and the files are present, and have user read permsissions\n" <<flush;     
        exitWithError(errOut.str(),std::cerr, P->inOut->logMain, EXIT_CODE_GENOME_FILES, *P);
    };            
    
    //check genome version
    if (P1->versionGenome.size()==0 || P1->versionGenome[0]==0) {//
        ostringstream errOut;
        errOut << "EXITING because of FATAL ERROR: read no value for the versionGenome parameter from genomeParameters.txt file\n";
        errOut << "SOLUTION: please re-generate genome from scratch with the latest version of STAR\n";
        exitWithError(errOut.str(),std::cerr, P->inOut->logMain, EXIT_CODE_GENOME_FILES, *P);
    } else if (P->sjdbFileChrStartEnd.at(0)=="-" && P1->versionGenome.at(0) >= P->versionGenome.at(0)) {//
        P->inOut->logMain << "Genome version is compatible with current STAR version\n";
    } else if (P->sjdbFileChrStartEnd.at(0)!="-" && P1->versionGenome.at(0) >= P->versionGenome.at(1)) {//
        P->inOut->logMain << "Genome version is compatible with current STAR version\n";        
    } else {
        ostringstream errOut;
        errOut << "EXITING because of FATAL ERROR: Genome version is INCOMPATIBLE with current STAR version\n";
        errOut << "SOLUTION: please re-generate genome from scratch with the latest version of STAR\n";
        exitWithError(errOut.str(),std::cerr, P->inOut->logMain, EXIT_CODE_GENOME_FILES, *P);
    };

    //find chr starts from files
    P->chrInfoLoad();

    //check if sjdbInfo.txt exists => genome was generated with junctions
    bool sjdbInfoExists=false;
    struct stat sjdb1;
    if ( stat( (P->genomeDir+"/sjdbInfo.txt").c_str(), &sjdb1) == 0 )
    {//file exists
        sjdbInfoExists=true;
    };
    
    if ( P->sjdbInsert.yes && sjdbInfoExists && P1->sjdbInsert.save=="") 
    {//if sjdbInsert, and genome had junctions, and genome is old - it should be re-generated with new STAR
        ostringstream errOut;
        errOut << "EXITING because of FATAL ERROR: old Genome is INCOMPATIBLE with on the fly junction insertion\n";
        errOut << "SOLUTION: please re-generate genome from scratch with the latest version of STAR\n";
        exitWithError(errOut.str(),std::cerr, P->inOut->logMain, EXIT_CODE_GENOME_FILES, *P);
    };
    
    //record required genome parameters in P
    P->genomeSAindexNbases=P1->genomeSAindexNbases;
    P->genomeChrBinNbits=P1->genomeChrBinNbits;
    P->genomeSAsparseD=P1->genomeSAsparseD;
    if (P->parArray.at(P->sjdbOverhang_par)->inputLevel==0 && P1->sjdbOverhang>0) 
    {//if --sjdbOverhang was not defined by user and it was defined >0 at the genome generation step, then use sjdbOverhang from the genome generation step
        P->sjdbOverhang=P1->sjdbOverhang;
        P->inOut->logMain << "--sjdbOverhang = " << P->sjdbOverhang << " taken from the generated genome\n";
    } else if (sjdbInfoExists && P->parArray.at(P->sjdbOverhang_par)->inputLevel>0 && P->sjdbOverhang!=P1->sjdbOverhang) 
    {//if sjdbOverhang was defined at the genome generation step,the mapping step value has to agree with it
        ostringstream errOut;
        errOut << "EXITING because of fatal PARAMETERS error: present --sjdbOverhang="<<P->sjdbOverhang << " is not equal to the value at the genome generation step ="<< P1->sjdbOverhang << "\n";
        errOut << "SOLUTION: \n" <<flush;     
        exitWithError(errOut.str(),std::cerr, P->inOut->logMain, EXIT_CODE_GENOME_FILES, *P);
    };
    
    P->sjdbLength = P->sjdbOverhang==0 ? 0 : P->sjdbOverhang*2+1;


    P->inOut->logMain << "Started loading the genome: " << asctime (localtime ( &rawtime ))<<"\n"<<flush;    
  
    ifstream GenomeIn, SAin, SAiIn;

    P->nGenome = OpenStream("Genome",GenomeIn);
    P->nSAbyte = OpenStream("SA",SAin);
    OpenStream("/SAindex",SAiIn);

    uint SAiInBytes=0;
    SAiInBytes += fstreamReadBig(SAiIn,(char*) &P->genomeSAindexNbases, sizeof(P->genomeSAindexNbases));
    P->genomeSAindexStart = new uint[P->genomeSAindexNbases+1];
    SAiInBytes += fstreamReadBig(SAiIn,(char*) P->genomeSAindexStart, sizeof(P->genomeSAindexStart[0])*(P->genomeSAindexNbases+1));  
    P->nSAi=P->genomeSAindexStart[P->genomeSAindexNbases];
    P->inOut->logMain << "Read from SAindex: genomeSAindexNbases=" << P->genomeSAindexNbases <<"  nSAi="<< P->nSAi <<endl;
    

    /////////////////////////////////// at this point all array sizes should be known: calculate packed array lengths
    P->GstrandBit = (uint) floor(log(P->nGenome)/log(2))+1;
    if (P->GstrandBit<32) P->GstrandBit=32; //TODO: use simple access function for SA

    P->GstrandMask = ~(1LLU<<P->GstrandBit);
    P->nSA=(P->nSAbyte*8)/(P->GstrandBit+1);
    SA.defineBits(P->GstrandBit+1,P->nSA);  
    
    P->SAiMarkNbit=P->GstrandBit+1;
    P->SAiMarkAbsentBit=P->GstrandBit+2;
    
    P->SAiMarkNmaskC=1LLU << P->SAiMarkNbit;
    P->SAiMarkNmask=~P->SAiMarkNmaskC;
    P->SAiMarkAbsentMaskC=1LLU << P->SAiMarkAbsentBit;
    P->SAiMarkAbsentMask=~P->SAiMarkAbsentMaskC;
    
    SAi.defineBits(P->GstrandBit+3,P->nSAi); 

    P->inOut->logMain << "nGenome=" << P->nGenome << ";  nSAbyte=" << P->nSAbyte <<endl<< flush;       
    P->inOut->logMain <<"GstrandBit="<<int(P->GstrandBit)<<"   SA number of indices="<<P->nSA<<endl<<flush;      
    
    shmSize=SA.lengthByte + P->nGenome+L+L+SHM_startG+8;
    shmSize+= SAi.lengthByte;                
    if (P->annotScoreScale>0) shmSize+=P->nGenome;


    if ((P->genomeLoad=="LoadAndKeep" ||
         P->genomeLoad=="LoadAndRemove" ||
         P->genomeLoad=="LoadAndExit" ||
         P->genomeLoad=="Remove") && sharedMemory == NULL)
    {
        bool unloadLast = P->genomeLoad=="LoadAndRemove";
        try
        {
            sharedMemory = new SharedMemory(shmKey, unloadLast);
            sharedMemory->SetErrorStream(P->inOut->logStdOut);

            if (!sharedMemory->NeedsAllocation())
            P->inOut->logMain <<"Found genome in shared memory\n"<<flush;
    
    if (P->genomeLoad=="Remove") {//kill the genome and exit
                if (sharedMemory->NeedsAllocation()) {//did not find genome in shared memory, nothing to kill
            ostringstream errOut;
            errOut << "EXITING: Did not find the genome in memory, did not remove any genomes from shared memory\n";
            exitWithError(errOut.str(),std::cerr, P->inOut->logMain, EXIT_CODE_GENOME_FILES, *P);
        } else {
                    sharedMemory->Clean();
            P->inOut->logMain <<"DONE: removed the genome from shared memory\n"<<flush;            
                    return;
        };
            }
     
            if (sharedMemory->NeedsAllocation()){
                P->inOut->logMain <<"Allocating shared memory for genome\n"<<flush;
                sharedMemory->Allocate(shmSize);
            }
        }
        catch (const SharedMemoryException & exc)
        {
            HandleSharedMemoryException(exc, shmSize);
        }
    
        shmStart = (char*) sharedMemory->GetMapped();
        shmNG= (uint*) (shmStart+SHM_sizeG);
        shmNSA= (uint*) (shmStart+SHM_sizeSA);       
   
        if (!sharedMemory->IsAllocator())
        {
            // genome is in shared memory or being loaded
            // wait for the process that will populate it
            // and record the sizes
        
        uint iwait=0;
            while (*shmNG != P->nGenome) {
            iwait++;
            P->inOut->logMain <<"Another job is still loading the genome, sleeping for 1 min\n" <<flush;
            sleep(60);                    
            if (iwait==100) {
                ostringstream errOut;
                errOut << "EXITING because of FATAL ERROR: waited too long for the other job to finish loading the genome" << strerror(errno) << "\n" <<flush;
                    errOut << "SOLUTION: remove the shared memory chunk by running STAR with --genomeLoad Remove, and restart STAR" <<flush;     
                    exitWithError(errOut.str(),std::cerr, P->inOut->logMain, EXIT_CODE_GENOME_LOADING_WAITED_TOO_LONG, *P);                
            };
        };

            if (P->nSAbyte!=*shmNSA)
            {
                ostringstream errOut;
                errOut << "EXITING because of FATAL ERROR: the SA file size did not match what we found in shared memory" << "\n" << flush;
                errOut << "SOLUTION: remove the shared memory chunk by running STAR with --genomeLoad Remove, and restart STAR" << flush;     
                exitWithError(errOut.str(),std::cerr, P->inOut->logMain, EXIT_CODE_INCONSISTENT_DATA, *P);  
            }
        
            P->inOut->logMain << "Using shared memory for genome. key=0x" <<hex<<shmKey<<dec<< ";   shmid="<< sharedMemory->GetId() <<endl<<flush;
        }

        G1=shmStart+SHM_startG;
        SA.pointArray(G1+P->nGenome+L+L);
        char* shmNext=SA.charArray+P->nSAbyte;

        SAi.pointArray(shmNext);
        shmNext += SAi.lengthByte;
    
//     if (twoPass.pass1readsN==0) {//not 2-pass
//         shmStartG=SHM_startSHM;
//         shmStartSA=0;
//     } else {//2-pass
//         ostringstream errOut;
//         errOut << "EXITING because of FATAL ERROR: 2-pass procedure cannot be used with genome already loaded im memory'  "\n" ;
//         errOut << "SOLUTION: check shared memory settigns as explained in STAR manual, OR run STAR with --genomeLoad NoSharedMemory to avoid using shared memory\n" <<flush;     
//         exitWithError(errOut.str(),std::cerr, P->inOut->logMain, EXIT_CODE_SHM, *P);
//     };
     if (P->annotScoreScale>0) {//optional allocation
            sigG = shmNext;
            shmNext += P->nGenome;
        }    
    }
    else if (P->genomeLoad=="NoSharedMemory") // simply allocate memory, do not use shared memory
    {
        P->genomeInsertL=0;
        if (P->genomeFastaFiles.at(0)!="-")
        {//will insert sequences in the genome, now estimate the extra size
           uint oldlen=P->chrStart.back();//record the old length
           P->genomeInsertL=genomeScanFastaFiles(P,G,false)-oldlen; 
        };
        
        try {
            
            if (P->sjdbInsert.pass1 || P->sjdbInsert.pass2)
            {//reserve extra memory for insertion at the 1st and/or 2nd step
                nGenomePass1=P->nGenome+P->genomeInsertL;
                nSApass1=P->nSA+2*P->genomeInsertL;
                if (P->sjdbInsert.pass1)
                {
                    nGenomePass1+=P->limitSjdbInsertNsj*P->sjdbLength;
                    nSApass1+=2*P->limitSjdbInsertNsj*P->sjdbLength;
                };
                nGenomePass2=nGenomePass1;
                nSApass2=nSApass1;
                if (P->sjdbInsert.pass2)
                {
                    nGenomePass2+=P->limitSjdbInsertNsj*P->sjdbLength;
                    nSApass2+=2*P->limitSjdbInsertNsj*P->sjdbLength;                    
                };                
                
                G1=new char[nGenomePass2+L+L];        
                
                SApass2.defineBits(P->GstrandBit+1,nSApass2);
                SApass2.allocateArray();
                
                SApass1.defineBits(P->GstrandBit+1,nSApass1);
                SApass1.pointArray(SApass2.charArray+SApass2.lengthByte-SApass1.lengthByte);
                
                SA.pointArray(SApass1.charArray+SApass1.lengthByte-SA.lengthByte);
            } else 
            {//no sjdb insertions
                if (P->genomeInsertL==0)
                {// no sequence insertion, simple allocation
                    G1=new char[P->nGenome+L+L];        
                    SA.allocateArray();
                } else 
                {
                    G1=new char[P->nGenome+L+L+P->genomeInsertL];        
                    SApass1.defineBits(P->GstrandBit+1,P->nSA+2*P->genomeInsertL);//TODO: re-define GstrandBit if necessary
                    SApass1.allocateArray();
                    SA.pointArray(SApass1.charArray+SApass1.lengthByte-SA.lengthByte);
                };

            };            
            SAi.allocateArray();
            P->inOut->logMain <<"Shared memory is not used for genomes. Allocated a private copy of the genome.\n"<<flush;                
        } catch (exception & exc) {
            ostringstream errOut;           
            errOut <<"EXITING: fatal error trying to allocate genome arrays, exception thrown: "<<exc.what()<<endl;
            errOut <<"Possible cause 1: not enough RAM. Check if you have enough RAM " << P->nGenome+L+L+SA.lengthByte+SAi.lengthByte+2000000000 << " bytes\n";
            errOut <<"Possible cause 2: not enough virtual memory allowed with ulimit. SOLUTION: run ulimit -v " <<  P->nGenome+L+L+SA.lengthByte+SAi.lengthByte+2000000000<<endl <<flush;
            exitWithError(errOut.str(),std::cerr, P->inOut->logMain, EXIT_CODE_MEMORY_ALLOCATION, *P);            
        };
        
    }

        
//     if (twopass1readsN==0) {//not 2-pass
//         shmStartG=SHM_startSHM;
//         shmStartSA=0;
//     } else {//2-pass
//         ostringstream errOut;
//         errOut << "EXITING because of FATAL ERROR: 2-pass procedure cannot be used with genome already loaded im memory'  "\n" ;
//         errOut << "SOLUTION: check shared memory settings as explained in STAR manual, OR run STAR with --genomeLoad NoSharedMemory to avoid using shared memory\n" <<flush;     
//         exitWithError(errOut.str(),std::cerr, P->inOut->logMain, EXIT_CODE_SHM, *P);
//     };


    G=G1+L;

    bool isAllocatorProcess = sharedMemory != NULL && sharedMemory->IsAllocator();

    if (P->genomeLoad=="NoSharedMemory" || isAllocatorProcess) {//load genome and SAs from files
        //load genome
        P->inOut->logMain <<"Genome file size: "<<P->nGenome <<" bytes; state: good=" <<GenomeIn.good()\
                <<" eof="<<GenomeIn.eof()<<" fail="<<GenomeIn.fail()<<" bad="<<GenomeIn.bad()<<"\n"<<flush;        
        P->inOut->logMain <<"Loading Genome ... " << flush;        
        uint genomeReadBytesN=fstreamReadBig(GenomeIn,G,P->nGenome);    
        P->inOut->logMain <<"done! state: good=" <<GenomeIn.good()\
                <<" eof="<<GenomeIn.eof()<<" fail="<<GenomeIn.fail()<<" bad="<<GenomeIn.bad()<<"; loaded "<<genomeReadBytesN<<" bytes\n" << flush;            
        GenomeIn.close();
        
        for (uint ii=0;ii<L;ii++) {// attach a tail with the largest symbol
            G1[ii]=K-1;
            G[P->nGenome+ii]=K-1;        
        };    
      
        //load SAs
        P->inOut->logMain <<"SA file size: "<<SA.lengthByte <<" bytes; state: good=" <<SAin.good()\
                <<" eof="<<SAin.eof()<<" fail="<<SAin.fail()<<" bad="<<SAin.bad()<<"\n"<<flush;        
        P->inOut->logMain <<"Loading SA ... " << flush;               
        genomeReadBytesN=fstreamReadBig(SAin,SA.charArray, SA.lengthByte);
        P->inOut->logMain <<"done! state: good=" <<SAin.good()\
                <<" eof="<<SAin.eof()<<" fail="<<SAin.fail()<<" bad="<<SAin.bad()<<"; loaded "<<genomeReadBytesN<<" bytes\n" << flush;            
        SAin.close();
        
        P->inOut->logMain <<"Loading SAindex ... " << flush;             
        SAiInBytes +=fstreamReadBig(SAiIn,SAi.charArray, SAi.lengthByte);
        P->inOut->logMain <<"done: "<<SAiInBytes<<" bytes\n" << flush;       
    };
    
    SAiIn.close();            

    if ((P->genomeLoad=="LoadAndKeep" || 
         P->genomeLoad=="LoadAndRemove" || 
         P->genomeLoad=="LoadAndExit") && isAllocatorProcess ) 
    {
        //record sizes. This marks the end of genome loading
        *shmNG=P->nGenome;
        *shmNSA=P->nSAbyte;
    };
    
    time ( &rawtime );
    P->inOut->logMain << "Finished loading the genome: " << asctime (localtime ( &rawtime )) <<"\n"<<flush;    
      
    #ifdef COMPILE_FOR_MAC
    {
        uint sum1=0;
        for (uint ii=0;ii<P->nGenome; ii++) sum1 +=  (uint) (unsigned char) G[ii];
        P->inOut->logMain << "Sum of all Genome bytes: " <<sum1 <<"\n"<<flush;  
        sum1=0;        
        for (uint ii=0;ii<SA.lengthByte; ii++) sum1 +=  (uint) (unsigned char) SA.charArray[ii];
        P->inOut->logMain << "Sum of all SA bytes: " <<sum1 <<"\n"<<flush;
        sum1=0;        
        for (uint ii=0;ii<SAi.lengthByte; ii++) sum1 +=  (uint) (unsigned char) SAi.charArray[ii];
        P->inOut->logMain << "Sum of all SAi bytes: " <<sum1 <<"\n"<<flush;
    };
    #endif
    
    if (P->genomeLoad=="LoadAndExit") {
	uint shmSum=0;
	for (uint ii=0;ii<shmSize;ii++) shmSum+=shmStart[ii];
        P->inOut->logMain << "genomeLoad=LoadAndExit: completed, the genome is loaded and kept in RAM, EXITING now.\n"<<flush;
        return;
    };
    
    insertSequences();

    P->chrBinFill();
 
    //splice junctions database
    if (P->nGenome==P->chrStart[P->nChrReal]) {//no sjdb
        P->sjdbN=0;
        P->sjGstart=P->chrStart[P->nChrReal]+1; //not sure why I need that
    } else {//there are sjdb chromosomes
        ifstream sjdbInfo((P->genomeDir+"/sjdbInfo.txt").c_str());
        if (sjdbInfo.fail()) {
            ostringstream errOut;                            
            errOut << "EXITING because of FATAL error, could not open file " << (P->genomeDir+"/sjdbInfo.txt") <<"\n";
            errOut << "SOLUTION: check that the path to genome files, specified in --genomeDir is correct and the files are present, and have user read permsissions\n" <<flush;     
            exitWithError(errOut.str(),std::cerr, P->inOut->logMain, EXIT_CODE_INPUT_FILES, *P);
        };
    
        
        sjdbInfo >> P->sjdbN >> P->sjdbOverhang;
        P->inOut->logMain << "Processing splice junctions database sjdbN=" <<P->sjdbN<<",   sjdbOverhang=" <<P->sjdbOverhang <<" \n";    
        
        P->sjChrStart=P->nChrReal;
        P->sjGstart=P->chrStart[P->sjChrStart];

        //fill the sj-db to genome translation array
        P->sjDstart=new uint [P->sjdbN];
        P->sjAstart=new uint [P->sjdbN];
        P->sjdbStart=new uint [P->sjdbN];
        P->sjdbEnd=new uint [P->sjdbN];
        
        P->sjdbMotif=new uint8 [P->sjdbN];
        P->sjdbShiftLeft=new uint8 [P->sjdbN];
        P->sjdbShiftRight=new uint8 [P->sjdbN];
        P->sjdbStrand=new uint8 [P->sjdbN];

        for (uint ii=0;ii<P->sjdbN;ii++) {//get the info about junctions from sjdbInfo.txt       
            {
                uint16 d1,d2,d3,d4;
                sjdbInfo >> P->sjdbStart[ii] >> P->sjdbEnd[ii] >> d1 >> d2 >> d3 >> d4;
                P->sjdbMotif[ii]      = (uint8) d1;
                P->sjdbShiftLeft[ii]  = (uint8) d2;
                P->sjdbShiftRight[ii] = (uint8) d3;
                P->sjdbStrand[ii] = (uint8) d4;
            };
            P->sjDstart[ii]   = P->sjdbStart[ii]  - P->sjdbOverhang; 
            P->sjAstart[ii]   = P->sjdbEnd[ii] + 1;     
            if (P->sjdbMotif[ii]==0) {//shinon-canonical junctions back to their true coordinates
                P->sjDstart[ii] += P->sjdbShiftLeft[ii];
                P->sjAstart[ii] += P->sjdbShiftLeft[ii];
            };
        };
    };     
    
    //check and redefine some parameters
    //max intron size
    if (P->alignIntronMax==0 && P->alignMatesGapMax==0) {
        P->inOut->logMain << "alignIntronMax=alignMatesGapMax=0, the max intron size will be approximately determined by (2^winBinNbits)*winAnchorDistNbins=" \
                << (1LLU<<P->winBinNbits)*P->winAnchorDistNbins <<endl;
    } else {
        //redefine winBinNbits
        P->winBinNbits=max( (uint) floor(log2(P->nGenome/40000)+0.5), (uint) floor(log2(max(max(4LLU,P->alignIntronMax),P->alignMatesGapMax)/4)+0.5) );
        P->inOut->logMain << "To accomodate alignIntronMax="<<P->alignIntronMax<<" redefined winBinNbits="<< P->winBinNbits <<endl;
    };
    
    if (P->winBinNbits > P->genomeChrBinNbits) {
       P->inOut->logMain << "winBinNbits=" <<P->winBinNbits <<" > " << "genomeChrBinNbits=" << P->genomeChrBinNbits << "   redefining:\n";
       P->winBinNbits=P->genomeChrBinNbits;
       P->inOut->logMain << "winBinNbits=" <<P->winBinNbits <<endl;
    };    
    
    
    if (P->alignIntronMax==0 && P->alignMatesGapMax==0) {
    } else {
        //redefine winFlankNbins,winAnchorDistNbins
        P->winFlankNbins=max(P->alignIntronMax,P->alignMatesGapMax)/(1LLU<<P->winBinNbits)+1;
        P->winAnchorDistNbins=2*P->winFlankNbins;
        P->inOut->logMain << "To accomodate alignIntronMax="<<P->alignIntronMax<<" and alignMatesGapMax="<<P->alignMatesGapMax<<\
                ", redefined winFlankNbins="<<P->winFlankNbins<<" and winAnchorDistNbins="<<P->winAnchorDistNbins<<endl;
    };
    
    P->winBinChrNbits=P->genomeChrBinNbits-P->winBinNbits;
    P->winBinN = P->nGenome/(1LLU << P->winBinNbits)+1;//this may be chenaged later
};
Ejemplo n.º 8
0
long double log2l(long double x) { return log2((double)x); }
Ejemplo n.º 9
0
/**
 *  hash(key) = floor(m * (key * A) mod 1)
 *  Translated into machine friendly computations:
 *  A = s/2^w where s = multiplier.
 *  m = 2^p, where m is the number of buckets.
 *  Since S is 2^S number of entries and B = 2^b = number of entries per bucket,
 *  where b is an integer, then p = S/b. 
 *  Thus, p = log2(2^S/B) = S-log2(B).
 */
MHash::MHash(uint multiplier, uint S, uint B){
    s = multiplier;
    p = S-log2(B);
}
Ejemplo n.º 10
0
void post()
{
	//calculate offsetY
	for(int i=0;i<num_jewels;i++)
	{
		int col = i % 8;
		int row = i / 8;
		float offsetY = *(offsetYs+i);
		float dragX = *(dragXs+i);
		float dragY = *(dragYs+i);
		float paddingX = 2.0;
		float paddingY = 2.0;
		int type = *(jewels+i);
		// fprintf(flog,"type:%d\n",type);
		int color = type & COLOR_BITS;//126 == 1111110
		int dir = type & DIR_BITS;
		int bomb = type & BOMB_BITS;
		if(dir)
		{
			fprintf(flog,"dir:%d\n",dir);
		}
		if(bomb)
		{
			fprintf(flog,"bomb:%d\n",bomb);
		}
		float ltx = col * GRID_SIZE + dragX+paddingX;
		float lty = row * GRID_SIZE - offsetY + dragY + paddingY;
		// printf("%d\n",i);
		int r = log2((float)color);
		int o = 0;
		// printf("r:%d,type:%d\n",r,type);
		if(bomb & JEWEL_BOMB)
		{
			if(dir & JEWEL_DIR_NONE)
			{
				r += 13;
			}
			else if(dir & JEWEL_DIR_HERIZ)
			{
				r += 6;
				fprintf(flog,"r += 5\n");
			}
			else if(dir & JEWEL_DIR_VERTI)
			{
				r += 6;
				o = 1;
				fprintf(flog,"r += 5,o = 1\n");
			}
		}
		else if(bomb & JEWEL_DIAMOND)
		{
			r = 13;
		}
		
		for(int j=0;j<4;j++)
		{
			*(vertices+i*16+0+j*4) = (ltx + j%2*GRID_SIZE);//x
			*(vertices+i*16+1+j*4) = (lty + j/2*GRID_SIZE);//y
			float u = tex_coords[r][j][0];
			float v = tex_coords[r][j][1];
			if(o)
			{
				
				u = tex_coords[r][rotateIndex(j)][0];
				v = tex_coords[r][rotateIndex(j)][1];
			}
			*(vertices+i*16+2+j*4) = u;//u
			*(vertices+i*16+3+j*4) = v;//v
		}
		*(indices+6*i+0) = 4 * i + 0;
		*(indices+6*i+1) = 4 * i + 1;
		*(indices+6*i+2) = 4 * i + 3;
		*(indices+6*i+3) = 4 * i + 3;
		*(indices+6*i+4) = 4 * i + 2;
		*(indices+6*i+5) = 4 * i + 0;
	}
	glBufferData(GL_ARRAY_BUFFER,num_jewels*4*4*sizeof(GLfloat),vertices,GL_DYNAMIC_DRAW);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER,num_jewels*6*sizeof(GLushort),indices,GL_DYNAMIC_DRAW);
}
Ejemplo n.º 11
0
/*
 * General handler for setting values in config files.
 *
 * @param context	The main context pointer
 * @param token  	The parse token value
 * @param value  	The value to set
 * @return 0 for success
 */
int context_set_value(build_image_context *context,
		parse_token token,
		u_int32_t value)
{
	assert(context != NULL);

	switch (token) {
	case token_attribute:
		context->newbl_attr = value;
		break;

	case token_block_size:
		context->block_size = value;
		context->block_size_log2 = log2(value);

		if (context->memory != NULL) {
			printf("Error: Too late to change block size.\n");
			return 1;
		}

		if (value != (u_int32_t)(1 << context->block_size_log2)) {
			printf("Error: Block size must be a power of 2.\n");
			return 1;
		}
		context->pages_per_blk= 1 << (context->block_size_log2-
				context->page_size_log2);
		g_soc_config->set_value(token_block_size_log2,
			context->block_size_log2, context->bct);
		break;

	case token_partition_size:
		if (context->memory != NULL) {
			printf("Error: Too late to change block size.\n");
			return 1;
		}

		context->partition_size= value;
		g_soc_config->set_value(token_partition_size,
			value, context->bct);
		break;

	case token_page_size:
		context->page_size = value;
		context->page_size_log2 = log2(value);
		context->pages_per_blk= 1 << (context->block_size_log2-
			context->page_size_log2);

		g_soc_config->set_value(token_page_size_log2,
			context->page_size_log2, context->bct);
		break;
	case token_redundancy:
		context->redundancy = value;
		break;

	case token_version:
		context->version = value;
		break;

	case token_bct_copy:
		context->bct_copy = value;
		break;

	case token_odm_data:
		context->odm_data = value;
		break;

	case token_pre_bct_pad_blocks:
		if (context->bct_init) {
			printf("Error: Too late to pre-BCT pad.\n");
			return 1;
		}
		context->pre_bct_pad_blocks = value;
		break;

	DEFAULT();
	}

	return 0;
}
Ejemplo n.º 12
0
void
cgen(Node *n, Node *nn)
{
	Node *l, *r, *t;
	Prog *p1;
	Node nod, nod1, nod2, nod3, nod4;
	int o, hardleft;
	long v, curs;
	vlong c;

	if(debug['g']) {
		prtree(nn, "cgen lhs");
		prtree(n, "cgen");
	}
	if(n == Z || n->type == T)
		return;
	if(typesu[n->type->etype]) {
		sugen(n, nn, n->type->width);
		return;
	}
	l = n->left;
	r = n->right;
	o = n->op;
	if(n->addable >= INDEXED) {
		if(nn == Z) {
			switch(o) {
			default:
				nullwarn(Z, Z);
				break;
			case OINDEX:
				nullwarn(l, r);
				break;
			}
			return;
		}
		gmove(n, nn);
		return;
	}
	curs = cursafe;

	if(l->complex >= FNX)
	if(r != Z && r->complex >= FNX)
	switch(o) {
	default:
		if(cond(o) && typesu[l->type->etype])
			break;

		regret(&nod, r);
		cgen(r, &nod);

		regsalloc(&nod1, r);
		gmove(&nod, &nod1);

		regfree(&nod);
		nod = *n;
		nod.right = &nod1;

		cgen(&nod, nn);
		return;

	case OFUNC:
	case OCOMMA:
	case OANDAND:
	case OOROR:
	case OCOND:
	case ODOT:
		break;
	}

	hardleft = l->addable < INDEXED || l->complex >= FNX;
	switch(o) {
	default:
		diag(n, "unknown op in cgen: %O", o);
		break;

	case ONEG:
	case OCOM:
		if(nn == Z) {
			nullwarn(l, Z);
			break;
		}
		regalloc(&nod, l, nn);
		cgen(l, &nod);
		gopcode(o, n->type, Z, &nod);
		gmove(&nod, nn);
		regfree(&nod);
		break;

	case OAS:
		if(l->op == OBIT)
			goto bitas;
		if(!hardleft) {
			if(nn != Z || r->addable < INDEXED || hardconst(r)) {
				if(r->complex >= FNX && nn == Z)
					regret(&nod, r);
				else
					regalloc(&nod, r, nn);
				cgen(r, &nod);
				gmove(&nod, l);
				if(nn != Z)
					gmove(&nod, nn);
				regfree(&nod);
			} else
				gmove(r, l);
			break;
		}
		if(l->complex >= r->complex) {
			if(l->op == OINDEX && immconst(r)) {
				gmove(r, l);
				break;
			}
			reglcgen(&nod1, l, Z);
			if(r->addable >= INDEXED && !hardconst(r)) {
				gmove(r, &nod1);
				if(nn != Z)
					gmove(r, nn);
				regfree(&nod1);
				break;
			}
			regalloc(&nod, r, nn);
			cgen(r, &nod);
		} else {
			regalloc(&nod, r, nn);
			cgen(r, &nod);
			reglcgen(&nod1, l, Z);
		}
		gmove(&nod, &nod1);
		regfree(&nod);
		regfree(&nod1);
		break;

	bitas:
		n = l->left;
		regalloc(&nod, r, nn);
		if(l->complex >= r->complex) {
			reglcgen(&nod1, n, Z);
			cgen(r, &nod);
		} else {
			cgen(r, &nod);
			reglcgen(&nod1, n, Z);
		}
		regalloc(&nod2, n, Z);
		gmove(&nod1, &nod2);
		bitstore(l, &nod, &nod1, &nod2, nn);
		break;

	case OBIT:
		if(nn == Z) {
			nullwarn(l, Z);
			break;
		}
		bitload(n, &nod, Z, Z, nn);
		gmove(&nod, nn);
		regfree(&nod);
		break;

	case OLSHR:
	case OASHL:
	case OASHR:
		if(nn == Z) {
			nullwarn(l, r);
			break;
		}
		if(r->op == OCONST) {
			if(r->vconst == 0) {
				cgen(l, nn);
				break;
			}
			regalloc(&nod, l, nn);
			cgen(l, &nod);
			if(o == OASHL && r->vconst == 1)
				gopcode(OADD, n->type, &nod, &nod);
			else
				gopcode(o, n->type, r, &nod);
			gmove(&nod, nn);
			regfree(&nod);
			break;
		}

		/*
		 * get nod to be D_CX
		 */
		if(nodreg(&nod, nn, D_CX)) {
			regsalloc(&nod1, n);
			gmove(&nod, &nod1);
			cgen(n, &nod);		/* probably a bug */
			gmove(&nod, nn);
			gmove(&nod1, &nod);
			break;
		}
		reg[D_CX]++;
		if(nn->op == OREGISTER && nn->reg == D_CX)
			regalloc(&nod1, l, Z);
		else
			regalloc(&nod1, l, nn);
		if(r->complex >= l->complex) {
			cgen(r, &nod);
			cgen(l, &nod1);
		} else {
			cgen(l, &nod1);
			cgen(r, &nod);
		}
		gopcode(o, n->type, &nod, &nod1);
		gmove(&nod1, nn);
		regfree(&nod);
		regfree(&nod1);
		break;

	case OADD:
	case OSUB:
	case OOR:
	case OXOR:
	case OAND:
		if(nn == Z) {
			nullwarn(l, r);
			break;
		}
		if(typefd[n->type->etype])
			goto fop;
		if(r->op == OCONST) {
			if(r->vconst == 0 && o != OAND) {
				cgen(l, nn);
				break;
			}
		}
		if(n->op == OADD && l->op == OASHL && l->right->op == OCONST
		&& (r->op != OCONST || r->vconst < -128 || r->vconst > 127)) {
			c = l->right->vconst;
			if(c > 0 && c <= 3) {
				if(l->left->complex >= r->complex) {
					regalloc(&nod, l->left, nn);
					cgen(l->left, &nod);
					if(r->addable < INDEXED) {
						regalloc(&nod1, r, Z);
						cgen(r, &nod1);
						genmuladd(&nod, &nod, 1 << c, &nod1);
						regfree(&nod1);
					}
					else
						genmuladd(&nod, &nod, 1 << c, r);
				}
				else {
					regalloc(&nod, r, nn);
					cgen(r, &nod);
					regalloc(&nod1, l->left, Z);
					cgen(l->left, &nod1);
					genmuladd(&nod, &nod1, 1 << c, &nod);
					regfree(&nod1);
				}
				gmove(&nod, nn);
				regfree(&nod);
				break;
			}
		}
		if(r->addable >= INDEXED && !hardconst(r)) {
			regalloc(&nod, l, nn);
			cgen(l, &nod);
			gopcode(o, n->type, r, &nod);
			gmove(&nod, nn);
			regfree(&nod);
			break;
		}
		if(l->complex >= r->complex) {
			regalloc(&nod, l, nn);
			cgen(l, &nod);
			regalloc(&nod1, r, Z);
			cgen(r, &nod1);
			gopcode(o, n->type, &nod1, &nod);
		} else {
			regalloc(&nod1, r, nn);
			cgen(r, &nod1);
			regalloc(&nod, l, Z);
			cgen(l, &nod);
			gopcode(o, n->type, &nod1, &nod);
		}
		gmove(&nod, nn);
		regfree(&nod);
		regfree(&nod1);
		break;

	case OLMOD:
	case OMOD:
	case OLMUL:
	case OLDIV:
	case OMUL:
	case ODIV:
		if(nn == Z) {
			nullwarn(l, r);
			break;
		}
		if(typefd[n->type->etype])
			goto fop;
		if(r->op == OCONST && typechl[n->type->etype]) {	/* TO DO */
			SET(v);
			switch(o) {
			case ODIV:
			case OMOD:
				c = r->vconst;
				if(c < 0)
					c = -c;
				v = log2(c);
				if(v < 0)
					break;
				/* fall thru */
			case OMUL:
			case OLMUL:
				regalloc(&nod, l, nn);
				cgen(l, &nod);
				switch(o) {
				case OMUL:
				case OLMUL:
					mulgen(n->type, r, &nod);
					break;
				case ODIV:
					sdiv2(r->vconst, v, l, &nod);
					break;
				case OMOD:
					smod2(r->vconst, v, l, &nod);
					break;
				}
				gmove(&nod, nn);
				regfree(&nod);
				goto done;
			case OLDIV:
				c = r->vconst;
				if((c & 0x80000000) == 0)
					break;
				regalloc(&nod1, l, Z);
				cgen(l, &nod1);
				regalloc(&nod, l, nn);
				zeroregm(&nod);
				gins(ACMPL, &nod1, nodconst(c));
				gins(ASBBL, nodconst(-1), &nod);
				regfree(&nod1);
				gmove(&nod, nn);
				regfree(&nod);
				goto done;
			}
		}

		if(o == OMUL) {
			if(l->addable >= INDEXED) {
				t = l;
				l = r;
				r = t;
			}
			/* should favour AX */
			regalloc(&nod, l, nn);
			cgen(l, &nod);
			if(r->addable < INDEXED || hardconst(r)) {
				regalloc(&nod1, r, Z);
				cgen(r, &nod1);
				gopcode(OMUL, n->type, &nod1, &nod);
				regfree(&nod1);
			}else
				gopcode(OMUL, n->type, r, &nod);	/* addressible */
			gmove(&nod, nn);
			regfree(&nod);
			break;
		}

		/*
		 * get nod to be D_AX
		 * get nod1 to be D_DX
		 */
		if(nodreg(&nod, nn, D_AX)) {
			regsalloc(&nod2, n);
			gmove(&nod, &nod2);
			v = reg[D_AX];
			reg[D_AX] = 0;

			if(isreg(l, D_AX)) {
				nod3 = *n;
				nod3.left = &nod2;
				cgen(&nod3, nn);
			} else
			if(isreg(r, D_AX)) {
				nod3 = *n;
				nod3.right = &nod2;
				cgen(&nod3, nn);
			} else
				cgen(n, nn);

			gmove(&nod2, &nod);
			reg[D_AX] = v;
			break;
		}
		if(nodreg(&nod1, nn, D_DX)) {
			regsalloc(&nod2, n);
			gmove(&nod1, &nod2);
			v = reg[D_DX];
			reg[D_DX] = 0;

			if(isreg(l, D_DX)) {
				nod3 = *n;
				nod3.left = &nod2;
				cgen(&nod3, nn);
			} else
			if(isreg(r, D_DX)) {
				nod3 = *n;
				nod3.right = &nod2;
				cgen(&nod3, nn);
			} else
				cgen(n, nn);

			gmove(&nod2, &nod1);
			reg[D_DX] = v;
			break;
		}
		reg[D_AX]++;

		if(r->op == OCONST && (o == ODIV || o == OLDIV) && immconst(r) && typechl[r->type->etype]) {
			reg[D_DX]++;
			if(l->addable < INDEXED) {
				regalloc(&nod2, l, Z);
				cgen(l, &nod2);
				l = &nod2;
			}
			if(o == ODIV)
				sdivgen(l, r, &nod, &nod1);
			else
				udivgen(l, r, &nod, &nod1);
			gmove(&nod1, nn);
			if(l == &nod2)
				regfree(l);
			goto freeaxdx;
		}

		if(l->complex >= r->complex) {
			cgen(l, &nod);
			reg[D_DX]++;
			if(o == ODIV || o == OMOD)
				gins(typechl[l->type->etype]? ACDQ: ACQO, Z, Z);
			if(o == OLDIV || o == OLMOD)
				zeroregm(&nod1);
			if(r->addable < INDEXED || r->op == OCONST) {
				regalloc(&nod3, r, Z);
				cgen(r, &nod3);
				gopcode(o, n->type, &nod3, Z);
				regfree(&nod3);
			} else
				gopcode(o, n->type, r, Z);
		} else {
			regsalloc(&nod3, r);
			cgen(r, &nod3);
			cgen(l, &nod);
			reg[D_DX]++;
			if(o == ODIV || o == OMOD)
				gins(typechl[l->type->etype]? ACDQ: ACQO, Z, Z);
			if(o == OLDIV || o == OLMOD)
				zeroregm(&nod1);
			gopcode(o, n->type, &nod3, Z);
		}
		if(o == OMOD || o == OLMOD)
			gmove(&nod1, nn);
		else
			gmove(&nod, nn);
	freeaxdx:
		regfree(&nod);
		regfree(&nod1);
		break;

	case OASLSHR:
	case OASASHL:
	case OASASHR:
		if(r->op == OCONST)
			goto asand;
		if(l->op == OBIT)
			goto asbitop;
		if(typefd[n->type->etype])
			goto asand;	/* can this happen? */

		/*
		 * get nod to be D_CX
		 */
		if(nodreg(&nod, nn, D_CX)) {
			regsalloc(&nod1, n);
			gmove(&nod, &nod1);
			cgen(n, &nod);
			if(nn != Z)
				gmove(&nod, nn);
			gmove(&nod1, &nod);
			break;
		}
		reg[D_CX]++;

		if(r->complex >= l->complex) {
			cgen(r, &nod);
			if(hardleft)
				reglcgen(&nod1, l, Z);
			else
				nod1 = *l;
		} else {
			if(hardleft)
				reglcgen(&nod1, l, Z);
			else
				nod1 = *l;
			cgen(r, &nod);
		}

		gopcode(o, l->type, &nod, &nod1);
		regfree(&nod);
		if(nn != Z)
			gmove(&nod1, nn);
		if(hardleft)
			regfree(&nod1);
		break;

	case OASAND:
	case OASADD:
	case OASSUB:
	case OASXOR:
	case OASOR:
	asand:
		if(l->op == OBIT)
			goto asbitop;
		if(typefd[l->type->etype] || typefd[r->type->etype])
			goto asfop;
		if(l->complex >= r->complex) {
			if(hardleft)
				reglcgen(&nod, l, Z);
			else
				nod = *l;
			if(!immconst(r)) {
				regalloc(&nod1, r, nn);
				cgen(r, &nod1);
				gopcode(o, l->type, &nod1, &nod);
				regfree(&nod1);
			} else
				gopcode(o, l->type, r, &nod);
		} else {
			regalloc(&nod1, r, nn);
			cgen(r, &nod1);
			if(hardleft)
				reglcgen(&nod, l, Z);
			else
				nod = *l;
			gopcode(o, l->type, &nod1, &nod);
			regfree(&nod1);
		}
		if(nn != Z)
			gmove(&nod, nn);
		if(hardleft)
			regfree(&nod);
		break;

	asfop:
		if(l->complex >= r->complex) {
			if(hardleft)
				reglcgen(&nod, l, Z);
			else
				nod = *l;
			if(r->addable < INDEXED){
				regalloc(&nod1, r, nn);
				cgen(r, &nod1);
			}else
				nod1 = *r;
			regalloc(&nod2, r, Z);
			gmove(&nod, &nod2);
			gopcode(o, r->type, &nod1, &nod2);
			gmove(&nod2, &nod);
			regfree(&nod2);
			if(r->addable < INDEXED)
				regfree(&nod1);
		} else {
			regalloc(&nod1, r, nn);
			cgen(r, &nod1);
			if(hardleft)
				reglcgen(&nod, l, Z);
			else
				nod = *l;
			if(o != OASMUL && o != OASADD) {
				regalloc(&nod2, r, Z);
				gmove(&nod, &nod2);
				gopcode(o, r->type, &nod1, &nod2);
				regfree(&nod1);
				gmove(&nod2, &nod);
				regfree(&nod2);
			} else {
				gopcode(o, r->type, &nod, &nod1);
				gmove(&nod1, &nod);
				regfree(&nod1);
			}
		}
		if(nn != Z)
			gmove(&nod, nn);
		if(hardleft)
			regfree(&nod);
		break;

	case OASLMUL:
	case OASLDIV:
	case OASLMOD:
	case OASMUL:
	case OASDIV:
	case OASMOD:
		if(l->op == OBIT)
			goto asbitop;
		if(typefd[n->type->etype] || typefd[r->type->etype])
			goto asfop;
		if(r->op == OCONST && typechl[n->type->etype]) {
			SET(v);
			switch(o) {
			case OASDIV:
			case OASMOD:
				c = r->vconst;
				if(c < 0)
					c = -c;
				v = log2(c);
				if(v < 0)
					break;
				/* fall thru */
			case OASMUL:
			case OASLMUL:
				if(hardleft)
					reglcgen(&nod2, l, Z);
				else
					nod2 = *l;
				regalloc(&nod, l, nn);
				cgen(&nod2, &nod);
				switch(o) {
				case OASMUL:
				case OASLMUL:
					mulgen(n->type, r, &nod);
					break;
				case OASDIV:
					sdiv2(r->vconst, v, l, &nod);
					break;
				case OASMOD:
					smod2(r->vconst, v, l, &nod);
					break;
				}
			havev:
				gmove(&nod, &nod2);
				if(nn != Z)
					gmove(&nod, nn);
				if(hardleft)
					regfree(&nod2);
				regfree(&nod);
				goto done;
			case OASLDIV:
				c = r->vconst;
				if((c & 0x80000000) == 0)
					break;
				if(hardleft)
					reglcgen(&nod2, l, Z);
				else
					nod2 = *l;
				regalloc(&nod1, l, nn);
				cgen(&nod2, &nod1);
				regalloc(&nod, l, nn);
				zeroregm(&nod);
				gins(ACMPL, &nod1, nodconst(c));
				gins(ASBBL, nodconst(-1), &nod);
				regfree(&nod1);
				goto havev;
			}
		}

		if(o == OASMUL) {
			/* should favour AX */
			regalloc(&nod, l, nn);
			if(r->complex >= FNX) {
				regalloc(&nod1, r, Z);
				cgen(r, &nod1);
				r = &nod1;
			}
			if(hardleft)
				reglcgen(&nod2, l, Z);
			else
				nod2 = *l;
			cgen(&nod2, &nod);
			if(r->addable < INDEXED || hardconst(r)) {
				if(r->complex < FNX) {
					regalloc(&nod1, r, Z);
					cgen(r, &nod1);
				}
				gopcode(OASMUL, n->type, &nod1, &nod);
				regfree(&nod1);
			}
			else
				gopcode(OASMUL, n->type, r, &nod);
			if(r == &nod1)
				regfree(r);
			gmove(&nod, &nod2);
			if(nn != Z)
				gmove(&nod, nn);
			regfree(&nod);
			if(hardleft)
				regfree(&nod2);
			break;
		}

		/*
		 * get nod to be D_AX
		 * get nod1 to be D_DX
		 */
		if(nodreg(&nod, nn, D_AX)) {
			regsalloc(&nod2, n);
			gmove(&nod, &nod2);
			v = reg[D_AX];
			reg[D_AX] = 0;

			if(isreg(l, D_AX)) {
				nod3 = *n;
				nod3.left = &nod2;
				cgen(&nod3, nn);
			} else
			if(isreg(r, D_AX)) {
				nod3 = *n;
				nod3.right = &nod2;
				cgen(&nod3, nn);
			} else
				cgen(n, nn);

			gmove(&nod2, &nod);
			reg[D_AX] = v;
			break;
		}
		if(nodreg(&nod1, nn, D_DX)) {
			regsalloc(&nod2, n);
			gmove(&nod1, &nod2);
			v = reg[D_DX];
			reg[D_DX] = 0;

			if(isreg(l, D_DX)) {
				nod3 = *n;
				nod3.left = &nod2;
				cgen(&nod3, nn);
			} else
			if(isreg(r, D_DX)) {
				nod3 = *n;
				nod3.right = &nod2;
				cgen(&nod3, nn);
			} else
				cgen(n, nn);

			gmove(&nod2, &nod1);
			reg[D_DX] = v;
			break;
		}
		reg[D_AX]++;
		reg[D_DX]++;

		if(l->complex >= r->complex) {
			if(hardleft)
				reglcgen(&nod2, l, Z);
			else
				nod2 = *l;
			cgen(&nod2, &nod);
			if(r->op == OCONST && typechl[r->type->etype]) {
				switch(o) {
				case OASDIV:
					sdivgen(&nod2, r, &nod, &nod1);
					goto divdone;
				case OASLDIV:
					udivgen(&nod2, r, &nod, &nod1);
				divdone:
					gmove(&nod1, &nod2);
					if(nn != Z)
						gmove(&nod1, nn);
					goto freelxaxdx;
				}
			}
			if(o == OASDIV || o == OASMOD)
				gins(typechl[l->type->etype]? ACDQ: ACQO, Z, Z);
			if(o == OASLDIV || o == OASLMOD)
				zeroregm(&nod1);
			if(r->addable < INDEXED || r->op == OCONST ||
			   !typeil[r->type->etype]) {
				regalloc(&nod3, r, Z);
				cgen(r, &nod3);
				gopcode(o, l->type, &nod3, Z);
				regfree(&nod3);
			} else
				gopcode(o, n->type, r, Z);
		} else {
			regalloc(&nod3, r, Z);
			cgen(r, &nod3);
			if(hardleft)
				reglcgen(&nod2, l, Z);
			else
				nod2 = *l;
			cgen(&nod2, &nod);
			if(o == OASDIV || o == OASMOD)
				gins(typechl[l->type->etype]? ACDQ: ACQO, Z, Z);
			if(o == OASLDIV || o == OASLMOD)
				zeroregm(&nod1);
			gopcode(o, l->type, &nod3, Z);
			regfree(&nod3);
		}
		if(o == OASMOD || o == OASLMOD) {
			gmove(&nod1, &nod2);
			if(nn != Z)
				gmove(&nod1, nn);
		} else {
			gmove(&nod, &nod2);
			if(nn != Z)
				gmove(&nod, nn);
		}
	freelxaxdx:
		if(hardleft)
			regfree(&nod2);
		regfree(&nod);
		regfree(&nod1);
		break;

	fop:
		if(l->complex >= r->complex) {
			regalloc(&nod, l, nn);
			cgen(l, &nod);
			if(r->addable < INDEXED) {
				regalloc(&nod1, r, Z);
				cgen(r, &nod1);
				gopcode(o, n->type, &nod1, &nod);
				regfree(&nod1);
			} else
				gopcode(o, n->type, r, &nod);
		} else {
			/* TO DO: could do better with r->addable >= INDEXED */
			regalloc(&nod1, r, Z);
			cgen(r, &nod1);
			regalloc(&nod, l, nn);
			cgen(l, &nod);
			gopcode(o, n->type, &nod1, &nod);
			regfree(&nod1);
		}
		gmove(&nod, nn);
		regfree(&nod);
		break;

	asbitop:
		regalloc(&nod4, n, nn);
		if(l->complex >= r->complex) {
			bitload(l, &nod, &nod1, &nod2, &nod4);
			regalloc(&nod3, r, Z);
			cgen(r, &nod3);
		} else {
			regalloc(&nod3, r, Z);
			cgen(r, &nod3);
			bitload(l, &nod, &nod1, &nod2, &nod4);
		}
		gmove(&nod, &nod4);

		{	/* TO DO: check floating point source */
			Node onod;

			/* incredible grot ... */
			onod = nod3;
			onod.op = o;
			onod.complex = 2;
			onod.addable = 0;
			onod.type = tfield;
			onod.left = &nod4;
			onod.right = &nod3;
			cgen(&onod, Z);
		}
		regfree(&nod3);
		gmove(&nod4, &nod);
		regfree(&nod4);
		bitstore(l, &nod, &nod1, &nod2, nn);
		break;

	case OADDR:
		if(nn == Z) {
			nullwarn(l, Z);
			break;
		}
		lcgen(l, nn);
		break;

	case OFUNC:
		if(l->complex >= FNX) {
			if(l->op != OIND)
				diag(n, "bad function call");

			regret(&nod, l->left);
			cgen(l->left, &nod);
			regsalloc(&nod1, l->left);
			gmove(&nod, &nod1);
			regfree(&nod);

			nod = *n;
			nod.left = &nod2;
			nod2 = *l;
			nod2.left = &nod1;
			nod2.complex = 1;
			cgen(&nod, nn);

			return;
		}
		o = reg[REGARG];
		gargs(r, &nod, &nod1);
		if(l->addable < INDEXED) {
			reglcgen(&nod, l, nn);
			nod.op = OREGISTER;
			gopcode(OFUNC, n->type, Z, &nod);
			regfree(&nod);
		} else
			gopcode(OFUNC, n->type, Z, l);
		if(REGARG)
			if(o != reg[REGARG])
				reg[REGARG]--;
		if(nn != Z) {
			regret(&nod, n);
			gmove(&nod, nn);
			regfree(&nod);
		}
		break;

	case OIND:
		if(nn == Z) {
			nullwarn(l, Z);
			break;
		}
		regialloc(&nod, n, nn);
		r = l;
		while(r->op == OADD)
			r = r->right;
		if(sconst(r)) {
			v = r->vconst;
			r->vconst = 0;
			cgen(l, &nod);
			nod.xoffset += v;
			r->vconst = v;
		} else
			cgen(l, &nod);
		regind(&nod, n);
		gmove(&nod, nn);
		regfree(&nod);
		break;

	case OEQ:
	case ONE:
	case OLE:
	case OLT:
	case OGE:
	case OGT:
	case OLO:
	case OLS:
	case OHI:
	case OHS:
		if(nn == Z) {
			nullwarn(l, r);
			break;
		}
		boolgen(n, 1, nn);
		break;

	case OANDAND:
	case OOROR:
		boolgen(n, 1, nn);
		if(nn == Z)
			patch(p, pc);
		break;

	case ONOT:
		if(nn == Z) {
			nullwarn(l, Z);
			break;
		}
		boolgen(n, 1, nn);
		break;

	case OCOMMA:
		cgen(l, Z);
		cgen(r, nn);
		break;

	case OCAST:
		if(nn == Z) {
			nullwarn(l, Z);
			break;
		}
		/*
		 * convert from types l->n->nn
		 */
		if(nocast(l->type, n->type) && nocast(n->type, nn->type)) {
			/* both null, gen l->nn */
			cgen(l, nn);
			break;
		}
		if(ewidth[n->type->etype] < ewidth[l->type->etype]){
			if(l->type->etype == TIND && typechlp[n->type->etype])
				warn(n, "conversion of pointer to shorter integer");
		}else if(0){
			if(nocast(n->type, nn->type) || castup(n->type, nn->type)){
				if(typefd[l->type->etype] != typefd[nn->type->etype])
					regalloc(&nod, l, nn);
				else
					regalloc(&nod, nn, nn);
				cgen(l, &nod);
				gmove(&nod, nn);
				regfree(&nod);
				break;
			}
		}
		regalloc(&nod, l, nn);
		cgen(l, &nod);
		regalloc(&nod1, n, &nod);
		gmove(&nod, &nod1);
		gmove(&nod1, nn);
		regfree(&nod1);
		regfree(&nod);
		break;

	case ODOT:
		sugen(l, nodrat, l->type->width);
		if(nn == Z)
			break;
		warn(n, "non-interruptable temporary");
		nod = *nodrat;
		if(!r || r->op != OCONST) {
			diag(n, "DOT and no offset");
			break;
		}
		nod.xoffset += (long)r->vconst;
		nod.type = n->type;
		cgen(&nod, nn);
		break;

	case OCOND:
		bcgen(l, 1);
		p1 = p;
		cgen(r->left, nn);
		gbranch(OGOTO);
		patch(p1, pc);
		p1 = p;
		cgen(r->right, nn);
		patch(p1, pc);
		break;

	case OPOSTINC:
	case OPOSTDEC:
		v = 1;
		if(l->type->etype == TIND)
			v = l->type->link->width;
		if(o == OPOSTDEC)
			v = -v;
		if(l->op == OBIT)
			goto bitinc;
		if(nn == Z)
			goto pre;

		if(hardleft)
			reglcgen(&nod, l, Z);
		else
			nod = *l;

		gmove(&nod, nn);
		if(typefd[n->type->etype]) {
			regalloc(&nod1, l, Z);
			gmove(&nod, &nod1);
			if(v < 0)
				gopcode(OSUB, n->type, nodfconst(-v), &nod1);
			else
				gopcode(OADD, n->type, nodfconst(v), &nod1);
			gmove(&nod1, &nod);
			regfree(&nod1);
		} else
			gopcode(OADD, n->type, nodconst(v), &nod);
		if(hardleft)
			regfree(&nod);
		break;

	case OPREINC:
	case OPREDEC:
		v = 1;
		if(l->type->etype == TIND)
			v = l->type->link->width;
		if(o == OPREDEC)
			v = -v;
		if(l->op == OBIT)
			goto bitinc;

	pre:
		if(hardleft)
			reglcgen(&nod, l, Z);
		else
			nod = *l;
		if(typefd[n->type->etype]) {
			regalloc(&nod1, l, Z);
			gmove(&nod, &nod1);
			if(v < 0)
				gopcode(OSUB, n->type, nodfconst(-v), &nod1);
			else
				gopcode(OADD, n->type, nodfconst(v), &nod1);
			gmove(&nod1, &nod);
			regfree(&nod1);
		} else
			gopcode(OADD, n->type, nodconst(v), &nod);
		if(nn != Z)
			gmove(&nod, nn);
		if(hardleft)
			regfree(&nod);
		break;

	bitinc:
		if(nn != Z && (o == OPOSTINC || o == OPOSTDEC)) {
			bitload(l, &nod, &nod1, &nod2, Z);
			gmove(&nod, nn);
			gopcode(OADD, tfield, nodconst(v), &nod);
			bitstore(l, &nod, &nod1, &nod2, Z);
			break;
		}
		bitload(l, &nod, &nod1, &nod2, nn);
		gopcode(OADD, tfield, nodconst(v), &nod);
		bitstore(l, &nod, &nod1, &nod2, nn);
		break;
	}
done:
	cursafe = curs;
}
Ejemplo n.º 13
0
	unsigned int componentMaskToInt(ComponentMask mask)
	{
		return (unsigned int)log2(mask.to_ulong());
	}
Ejemplo n.º 14
0
int	main(int argc, char* argv[])
{
	char*	infile = NULL;
	char*	outfile = NULL;
	int	tree_depth = 6;
	int	tile_size = 256;

	for ( int arg = 1; arg < argc; arg++ ) {
		if ( argv[arg][0] == '-' ) {
			// command-line switch.
			
			switch ( argv[arg][1] ) {
			case 'h':
			case '?':
				print_usage();
				exit( 1 );
				break;

			case 't':
				// Set the tilesize.
				if (arg + 1 >= argc) {
					printf("error: -t option requires an integer for tile_size\n");
					print_usage();
					exit(1);
				}
				arg++;
				tile_size = atoi(argv[arg]);
				break;
			case 'd':
				// Tree depth.
				if (arg + 1 >= argc) {
					printf("error: -d option requires an integer for tree_depth\n");
					print_usage();
					exit(1);
				}
				arg++;
				tree_depth = atoi(argv[arg]);
				break;

			default:
				printf("error: unknown command-line switch -%c\n", argv[arg][1]);
				exit(1);
				break;
			}

		} else {
			// File argument.
			if ( infile == NULL ) {
				infile = argv[arg];
			} else if ( outfile == NULL ) {
				outfile = argv[arg];
			} else {
				// This looks like extra noise on the command line; complain and exit.
				printf( "argument '%s' looks like extra noise; exiting.\n", argv[arg]);
				print_usage();
				exit( 1 );
			}
		}
	}

	// Must specify input filename.
	if (infile == NULL) {
		printf("error: you must supply an input filename which points to a .jpg image\n");
		print_usage();
		exit(1);
	}

	// Must specify an output filename.
	if (outfile == NULL) {
		printf("error: you must specify an output filename, for the texture quadtree output\n");
		print_usage();
		exit(1);
	}

	// Validate the tile_size.  Must be a power of two.
	int	logged_tile_size = 1 << frnd(log2((float) tile_size));
	if (tile_size <= 0 || logged_tile_size != tile_size) {
		printf("error: tile_size must be a power of two.\n");
		print_usage();
		exit(1);
	}

	// Validate tree depth.  Keep it within reason.
	if (tree_depth <= 0 || tree_depth > 12)
	{
		printf("error: tree_depth out of range.  Keep it between 1 and 12.\n");
		print_usage();
		exit(1);
	}
	
	// Open input file.
	tu_file*	in = new tu_file(infile, "rb");
	if (in->get_error())
	{
		printf("Can't open input file '%s'!\n", infile);
		delete in;
		exit(1);
	}

	// Open output file.
	tu_file*	out = new tu_file(outfile, "w+b");
	if (out->get_error())
	{
		printf("Can't open output file '%s'!\n", outfile);
		delete in;
		delete out;
		exit(1);
	}

	// Start reading the input.
	jpeg::input*	j_in = jpeg::input::create(in);
	if (j_in == NULL) {
		printf("Failure reading JPEG header of input file '%s'!\n", infile);
		delete in;
		delete out;
		exit(1);
	}

	// Size the tiles.
	int	tile_dim = 1 << (tree_depth - 1);

	// Write .tqt header.
	out->write_bytes("tqt\0", 4);	// filetype tag
	out->write_le32(1);			// version number.
	out->write_le32(tree_depth);
	out->write_le32(tile_size);

	// Make a null table of contents, and write it to the file.
	array<Uint32>	toc;
	toc.resize(tqt::node_count(tree_depth));

	int	toc_start = out->get_position();
	for (int i = 0; i < toc.size(); i++) {
		toc[i] = 0;
		out->write_le32(toc[i]);
	}

	int	tile_max_source_height = int(j_in->get_height() / float(tile_dim) + 1);

	// Create a horizontal strip, as wide as the image, and tall
	// enough to cover a whole tile.
	image::rgb*	strip = image::create_rgb(j_in->get_width(), tile_max_source_height);

	// Initialize the strip by reading the first set of scanlines.
	int	next_scanline = 0;
	int	strip_top = 0;
	while (next_scanline < tile_max_source_height) {
		j_in->read_scanline(image::scanline(strip, next_scanline));
		next_scanline++;
	}

	image::rgb*	tile = image::create_rgb(tile_size, tile_size);

	printf("making leaf tiles....     ");

	// generate base level tiles.
	for (int row = 0; row < tile_dim; row++) {
		float	y0 = float(row) / tile_dim * j_in->get_height();
		float	y1 = float(row + 1) / tile_dim * j_in->get_height();

		int	lines_to_read = imin(int(y1), j_in->get_height()) - (strip_top + strip->m_height);
		if (lines_to_read > 0)
		{
			// Copy existing lines up...
			int	lines_to_keep = strip->m_height - lines_to_read;
			{for (int i = 0; i < lines_to_keep; i++) {
				memcpy(image::scanline(strip, i), image::scanline(strip, i + lines_to_read /*keep*/), strip->m_width * 3);
			}}

			// Read new lines
			{for (int i = lines_to_keep; i < strip->m_height; i++) {
				j_in->read_scanline(image::scanline(strip, i));
			}}

			strip_top += lines_to_read;
		}

		for (int col = 0; col < tile_dim; col++) {
			float	x0 = float(col) / tile_dim * j_in->get_width();
			float	x1 = float(col + 1) / tile_dim * j_in->get_width();

			// Resample from the input strip to the output tile.
			image::resample(tile, 0, 0, tile_size - 1, tile_size - 1,
					strip, x0, y0 - strip_top, x1, y1 - strip_top);

			// Update the table of contents with an offset
			// to the data we're about to write.
			int	offset = out->get_position();
			int	quadtree_index = tqt::node_index(tree_depth - 1, col, row);
			toc[quadtree_index] = offset;

			// Write the jpeg data.
			image::write_jpeg(out, tile, 90);

			int	percent_done = int(100.f * float(col + row * tile_dim) / (tile_dim * tile_dim));
			printf("\b\b\b\b\b\b%3d%% %c", percent_done, spinner[(spin_count++)&3]);
		}
	}


	// Done reading the input file.
	delete j_in;
	delete in;

	delete strip;
	delete tile;	// done with the working tile surface.

	printf("\n");

	printf("making interior tiles....");

	// Now generate the upper levels of the tree by resampling the
	// lower levels.
	// 
	// The output file is both input and output at this point.
	tqt_info	inf(out, &toc, tree_depth, tile_size);
	image::rgb*	root_tile = generate_tiles(&inf, 0, 0, 0);

	delete root_tile;	// dispose of root tile.

	// Write the TOC back into the head of the file.
	out->set_position(toc_start);
	{for (int i = 0; i < toc.size(); i++) {
		out->write_le32(toc[i]);
	}}

	delete out;

	return 0;
}
Ejemplo n.º 15
0
bool
run_example(int argc, char** argv)
{
    // Initialize libMesh, PETSc, MPI, and SAMRAI.
    LibMeshInit init(argc, argv);
    SAMRAI_MPI::setCommunicator(PETSC_COMM_WORLD);
    SAMRAI_MPI::setCallAbortInSerialInsteadOfExit();
    SAMRAIManager::startup();

    { // cleanup dynamically allocated objects prior to shutdown

        // Parse command line options, set some standard options from the input
        // file, initialize the restart database (if this is a restarted run),
        // and enable file logging.
        Pointer<AppInitializer> app_initializer = new AppInitializer(argc, argv, "IB.log");
        Pointer<Database> input_db = app_initializer->getInputDatabase();

        // Setup user-defined kernel function.
        LEInteractor::s_kernel_fcn = &kernel;
        LEInteractor::s_kernel_fcn_stencil_size = 8;

        // Get various standard options set in the input file.
        const bool dump_viz_data = app_initializer->dumpVizData();
        const int viz_dump_interval = app_initializer->getVizDumpInterval();
        const bool uses_visit = dump_viz_data && app_initializer->getVisItDataWriter();
#ifdef LIBMESH_HAVE_EXODUS_API
        const bool uses_exodus = dump_viz_data && !app_initializer->getExodusIIFilename().empty();
#else
        const bool uses_exodus = false;
        if (!app_initializer->getExodusIIFilename().empty())
        {
            plog << "WARNING: libMesh was compiled without Exodus support, so no "
                 << "Exodus output will be written in this program.\n";
        }
#endif
        const string exodus_filename = app_initializer->getExodusIIFilename();

        const bool dump_restart_data = app_initializer->dumpRestartData();
        const int restart_dump_interval = app_initializer->getRestartDumpInterval();
        const string restart_dump_dirname = app_initializer->getRestartDumpDirectory();

        const bool dump_postproc_data = app_initializer->dumpPostProcessingData();
        const int postproc_data_dump_interval = app_initializer->getPostProcessingDataDumpInterval();
        const string postproc_data_dump_dirname = app_initializer->getPostProcessingDataDumpDirectory();
        if (dump_postproc_data && (postproc_data_dump_interval > 0) && !postproc_data_dump_dirname.empty())
        {
            Utilities::recursiveMkdir(postproc_data_dump_dirname);
        }

        const bool dump_timer_data = app_initializer->dumpTimerData();
        const int timer_dump_interval = app_initializer->getTimerDumpInterval();

        // Create a simple FE mesh.
        Mesh solid_mesh(init.comm(), NDIM);
        const double dx = input_db->getDouble("DX");
        const double ds = input_db->getDouble("MFAC") * dx;
        string elem_type = input_db->getString("ELEM_TYPE");
        R = input_db->getDouble("R");
        if (NDIM == 2 && (elem_type == "TRI3" || elem_type == "TRI6"))
        {
#ifdef LIBMESH_HAVE_TRIANGLE
            const int num_circum_nodes = ceil(2.0 * M_PI * R / ds);
            for (int k = 0; k < num_circum_nodes; ++k)
            {
                const double theta = 2.0 * M_PI * static_cast<double>(k) / static_cast<double>(num_circum_nodes);
                solid_mesh.add_point(libMesh::Point(R * cos(theta), R * sin(theta)));
            }
            TriangleInterface triangle(solid_mesh);
            triangle.triangulation_type() = TriangleInterface::GENERATE_CONVEX_HULL;
            triangle.elem_type() = Utility::string_to_enum<ElemType>(elem_type);
            triangle.desired_area() = 1.5 * sqrt(3.0) / 4.0 * ds * ds;
            triangle.insert_extra_points() = true;
            triangle.smooth_after_generating() = true;
            triangle.triangulate();
#else
            TBOX_ERROR("ERROR: libMesh appears to have been configured without support for Triangle,\n"
                       << "       but Triangle is required for TRI3 or TRI6 elements.\n");
#endif
        }
        else
        {
            // NOTE: number of segments along boundary is 4*2^r.
            const double num_circum_segments = 2.0 * M_PI * R / ds;
            const int r = log2(0.25 * num_circum_segments);
            MeshTools::Generation::build_sphere(solid_mesh, R, r, Utility::string_to_enum<ElemType>(elem_type));
        }

        // Ensure nodes on the surface are on the analytic boundary.
        MeshBase::element_iterator el_end = solid_mesh.elements_end();
        for (MeshBase::element_iterator el = solid_mesh.elements_begin(); el != el_end; ++el)
        {
            Elem* const elem = *el;
            for (unsigned int side = 0; side < elem->n_sides(); ++side)
            {
                const bool at_mesh_bdry = !elem->neighbor_ptr(side);
                if (!at_mesh_bdry) continue;
                for (unsigned int k = 0; k < elem->n_nodes(); ++k)
                {
                    if (!elem->is_node_on_side(k, side)) continue;
                    Node& n = elem->node_ref(k);
                    n = R * n.unit();
                }
            }
        }
        solid_mesh.prepare_for_use();
        Mesh& mesh = solid_mesh;

        // Create major algorithm and data objects that comprise the
        // application.  These objects are configured from the input database
        // and, if this is a restarted run, from the restart database.
        Pointer<INSHierarchyIntegrator> navier_stokes_integrator = new INSStaggeredHierarchyIntegrator(
            "INSStaggeredHierarchyIntegrator",
            app_initializer->getComponentDatabase("INSStaggeredHierarchyIntegrator"));

        Pointer<IBFEMethod> ib_method_ops =
            new IBFEMethod("IBFEMethod",
                           app_initializer->getComponentDatabase("IBFEMethod"),
                           &mesh,
                           app_initializer->getComponentDatabase("GriddingAlgorithm")->getInteger("max_levels"));
        Pointer<IBHierarchyIntegrator> time_integrator =
            new IBExplicitHierarchyIntegrator("IBHierarchyIntegrator",
                                              app_initializer->getComponentDatabase("IBHierarchyIntegrator"),
                                              ib_method_ops,
                                              navier_stokes_integrator);
        Pointer<CartesianGridGeometry<NDIM> > grid_geometry = new CartesianGridGeometry<NDIM>(
            "CartesianGeometry", app_initializer->getComponentDatabase("CartesianGeometry"));
        Pointer<PatchHierarchy<NDIM> > patch_hierarchy = new PatchHierarchy<NDIM>("PatchHierarchy", grid_geometry);
        Pointer<StandardTagAndInitialize<NDIM> > error_detector =
            new StandardTagAndInitialize<NDIM>("StandardTagAndInitialize",
                                               time_integrator,
                                               app_initializer->getComponentDatabase("StandardTagAndInitialize"));
        Pointer<BergerRigoutsos<NDIM> > box_generator = new BergerRigoutsos<NDIM>();
        Pointer<LoadBalancer<NDIM> > load_balancer =
            new LoadBalancer<NDIM>("LoadBalancer", app_initializer->getComponentDatabase("LoadBalancer"));
        Pointer<GriddingAlgorithm<NDIM> > gridding_algorithm =
            new GriddingAlgorithm<NDIM>("GriddingAlgorithm",
                                        app_initializer->getComponentDatabase("GriddingAlgorithm"),
                                        error_detector,
                                        box_generator,
                                        load_balancer);

        // Create IBFE direct forcing kinematics object.
        Pointer<IBFEDirectForcingKinematics> df_kinematics_ops = new IBFEDirectForcingKinematics(
            "cylinder_dfk",
            app_initializer->getComponentDatabase("CylinderIBFEDirectForcingKinematics"),
            ib_method_ops,
            /*part*/ 0,
            /*register_for_restart*/ true);
        ib_method_ops->registerDirectForcingKinematics(df_kinematics_ops, /*part*/ 0);

        // Specify structure kinematics
        FreeRigidDOFVector solve_dofs;
        solve_dofs.setZero();
        df_kinematics_ops->setSolveRigidBodyVelocity(solve_dofs);
        df_kinematics_ops->registerKinematicsFunction(&cylinder_kinematics, NULL);

        // Configure the IBFE solver.
        ib_method_ops->initializeFEEquationSystems();
        EquationSystems* equation_systems = ib_method_ops->getFEDataManager()->getEquationSystems();

        // Create Eulerian initial condition specification objects.
        if (input_db->keyExists("VelocityInitialConditions"))
        {
            Pointer<CartGridFunction> u_init = new muParserCartGridFunction(
                "u_init", app_initializer->getComponentDatabase("VelocityInitialConditions"), grid_geometry);
            navier_stokes_integrator->registerVelocityInitialConditions(u_init);
        }

        if (input_db->keyExists("PressureInitialConditions"))
        {
            Pointer<CartGridFunction> p_init = new muParserCartGridFunction(
                "p_init", app_initializer->getComponentDatabase("PressureInitialConditions"), grid_geometry);
            navier_stokes_integrator->registerPressureInitialConditions(p_init);
        }

        // Create Eulerian boundary condition specification objects (when necessary).
        const IntVector<NDIM>& periodic_shift = grid_geometry->getPeriodicShift();
        vector<RobinBcCoefStrategy<NDIM>*> u_bc_coefs(NDIM);
        if (periodic_shift.min() > 0)
        {
            for (unsigned int d = 0; d < NDIM; ++d)
            {
                u_bc_coefs[d] = NULL;
            }
        }
        else
        {
            for (unsigned int d = 0; d < NDIM; ++d)
            {
                const std::string bc_coefs_name = "u_bc_coefs_" + std::to_string(d);

                const std::string bc_coefs_db_name = "VelocityBcCoefs_" + std::to_string(d);

                u_bc_coefs[d] = new muParserRobinBcCoefs(
                    bc_coefs_name, app_initializer->getComponentDatabase(bc_coefs_db_name), grid_geometry);
            }
            navier_stokes_integrator->registerPhysicalBoundaryConditions(u_bc_coefs);
        }

        // Create Eulerian body force function specification objects.
        if (input_db->keyExists("ForcingFunction"))
        {
            Pointer<CartGridFunction> f_fcn = new muParserCartGridFunction(
                "f_fcn", app_initializer->getComponentDatabase("ForcingFunction"), grid_geometry);
            time_integrator->registerBodyForceFunction(f_fcn);
        }

        // Set up visualization plot file writers.
        Pointer<VisItDataWriter<NDIM> > visit_data_writer = app_initializer->getVisItDataWriter();
        if (uses_visit)
        {
            time_integrator->registerVisItDataWriter(visit_data_writer);
        }
        std::unique_ptr<ExodusII_IO> exodus_io(uses_exodus ? new ExodusII_IO(mesh) : NULL);

        // Initialize hierarchy configuration and data on all patches.
        ib_method_ops->initializeFEData();
        time_integrator->initializePatchHierarchy(patch_hierarchy, gridding_algorithm);

        // Deallocate initialization objects.
        app_initializer.setNull();

        // Print the input database contents to the log file.
        plog << "Input database:\n";
        input_db->printClassData(plog);

        // Write out initial visualization data.
        int iteration_num = time_integrator->getIntegratorStep();
        double loop_time = time_integrator->getIntegratorTime();
        if (dump_viz_data)
        {
            pout << "\n\nWriting visualization files...\n\n";
            if (uses_visit)
            {
                time_integrator->setupPlotData();
                visit_data_writer->writePlotData(patch_hierarchy, iteration_num, loop_time);
            }
            if (uses_exodus)
            {
                exodus_io->write_timestep(
                    exodus_filename, *equation_systems, iteration_num / viz_dump_interval + 1, loop_time);
            }
        }

        // Open streams to save lift and drag coefficients.
        if (SAMRAI_MPI::getRank() == 0)
        {
            drag_stream.open("C_D.curve", ios_base::out | ios_base::trunc);
            lift_stream.open("C_L.curve", ios_base::out | ios_base::trunc);

            drag_stream.precision(10);
            lift_stream.precision(10);
        }

        // Main time step loop.
        double loop_time_end = time_integrator->getEndTime();
        double dt = 0.0;
        while (!MathUtilities<double>::equalEps(loop_time, loop_time_end) && time_integrator->stepsRemaining())
        {
            iteration_num = time_integrator->getIntegratorStep();
            loop_time = time_integrator->getIntegratorTime();

            pout << "\n";
            pout << "+++++++++++++++++++++++++++++++++++++++++++++++++++\n";
            pout << "At beginning of timestep # " << iteration_num << "\n";
            pout << "Simulation time is " << loop_time << "\n";

            dt = time_integrator->getMaximumTimeStepSize();
            time_integrator->advanceHierarchy(dt);
            loop_time += dt;

            pout << "\n";
            pout << "At end       of timestep # " << iteration_num << "\n";
            pout << "Simulation time is " << loop_time << "\n";
            pout << "+++++++++++++++++++++++++++++++++++++++++++++++++++\n";
            pout << "\n";

            // At specified intervals, write visualization and restart files,
            // print out timer data, and store hierarchy data for post
            // processing.
            iteration_num += 1;
            const bool last_step = !time_integrator->stepsRemaining();
            if (dump_viz_data && (iteration_num % viz_dump_interval == 0 || last_step))
            {
                pout << "\nWriting visualization files...\n\n";
                if (uses_visit)
                {
                    time_integrator->setupPlotData();
                    visit_data_writer->writePlotData(patch_hierarchy, iteration_num, loop_time);
                }
                if (uses_exodus)
                {
                    exodus_io->write_timestep(
                        exodus_filename, *equation_systems, iteration_num / viz_dump_interval + 1, loop_time);
                }
            }
            if (dump_restart_data && (iteration_num % restart_dump_interval == 0 || last_step))
            {
                pout << "\nWriting restart files...\n\n";
                RestartManager::getManager()->writeRestartFile(restart_dump_dirname, iteration_num);
            }
            if (dump_timer_data && (iteration_num % timer_dump_interval == 0 || last_step))
            {
                pout << "\nWriting timer data...\n\n";
                TimerManager::getManager()->print(plog);
            }
            if (dump_postproc_data && (iteration_num % postproc_data_dump_interval == 0 || last_step))
            {
                postprocess_data(patch_hierarchy,
                                 navier_stokes_integrator,
                                 mesh,
                                 equation_systems,
                                 iteration_num,
                                 loop_time,
                                 postproc_data_dump_dirname);
            }
        }

        // Close the logging streams.
        if (SAMRAI_MPI::getRank() == 0)
        {
            drag_stream.close();
            lift_stream.close();
        }

        // Cleanup Eulerian boundary condition specification objects (when
        // necessary).
        for (unsigned int d = 0; d < NDIM; ++d) delete u_bc_coefs[d];

    } // cleanup dynamically allocated objects prior to shutdown

    SAMRAIManager::shutdown();
    return true;
} // run_example
Ejemplo n.º 16
0
//Operate does operations AND NOT OR DECODER MUX
void operate(int *table, FILE *circ)
{
  //These declarations are for the switch cases AND and OR
  int var1, var2, var3;
  char a, b, c;

  //Reading the operation name
  char temp[100];
  fscanf(circ, "%s", temp);

  switch (temp[0])
    {
      //Case AND
    case 'A': 
      fscanf(circ, " %c %c %c\n", &a, &b, &c);

      int hashA = hash(a);
      int hashB = hash(b);
      int hashC = hash(c);

      var1 = table[hashA];
      var2 = table[hashB];

      if (var1 == -1)
	var1 = atoi(&a);
      if (var2 == -1)
	var2 = atoi(&b);

      var3 = var1&&var2;
      //printf("AND: %d\n", var3);
      table[hashC] = var3;
      break;
      
      //Case OR
    case 'O': 
      fscanf(circ, " %c %c %c\n", &a, &b, &c);

      var1 = table[hash(a)];
      var2 = table[hash(b)];
      
      if (var1 == -1)
	var1 = atoi(&a);
      if (var2 == -1)
	var2 = atoi(&b);

      var3 = var1||var2;
      //printf("OR: %d\n", var3);
      table[hash(c)] = var3;
      break;

      //Case NOT
    case 'N':
      fscanf(circ, " %c %c\n", &a, &b);

      var1 = table[hash(a)];

      if (var1 == -1)
	var1 = atoi(&a);

      var2 = !var1;
      //printf("NOT: %d\n", var2);
      table[hash(b)] = var2;
      break;

      //Case DECODER
    case 'D': ;

      //Declarations of variables for this function's use
      int greycode[100], temp, size, counter = 0;
      char greyoutput[100];


      //Find out how many inputvars
      fscanf(circ, " %d ", &temp);

      //Reading the DECODER line and getting the input vars
      while(counter < temp)
	{
	  fscanf(circ, " %c", &a);
	  greyoutput[counter] = a;
	  counter++;
	}

      //Decode for last 2 variables
      char first, second;
      first = greyoutput[counter-2];
      second = greyoutput[counter-1];

      decoder(greycode, table, first, second);
      counter -= 2;
      size = 4;

      //If there are more than 2 input variables
      while(counter > 0)
	{
	  size = size*2;
	  decode(greycode, table, size, greyoutput[counter-1]);
	  counter--;
	}

      //put these values back in for variables
      temp = (int) pow(2.0, temp);      

      //Get output vars
      int loop;
      for (loop = 0; loop < temp; loop++)
	{
	  fscanf(circ, " %c", &a);
	  greyoutput[loop] = a;
	}
      fscanf(circ, "\n");
      //set values for the local variables in temp array
      while (loop >= 0)
	{
	  char ind = greyoutput[loop];
	  table[hash(ind)] = greycode[loop];
	  loop--;
	}
      break;

      //Case MULTIPLEXER
    case 'M': ;

      //int index, inpindex;
      char greyinps[100], selectors[100], output;
      counter = 0;

      //MUX INPUTS XOR OUTPUTS CAN BE VARIABLES OR INT VALUES
      fscanf(circ, " %d", &temp);


      //Scan input variables
      while (counter < temp)
	{
	  fscanf(circ, " %c", &a);
	  greyinps[counter] = a;
	  counter++;
	}

      int numselectors;
      //Scan output selectors
      numselectors = (int) log2(temp);


      for (counter = 0; counter < numselectors; counter++)
	{
	  fscanf(circ, " %c", &a);
	  selectors[counter] = a;
	}


      //Scan output variable
      fscanf(circ, " %c\n", &output);      
      
      //This is the array which contains greycode decimal
      //converted numbers
      int arr[1000];

      //This creates the array that contains the indexes
      creategrey(arr);
      size = 2;
      while (numselectors-2 >= 0)
	{
	  makegrey(arr, size);
	  size = size*2;
	  numselectors--;
	}      

      //Convert selector value to binary
      int index = 0;
      loop = counter-1;
      int power;

      while (loop >= 0)
	{
	  //if the selector has a variable value
	  if (hash(selectors[loop]) != -1)
	    {
	      char c = selectors[loop];
	      int val = hash(c);
	      if (table[val] == 1)
		{
		  power = counter-loop-1;
		  index += pow(2.0, power);
		}
	    }
	  //if the selector is a int number
	  else if (selectors[loop] == '1')
	    {
	      power = counter-loop-1;
	      index += pow(2.0, power);
	    }
	  loop--;
	}
      
      //find the index in arr where index = arr[ind]
      for (loop = 0; loop < size; loop++)
	{
	  if (arr[loop] == index)
	    {
	      index = loop;
	      break;
	    }
	}
      int val = hash(output);

      if (greyinps[index] == '1' || greyinps[index] == '0')
	{	  	  
	  char c = greyinps[index];
	  table[val] = atoi(&c);
	}
      else
	table[val] = table[hash(greyinps[index])];

      //printf("output:%c %d\n", output, table[val]);
      break;

    default:
      break;
    }

}
Ejemplo n.º 17
0
static inline unsigned int size_to_bucket(size_t size) {
  if (size < kMinBucketAllocationSize) return kMinBucketAllocationSize;
  return log2(size - 1) + 1 - const_log2(kMinBucketAllocationSize);
}
Ejemplo n.º 18
0
void
default_pager_initialize(
	mach_port_t host_port)
{
	kern_return_t		kr;
	static char		here[] = "default_pager_initialize";

	/* 
	 * Initial thread and task ports.
	 */
	default_pager_self = mach_task_self();
	default_pager_default_thread = mach_thread_self();

	PRINTF_LOCK_INIT();

	/*
	 * Make ourselves unswappable.
	 */
	kr = task_swappable(default_pager_host_port, default_pager_self, FALSE);
	if (kr != KERN_SUCCESS)
		dprintf(("task_swappable failed 0x%x %s\n",
			 kr, mach_error_string(kr)));

	/*
	 * Exported DMM port.
	 */
	kr = mach_port_allocate(default_pager_self, MACH_PORT_RIGHT_RECEIVE,
				&default_pager_default_port);
	if (kr != KERN_SUCCESS)
		Panic("default port");

	/*
	 * Port sets.
	 */
	kr = mach_port_allocate(default_pager_self, MACH_PORT_RIGHT_PORT_SET,
				&default_pager_internal_set);
	if (kr != KERN_SUCCESS)
		Panic("internal set");

	kr = mach_port_allocate(default_pager_self, MACH_PORT_RIGHT_PORT_SET,
				&default_pager_external_set);
	if (kr != KERN_SUCCESS)
		Panic("external set");

	/*
	 * Export pager interfaces.
	 */
#ifdef	USER_PAGER
	if ((kr = netname_check_in(name_server_port, "UserPager",
				   default_pager_self,
				   default_pager_default_port))
	    != KERN_SUCCESS) {
		dprintf(("netname_check_in returned 0x%x %s\n",
			 kr, mach_error_string(kr)));
		exit(1);
	}
#else	/* USER_PAGER */
	{
		int clsize;
		memory_object_t DMM;

		/* get a send right for vm_set_default_memory_manager */
		kr = mach_port_insert_right(default_pager_self,
					    default_pager_default_port,
					    default_pager_default_port,
					    MACH_MSG_TYPE_MAKE_SEND);
		DMM = default_pager_default_port;
		clsize = (vm_page_size << vstruct_def_clshift);

		kr = host_default_memory_manager(host_port, &DMM, clsize);
		if ((kr != KERN_SUCCESS) || (DMM != MACH_PORT_NULL))
			Panic("default memory manager");

		/* release the extra send right */
		(void) mach_port_mod_refs(default_pager_self,
					  default_pager_default_port,
					  MACH_PORT_RIGHT_SEND,
					  -1);
	}
#endif	/* USER_PAGER */

	kr = mach_port_allocate(default_pager_self, MACH_PORT_RIGHT_PORT_SET,
				&default_pager_default_set);
	if (kr != KERN_SUCCESS)
		Panic("default set");

	kr = mach_port_move_member(default_pager_self,
				   default_pager_default_port,
				   default_pager_default_set);
	if (kr != KERN_SUCCESS)
		Panic("set up default");

	/*
	 * Arrange for wiring privileges.
	 */
	wire_setup(host_port);

	/*
	 * Find out how many CPUs we have, to determine the number
	 * of threads to create.
	 */
	if (default_pager_internal_count == 0) {
		host_basic_info_data_t h_info;
		mach_msg_type_number_t h_info_count;

		h_info_count = HOST_BASIC_INFO_COUNT;
		(void) host_info(host_port, HOST_BASIC_INFO,
				(host_info_t) &h_info, &h_info_count);

		/*
		 * Random computation to get more parallelism on
		 * multiprocessors.
		 */
		default_pager_internal_count = ((h_info.avail_cpus > 32)
						? 32
						: h_info.avail_cpus) / 4 + 3;
	}

	/*
	 * Vm variables.
	 */
	vm_page_mask = vm_page_size - 1;
	vm_page_shift = log2(vm_page_size);

	/*
	 * List of all vstructs.
	 */
	VSL_LOCK_INIT();
	queue_init(&vstruct_list.vsl_queue);
	queue_init(&vstruct_list.vsl_leak_queue);
	vstruct_list.vsl_count = 0;

	VSTATS_LOCK_INIT(&global_stats.gs_lock);

	bs_initialize();
}
Ejemplo n.º 19
0
static int ext2_fill_super(struct super_block *sb, void *data, int silent)
{
	struct buffer_head * bh;
	struct ext2_sb_info * sbi;
	struct ext2_super_block * es;
	struct inode *root;
	unsigned long block;
	unsigned long sb_block = get_sb_block(&data);
	unsigned long logic_sb_block;
	unsigned long offset = 0;
	unsigned long def_mount_opts;
	int blocksize = BLOCK_SIZE;
	int db_count;
	int i, j;
	__le32 features;

	sbi = kmalloc(sizeof(*sbi), GFP_KERNEL);
	if (!sbi)
		return -ENOMEM;
	sb->s_fs_info = sbi;
	memset(sbi, 0, sizeof(*sbi));

	/*
	 * See what the current blocksize for the device is, and
	 * use that as the blocksize.  Otherwise (or if the blocksize
	 * is smaller than the default) use the default.
	 * This is important for devices that have a hardware
	 * sectorsize that is larger than the default.
	 */
	blocksize = sb_min_blocksize(sb, BLOCK_SIZE);
	if (!blocksize) {
		printk ("EXT2-fs: unable to set blocksize\n");
		goto failed_sbi;
	}

	/*
	 * If the superblock doesn't start on a hardware sector boundary,
	 * calculate the offset.  
	 */
	if (blocksize != BLOCK_SIZE) {
		logic_sb_block = (sb_block*BLOCK_SIZE) / blocksize;
		offset = (sb_block*BLOCK_SIZE) % blocksize;
	} else {
		logic_sb_block = sb_block;
	}

	if (!(bh = sb_bread(sb, logic_sb_block))) {
		printk ("EXT2-fs: unable to read superblock\n");
		goto failed_sbi;
	}
	/*
	 * Note: s_es must be initialized as soon as possible because
	 *       some ext2 macro-instructions depend on its value
	 */
	es = (struct ext2_super_block *) (((char *)bh->b_data) + offset);
	sbi->s_es = es;
	sb->s_magic = le16_to_cpu(es->s_magic);

	if (sb->s_magic != EXT2_SUPER_MAGIC)
		goto cantfind_ext2;

	/* Set defaults before we parse the mount options */
	def_mount_opts = le32_to_cpu(es->s_default_mount_opts);
	if (def_mount_opts & EXT2_DEFM_DEBUG)
		set_opt(sbi->s_mount_opt, DEBUG);
	if (def_mount_opts & EXT2_DEFM_BSDGROUPS)
		set_opt(sbi->s_mount_opt, GRPID);
	if (def_mount_opts & EXT2_DEFM_UID16)
		set_opt(sbi->s_mount_opt, NO_UID32);
	if (def_mount_opts & EXT2_DEFM_XATTR_USER)
		set_opt(sbi->s_mount_opt, XATTR_USER);
	if (def_mount_opts & EXT2_DEFM_ACL)
		set_opt(sbi->s_mount_opt, POSIX_ACL);
	
	if (le16_to_cpu(sbi->s_es->s_errors) == EXT2_ERRORS_PANIC)
		set_opt(sbi->s_mount_opt, ERRORS_PANIC);
	else if (le16_to_cpu(sbi->s_es->s_errors) == EXT2_ERRORS_RO)
		set_opt(sbi->s_mount_opt, ERRORS_RO);

	sbi->s_resuid = le16_to_cpu(es->s_def_resuid);
	sbi->s_resgid = le16_to_cpu(es->s_def_resgid);
	
	if (!parse_options ((char *) data, sbi))
		goto failed_mount;

	sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
		((EXT2_SB(sb)->s_mount_opt & EXT2_MOUNT_POSIX_ACL) ?
		 MS_POSIXACL : 0);

	if (le32_to_cpu(es->s_rev_level) == EXT2_GOOD_OLD_REV &&
	    (EXT2_HAS_COMPAT_FEATURE(sb, ~0U) ||
	     EXT2_HAS_RO_COMPAT_FEATURE(sb, ~0U) ||
	     EXT2_HAS_INCOMPAT_FEATURE(sb, ~0U)))
		printk("EXT2-fs warning: feature flags set on rev 0 fs, "
		       "running e2fsck is recommended\n");
	/*
	 * Check feature flags regardless of the revision level, since we
	 * previously didn't change the revision level when setting the flags,
	 * so there is a chance incompat flags are set on a rev 0 filesystem.
	 */
	features = EXT2_HAS_INCOMPAT_FEATURE(sb, ~EXT2_FEATURE_INCOMPAT_SUPP);
	if (features) {
		printk("EXT2-fs: %s: couldn't mount because of "
		       "unsupported optional features (%x).\n",
		       sb->s_id, le32_to_cpu(features));
		goto failed_mount;
	}
	if (!(sb->s_flags & MS_RDONLY) &&
	    (features = EXT2_HAS_RO_COMPAT_FEATURE(sb, ~EXT2_FEATURE_RO_COMPAT_SUPP))){
		printk("EXT2-fs: %s: couldn't mount RDWR because of "
		       "unsupported optional features (%x).\n",
		       sb->s_id, le32_to_cpu(features));
		goto failed_mount;
	}

	blocksize = BLOCK_SIZE << le32_to_cpu(sbi->s_es->s_log_block_size);

	/* If the blocksize doesn't match, re-read the thing.. */
	if (sb->s_blocksize != blocksize) {
		brelse(bh);

		if (!sb_set_blocksize(sb, blocksize)) {
			printk(KERN_ERR "EXT2-fs: blocksize too small for device.\n");
			goto failed_sbi;
		}

		logic_sb_block = (sb_block*BLOCK_SIZE) / blocksize;
		offset = (sb_block*BLOCK_SIZE) % blocksize;
		bh = sb_bread(sb, logic_sb_block);
		if(!bh) {
			printk("EXT2-fs: Couldn't read superblock on "
			       "2nd try.\n");
			goto failed_sbi;
		}
		es = (struct ext2_super_block *) (((char *)bh->b_data) + offset);
		sbi->s_es = es;
		if (es->s_magic != cpu_to_le16(EXT2_SUPER_MAGIC)) {
			printk ("EXT2-fs: Magic mismatch, very weird !\n");
			goto failed_mount;
		}
	}

	sb->s_maxbytes = ext2_max_size(sb->s_blocksize_bits);

	if (le32_to_cpu(es->s_rev_level) == EXT2_GOOD_OLD_REV) {
		sbi->s_inode_size = EXT2_GOOD_OLD_INODE_SIZE;
		sbi->s_first_ino = EXT2_GOOD_OLD_FIRST_INO;
	} else {
		sbi->s_inode_size = le16_to_cpu(es->s_inode_size);
		sbi->s_first_ino = le32_to_cpu(es->s_first_ino);
		if ((sbi->s_inode_size < EXT2_GOOD_OLD_INODE_SIZE) ||
		    (sbi->s_inode_size & (sbi->s_inode_size - 1)) ||
		    (sbi->s_inode_size > blocksize)) {
			printk ("EXT2-fs: unsupported inode size: %d\n",
				sbi->s_inode_size);
			goto failed_mount;
		}
	}

	sbi->s_frag_size = EXT2_MIN_FRAG_SIZE <<
				   le32_to_cpu(es->s_log_frag_size);
	if (sbi->s_frag_size == 0)
		goto cantfind_ext2;
	sbi->s_frags_per_block = sb->s_blocksize / sbi->s_frag_size;

	sbi->s_blocks_per_group = le32_to_cpu(es->s_blocks_per_group);
	sbi->s_frags_per_group = le32_to_cpu(es->s_frags_per_group);
	sbi->s_inodes_per_group = le32_to_cpu(es->s_inodes_per_group);

	if (EXT2_INODE_SIZE(sb) == 0)
		goto cantfind_ext2;
	sbi->s_inodes_per_block = sb->s_blocksize / EXT2_INODE_SIZE(sb);
	if (sbi->s_inodes_per_block == 0)
		goto cantfind_ext2;
	sbi->s_itb_per_group = sbi->s_inodes_per_group /
					sbi->s_inodes_per_block;
	sbi->s_desc_per_block = sb->s_blocksize /
					sizeof (struct ext2_group_desc);
	sbi->s_sbh = bh;
	sbi->s_mount_state = le16_to_cpu(es->s_state);
	sbi->s_addr_per_block_bits =
		log2 (EXT2_ADDR_PER_BLOCK(sb));
	sbi->s_desc_per_block_bits =
		log2 (EXT2_DESC_PER_BLOCK(sb));

	if (sb->s_magic != EXT2_SUPER_MAGIC)
		goto cantfind_ext2;

	if (sb->s_blocksize != bh->b_size) {
		if (!silent)
			printk ("VFS: Unsupported blocksize on dev "
				"%s.\n", sb->s_id);
		goto failed_mount;
	}

	if (sb->s_blocksize != sbi->s_frag_size) {
		printk ("EXT2-fs: fragsize %lu != blocksize %lu (not supported yet)\n",
			sbi->s_frag_size, sb->s_blocksize);
		goto failed_mount;
	}

	if (sbi->s_blocks_per_group > sb->s_blocksize * 8) {
		printk ("EXT2-fs: #blocks per group too big: %lu\n",
			sbi->s_blocks_per_group);
		goto failed_mount;
	}
	if (sbi->s_frags_per_group > sb->s_blocksize * 8) {
		printk ("EXT2-fs: #fragments per group too big: %lu\n",
			sbi->s_frags_per_group);
		goto failed_mount;
	}
	if (sbi->s_inodes_per_group > sb->s_blocksize * 8) {
		printk ("EXT2-fs: #inodes per group too big: %lu\n",
			sbi->s_inodes_per_group);
		goto failed_mount;
	}

	if (EXT2_BLOCKS_PER_GROUP(sb) == 0)
		goto cantfind_ext2;
	sbi->s_groups_count = (le32_to_cpu(es->s_blocks_count) -
				        le32_to_cpu(es->s_first_data_block) +
				       EXT2_BLOCKS_PER_GROUP(sb) - 1) /
				       EXT2_BLOCKS_PER_GROUP(sb);
	db_count = (sbi->s_groups_count + EXT2_DESC_PER_BLOCK(sb) - 1) /
		   EXT2_DESC_PER_BLOCK(sb);
	sbi->s_group_desc = kmalloc (db_count * sizeof (struct buffer_head *), GFP_KERNEL);
	if (sbi->s_group_desc == NULL) {
		printk ("EXT2-fs: not enough memory\n");
		goto failed_mount;
	}
	percpu_counter_init(&sbi->s_freeblocks_counter);
	percpu_counter_init(&sbi->s_freeinodes_counter);
	percpu_counter_init(&sbi->s_dirs_counter);
	bgl_lock_init(&sbi->s_blockgroup_lock);
	sbi->s_debts = kmalloc(sbi->s_groups_count * sizeof(*sbi->s_debts),
			       GFP_KERNEL);
	if (!sbi->s_debts) {
		printk ("EXT2-fs: not enough memory\n");
		goto failed_mount_group_desc;
	}
	memset(sbi->s_debts, 0, sbi->s_groups_count * sizeof(*sbi->s_debts));
	for (i = 0; i < db_count; i++) {
		block = descriptor_loc(sb, logic_sb_block, i);
		sbi->s_group_desc[i] = sb_bread(sb, block);
		if (!sbi->s_group_desc[i]) {
			for (j = 0; j < i; j++)
				brelse (sbi->s_group_desc[j]);
			printk ("EXT2-fs: unable to read group descriptors\n");
			goto failed_mount_group_desc;
		}
	}
	if (!ext2_check_descriptors (sb)) {
		printk ("EXT2-fs: group descriptors corrupted!\n");
		db_count = i;
		goto failed_mount2;
	}
	sbi->s_gdb_count = db_count;
	get_random_bytes(&sbi->s_next_generation, sizeof(u32));
	spin_lock_init(&sbi->s_next_gen_lock);
	/*
	 * set up enough so that it can read an inode
	 */
	sb->s_op = &ext2_sops;
	sb->s_export_op = &ext2_export_ops;
	sb->s_xattr = ext2_xattr_handlers;
	root = iget(sb, EXT2_ROOT_INO);
	sb->s_root = d_alloc_root(root);
	if (!sb->s_root) {
		iput(root);
		printk(KERN_ERR "EXT2-fs: get root inode failed\n");
		goto failed_mount2;
	}
	if (!S_ISDIR(root->i_mode) || !root->i_blocks || !root->i_size) {
		dput(sb->s_root);
		sb->s_root = NULL;
		printk(KERN_ERR "EXT2-fs: corrupt root inode, run e2fsck\n");
		goto failed_mount2;
	}
	if (EXT2_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_HAS_JOURNAL))
		ext2_warning(sb, __FUNCTION__,
			"mounting ext3 filesystem as ext2\n");
	ext2_setup_super (sb, es, sb->s_flags & MS_RDONLY);
	percpu_counter_mod(&sbi->s_freeblocks_counter,
				ext2_count_free_blocks(sb));
	percpu_counter_mod(&sbi->s_freeinodes_counter,
				ext2_count_free_inodes(sb));
	percpu_counter_mod(&sbi->s_dirs_counter,
				ext2_count_dirs(sb));
	return 0;

cantfind_ext2:
	if (!silent)
		printk("VFS: Can't find an ext2 filesystem on dev %s.\n",
		       sb->s_id);
	goto failed_mount;

failed_mount2:
	for (i = 0; i < db_count; i++)
		brelse(sbi->s_group_desc[i]);
failed_mount_group_desc:
	kfree(sbi->s_group_desc);
	kfree(sbi->s_debts);
failed_mount:
	brelse(bh);
failed_sbi:
	sb->s_fs_info = NULL;
	kfree(sbi);
	return -EINVAL;
}
 int rangeBitwiseAnd(int m, int n) {
    /// return 0xffffffff<<(int)floor(log(n-m))&n; //bug:n-m可能为0
    return (0xffffffff << (int)ceil(log2(n-m+1))) & m & n;
    或
    return (n > m) ? (rangeBitwiseAnd(m/2, n/2) << 1) : m;
 }
Ejemplo n.º 21
0
int ms_pack_steim 
   (DATA_HDR	*hdr0,		/* ptr to initial data hdr.		*/
    BS		*init_bs,	/* ptr to onetime blockettes.		*/
    int		*data,		/* ptr to data buffer.			*/
    int		*diff,		/* ptr to diff buffer (optional)	*/
    int		num_samples,	/* number of data samples.		*/
    int		*n_blocks,	/* # miniSEED blocks (returned).	*/
    char	**pp_ms,	/* ptr **miniSEED (returned).		*/
    int		ms_len,		/* miniSEED buffer len (if supplied).	*/
    char	*p_errmsg)	/* ptr to error msg buffer.		*/
{
	DATA_HDR *hdr;		/* data_hdr used for writing Mini-SEED	*/
	char *p_ms;			/* ptr to current Mini-SEED block.	*/
	SDF *p_sdf;			/* ptr to STEIM data frame.		*/
	char errmsg[256];		/* error msg buffer.			*/
	unsigned char *minbits;	/* min # of bits required to pack data.	*/
	int free_diff = 0;		/* flag to remind whether we free diff.	*/
	int ipt;			/* index of data to pack.		*/
	int nblks_malloced;		/* # Mini-SEED output blocks malloced.	*/
	int num_blocks;		/* # Mini-SEED block created.		*/
	int samples_remaining;	/* # samples left to cvt to Mini-seed.	*/
	int frames_per_block;	/* # of steim compressed framed per blk.*/
	int	nframes;		/* # of steim frames in Mini-SEED block.*/
	int nsamples;		/* # of samples in Mini-SEED block.	*/
	int seconds, usecs;		/* seconds and usecs for time calcs.	*/
	int pad;			/* flag to indicate padding of frames.	*/
	int status;			/* status from data packing routine.	*/
	int i;			/* loop indices.			*/
	int blksize = hdr0->blksize;/* output blksize.			*/
	
	/* Initialization.							*/
	*n_blocks = 0;
	minbits = NULL;
	
	/* Check for invalid arguments.					*/
	if (num_samples <= 0) return(MS_ERROR);
	if (blksize < 128 || 
			(blksize != (int)pow(2.0,rint(log2((double)blksize))))) {
		sprintf (errmsg, "Warning: invalid blksize: %d\n", blksize);
		if (p_errmsg) strcpy(p_errmsg, errmsg);
		else fprintf (stderr, "%s", errmsg);
		return (MS_ERROR);
	}
	
	/* If no diff buffer provided, create one and compute differences.	*/
	if (diff == NULL) {
		if ((diff = (int *)malloc(num_samples * sizeof(int))) == NULL) {
	    sprintf (errmsg, "Error mallocing diff buffer\n");
	    if (p_errmsg) strcpy(p_errmsg, errmsg);
	    else fprintf (stderr, "%s", errmsg);
	    return (QLIB2_MALLOC_ERROR);
		}
		free_diff = 1;
		diff[0] = data[0] - hdr0->xm1;
		for (i=1; i<num_samples; i++) {
	    diff[i] = data[i] - data[i-1];
		}
	}
	
	/* If *pp_ms != NULL, assume that the caller is providing sufficient*/
	/* memory to hold all of the resulting Mini-SEED records.		*/
	/* If it is NULL, we allocate the space, and set it to point to the	*/
	/* allocated Mini-SEED records.					*/
	/* If we allocated the space for the Mini-SEED, the caller is	*/
	/* responsible for freeing the space.				*/
	if (*pp_ms) nblks_malloced = -1;
	else nblks_malloced = 0;
	
	/* Create a copy of the initial data_hdr for our use.		*/
	/* We will update this each time we create a Mini-SEED block.	*/
	hdr = dup_data_hdr (hdr0);
	if (hdr == NULL) {
		if (free_diff) free(diff);
		return (MS_ERROR);
	}
	
	/* Start compressor.						*/
	num_blocks = 0;
	samples_remaining = num_samples;
	ipt = 0;
	pad = 1;
	
	while (samples_remaining) {
		/* Check for available space.					*/
		/* Allocate more space for Mini-SEED blocks if necessary.	*/
		if (nblks_malloced < 0) {
	    if (ms_len < blksize) {
				*n_blocks = num_blocks;
				if(free_diff) free( (char *) diff);
				free_data_hdr(hdr);
				return (num_samples - samples_remaining);
	    }
	    ms_len -= blksize;
		}
		if (nblks_malloced >= 0 && num_blocks == nblks_malloced) {
	    *pp_ms = (*pp_ms == NULL) ?
				(char *)malloc((nblks_malloced+MALLOC_INCREMENT)*blksize) :
				(char *)realloc(*pp_ms,(nblks_malloced+MALLOC_INCREMENT)*blksize);
	    if (*pp_ms == NULL) {
				sprintf (errmsg, "Error mallocing Mini-SEED buffer\n");
				if (p_errmsg) strcpy(p_errmsg, errmsg);
				else fprintf (stderr, "%s", errmsg);
				if (free_diff) free ((char *)diff);
				free_data_hdr (hdr);
				return (QLIB2_MALLOC_ERROR);
	    }
	    nblks_malloced += MALLOC_INCREMENT;
		}
		
		/* Initialize the next fixed data header.			*/
		p_ms = *pp_ms + (num_blocks * blksize);
		if (init_miniseed_hdr ((SDR_HDR *)p_ms, hdr, init_bs) < 0) {
	    sprintf (errmsg, "Error: initializing MiniSEED header");
	    if (p_errmsg) strcpy(p_errmsg, errmsg);
	    else fprintf (stderr, "%s", errmsg);
	    if (free_diff) free ((char *)diff);
	    free_data_hdr (hdr);
	    if (nblks_malloced > 0) free(*pp_ms);
	    return (MS_ERROR);
		}
		
		init_bs = NULL;
		frames_per_block = (blksize-hdr->first_data) / 64;
		p_sdf = (SDF *)(p_ms + hdr->first_data);
		
		/* Pack data into the next Mini-SEED block.			*/
		switch (hdr->data_type) {
	  case STEIM1:
	    status = pack_steim1 (p_sdf, &data[ipt], &diff[ipt], 
														samples_remaining, frames_per_block, 
				  pad, hdr->data_wordorder, &nframes, &nsamples);
	    break;
	  case STEIM2:
	    status = pack_steim2 (p_sdf, &data[ipt], &diff[ipt], 
														samples_remaining, frames_per_block, 
														pad, hdr->data_wordorder, &nframes, &nsamples);
	    break;
	  default:
	    sprintf (errmsg, "Error: invalid format %d for ms_pack_steim\n",
							 hdr->data_type);
	    if (p_errmsg) strcpy(p_errmsg, errmsg);
	    else fprintf (stderr, "%s", errmsg);
	    fflush (stderr);
	    if (QLIB2_CLASSIC) exit (1);
	    if (free_diff) free ((char *)diff);
	    free_data_hdr (hdr);
	    if (nblks_malloced > 0) free(*pp_ms);
	    return (MS_ERROR);
	    break;
		}
		
		if (status != 0) {
			sprintf (errmsg, "Error packing %s data\n",
							 (hdr->data_type == STEIM1) ? "STEIM1" : "STEIM2");
			if (p_errmsg) strcpy(p_errmsg, errmsg);
			else fprintf (stderr, "%s", errmsg);
			if (free_diff) free ((char *)diff);
			free_data_hdr (hdr);
			*n_blocks = num_blocks;
			return (status);
		}
	
		/* End of data or Mini-SEED block is full.			*/
		/* Update Mini-SEED header with:				*/
		/*	final sample count.					*/
		/* Update hdr for the next record.				*/
		hdr->num_samples = nsamples;
		update_miniseed_hdr ((SDR_HDR *)p_ms, hdr);
		ms_pack_update_hdr (hdr, 1, nsamples, &data[ipt]);
		ipt += nsamples;
		samples_remaining -= nsamples;
		++num_blocks;
		hdr->num_samples = 0;
	}
	
	/* Cleanup.								*/
	free ((char *)minbits);
	free_data_hdr (hdr);
	if (free_diff) free ((char *)diff);
	*n_blocks = num_blocks;
	ms_pack_update_return_hdr (hdr0, num_blocks, num_samples, data);
	return(num_samples);
}
void PD_flow_mrpt::solveSceneFlowGPU()
{
    printf("Solving Scene Flow...\n");

    //Define variables
    CTicTac	clock;

    unsigned int s;
    unsigned int cols_i, rows_i;
    unsigned int level_image;
    unsigned int num_iter;

    clock.Tic();

    printf("Level: ");
    //For every level (coarse-to-fine)
    for (unsigned int i=0; i<ctf_levels; i++)
    {
        printf("%d ", i);
        const unsigned int width = colour_wf.getColCount();
        s = pow(2.f,int(ctf_levels-(i+1)));
        cols_i = cols/s;
        rows_i = rows/s;
        level_image = ctf_levels - i + round(log2(width/cols)) - 1;

        //=========================================================================
        //                              Cuda - Begin
        //=========================================================================

        //Cuda allocate memory
        csf_host.allocateMemoryNewLevel(rows_i, cols_i, i, level_image);

        //Cuda copy object to device
        csf_device = ObjectToDevice(&csf_host);

        //Assign zeros to the corresponding variables
        AssignZerosBridge(csf_device);

        //Upsample previous solution
        if (i>0)
            UpsampleBridge(csf_device);

        //Compute connectivity (Rij)
		RijBridge(csf_device);
		
		//Compute colour and depth derivatives
        ImageGradientsBridge(csf_device);
        WarpingBridge(csf_device);

        //Compute mu_uv and step sizes for the primal-dual algorithm
        MuAndStepSizesBridge(csf_device);

		//Primal-Dual solver
        for (num_iter = 0; num_iter < num_max_iter[i]; num_iter++)
        {
            GradientBridge(csf_device);
            DualVariablesBridge(csf_device);
            DivergenceBridge(csf_device);
            PrimalVariablesBridge(csf_device);
        }

        //Filter solution
        FilterBridge(csf_device);

        //Compute the motion field
        MotionFieldBridge(csf_device);

        //BridgeBack
        BridgeBack(&csf_host, csf_device);

        //Free variables of variables associated to this level
        csf_host.freeLevelVariables();

        //Copy motion field and images to CPU
		csf_host.copyAllSolutions(dx[ctf_levels-i-1].data(), dy[ctf_levels-i-1].data(), dz[ctf_levels-i-1].data(),
                        depth[level_image].data(), depth_old[level_image].data(), colour[level_image].data(), colour_old[level_image].data(),
                        xx[level_image].data(), xx_old[level_image].data(), yy[level_image].data(), yy_old[level_image].data());

		//For debugging
        //DebugBridge(csf_device);

        //=========================================================================
        //                              Cuda - end
        //=========================================================================
    }
}
Ejemplo n.º 23
0
int main(int argc, char **argv)
{
  double start_time, end_time;
  start_time = get_time();
  int ret = 0;
  init_mpi(argc, argv);
  parse_args(argc, argv);

  rank_0_print("Merge Program\n");

#if 0
  comm = MPI_COMM_WORLD;
#endif

  ret = IDX_file_open(output_file_name);
  if (ret != 0)  terminate_with_error_msg("PIDX_file_create");

  maxh = strlen(bitSequence);

  fprintf(stderr, "Partition size :: and count %d %d %d :: %d %d %d\n", idx_count[0], idx_count[1], idx_count[2], idx_size[0], idx_size[1], idx_size[2]);
  fprintf(stderr, "bitstring %s maxh = %d\n", bitSequence, maxh);

  // shared_block_level is the level upto which the idx blocks are shared
  int shared_block_level = (int)log2(idx_count[0] * idx_count[1] * idx_count[2]) + bits_per_block + 1;
  if (shared_block_level >= maxh)
    shared_block_level = maxh;

  int shared_block_count = pow(2, shared_block_level - 1) / samples_per_block;
  fprintf(stderr, "Shared block level = %d Shared block count = %d\n", shared_block_level, shared_block_count);

  int level = 0;
  int ts = 0;

  // Iteration through all the timesteps
  for (ts = start_time_step; ts <= end_time_step; ts++)
  {
    // Iteration through all the shared blocks
    //for (level = 0; level < shared_block_level; level = level + 1)
    {
      int hz_index = (int)pow(2, level - 1);
      int file_no = hz_index / (blocks_per_file * samples_per_block);
      int file_count;
      char existing_file_name[PIDX_FILE_PATH_LENGTH];
      char new_file_name[PIDX_FILE_PATH_LENGTH];
      int ic = 0;
      if (level <= bits_per_block + log2(blocks_per_file) + 1)
        file_count = 1;
      else
        file_count = (int)pow(2, level - (bits_per_block + log2(blocks_per_file) + 1));

      // file_no is the index of the file that needs to be opened to read from all the partitions
      // they contain the shared blocks
      fprintf(stderr, "Opening file %d\n", file_no);

#if 1
      // iterate throuh all the files that contains the shared blocks
      // most likely this will be only the first file of all the partitions
      // so fc = 1
      int fc = 0;
      for (fc = file_no; fc < file_no + file_count; fc++)
      {
        // malloc for the header for the outpur blocks, i.e. the merged blocks
        uint32_t* write_binheader;
        int write_binheader_count;
        write_binheader_count = 10 + 10 * blocks_per_file * variable_count;
        int write_binheader_length = write_binheader_count * sizeof (*write_binheader);
        write_binheader = malloc(write_binheader_length);
        memset(write_binheader, 0, write_binheader_length);

        //iterate through all the variables/fields
        int var = 0;
        off_t var_offset = 0;
        for (var = 0; var < 1; var++)
        {
          unsigned char *write_data_buffer = malloc(samples_per_block * shared_block_count * bpv[var]/8);
          memset(write_data_buffer, 0, samples_per_block * shared_block_count * bpv[var]/8);
          //fprintf(stderr, "Write bufer size = %d [%d x %d x %d]\n", samples_per_block * shared_block_count * bpv[var]/8, (int)pow(2, bits_per_block), shared_block_count, bpv[var]/8);

          // shared block data
          // doube pointer (number o fpartitions x number of shared blocks)
          unsigned char **read_data_buffer = malloc(idx_count[0] * idx_count[1] * idx_count[2] * sizeof(*read_data_buffer));
          memset(read_data_buffer, 0, idx_count[0] * idx_count[1] * idx_count[2] * sizeof(*read_data_buffer));

          // shared block header info

          uint32_t** read_binheader = malloc(idx_count[0] * idx_count[1] * idx_count[2] * sizeof(*read_binheader));
          memset(read_binheader, 0, idx_count[0] * idx_count[1] * idx_count[2] * sizeof(*read_binheader));

          file_initialize_time_step(ts, output_file_name, output_file_template);
          generate_file_name(blocks_per_file, output_file_template, fc, new_file_name, PATH_MAX);
          //fprintf(stderr, "Merged blocks to be written in %s\n", new_file_name);

          // iterate through all the parttions
          for (ic = 0; ic < idx_count[0] * idx_count[1] * idx_count[2]; ic++)
          {
            char file_name_skeleton[PIDX_FILE_PATH_LENGTH];
            strncpy(file_name_skeleton, output_file_name, strlen(output_file_name) - 4);
            file_name_skeleton[strlen(output_file_name) - 4] = '\0';

            if (idx_count[0] != 1 || idx_count[1] != 1 || idx_count[2] != 1)
              sprintf(partition_file_name, "%s_%d.idx", file_name_skeleton, ic);
            else
              strcpy(partition_file_name, output_file_name);

            file_initialize_time_step(ts, partition_file_name, partition_file_template);
            generate_file_name(blocks_per_file, partition_file_template, fc, existing_file_name, PATH_MAX);

            int read_binheader_count;
            read_binheader_count = 10 + 10 * blocks_per_file * variable_count;
            read_binheader[ic] = (uint32_t*) malloc(sizeof (*read_binheader[ic])*(read_binheader_count));
            memset(read_binheader[ic], 0, sizeof (*(read_binheader[ic]))*(read_binheader_count));

            fprintf(stderr, "[%d] Partition File name %s\n", ic, existing_file_name);
            // file exists
            if ( access( partition_file_name, F_OK ) != -1 )
            {
              // contins data from the shared blocks
              read_data_buffer[ic] = malloc(samples_per_block * shared_block_count * bpv[var]/8);
              memset(read_data_buffer[ic], 0, samples_per_block * shared_block_count * bpv[var]/8);

              int fd;
              fd = open(existing_file_name, O_RDONLY | O_BINARY);
              if (fd < 0)
              {
                fprintf(stderr, "[File : %s] [Line : %d] open\n", __FILE__, __LINE__);
                continue;
                return 0;
              }

              // reads the header infor from binary file of the partitions
              ret = read(fd, read_binheader[ic], (sizeof (*(read_binheader[ic])) * read_binheader_count));
              if (ret < 0)
              {
                fprintf(stderr, "[File : %s] [Line : %d] read\n", __FILE__, __LINE__);
                return 0;
              }
              //assert(ret == (sizeof (*(read_binheader[ic])) * read_binheader_count));

              // copy the header from the partition file to the merged output file
              // do it only for first partition (this gets all info other than block offset nd count)
              if (ic == 0)
                memcpy(write_binheader, read_binheader[ic], 10 * sizeof (*write_binheader));

              int bpf = 0;
              size_t data_size = 0;
              off_t data_offset = 0;
              for (bpf = 0; bpf < shared_block_count; bpf++)
              {
                data_offset = ntohl(read_binheader[ic][(bpf + var * blocks_per_file)*10 + 12]);
                data_size = ntohl(read_binheader[ic][(bpf + var * blocks_per_file)*10 + 14]);
                fprintf(stderr, "[%s] [Partition %d Block %d Variable %d] --> Offset %d Count %d\n", partition_file_name, ic, bpf, var, (int)data_offset, (int)data_size);

                if (data_offset != 0 && data_size != 0)
                {
                  pread(fd, read_data_buffer[ic] + (bpf * samples_per_block * (bpv[var] / 8)), data_size, data_offset);

                  write_binheader[((bpf + var * blocks_per_file)*10 + 12)] = htonl(write_binheader_length + (bpf * data_size) + var * shared_block_count);
                  write_binheader[((bpf + var * blocks_per_file)*10 + 14)] = htonl(data_size);

                  // Merge happening while the shared block is being read
                  // Hardcoded stupid merge
                  // checks if value is not zero then copies to the write block
                  int m = 0;
                  for (m = 0; m < data_size / (bpv[var] / 8) ; m++)
                  {
                    double temp;
                    memcpy(&temp, read_data_buffer[ic] + (bpf * samples_per_block + m) * sizeof(double), sizeof(double));
                    if (temp != 0)
                      memcpy(write_data_buffer + ((bpf * samples_per_block) + m) * sizeof(double), &temp, sizeof(double));
                  }
                }
              }

              close(fd);
            }
            else
              continue;
          }

          //Merge after all the reads
          for (ic = 0; ic < idx_count[0] * idx_count[1] * idx_count[2]; ic++)
          {
            //input is read_data_buffer**
            //output is write_data_buffer*
          }

          if ( access( new_file_name, F_OK ) != -1 )
          {
            // file exists
            int fd;
            fd = open(new_file_name, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
            {
            }
            close(fd);
          }
          else
          {
            // file doesn't exist
            /*
            int r;
            for (r = 0; r < (shared_block_count * samples_per_block * bpv[var]/8) / sizeof(double); r++)
            {
              double dval;
              memcpy(&dval, write_data_buffer + r * sizeof(double), sizeof(double));
              fprintf(stderr, "value at %d = %f\n", r, dval);
            }
            */

            int fd;
            fd = open(new_file_name, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR);
            pwrite(fd, write_binheader, sizeof (*write_binheader)*(write_binheader_count), 0);
            pwrite(fd, write_data_buffer, shared_block_count * samples_per_block * bpv[var]/8, sizeof (*write_binheader)*(write_binheader_count));
            close(fd);
          }
        }
      }
      #endif
    }
  }


  shutdown_mpi();

  end_time = get_time();
  fprintf(stderr, "Total time taken = %f %f\n", end_time, start_time);

  return 0;
}
PD_flow_mrpt::PD_flow_mrpt(unsigned int cam_mode_config, unsigned int fps_config, unsigned int rows_config)
{     
    rows = rows_config;      //Maximum size of the coarse-to-fine scheme - Default 240 (QVGA)
    cols = rows*320/240;
    cam_mode = cam_mode_config;   // (1 - 640 x 480, 2 - 320 x 240), Default - 1
    ctf_levels = round(log2(rows/15)) + 1;
    fovh = M_PI*62.5f/180.f;
    fovv = M_PI*45.f/180.f;
	fps = fps_config;		//In Hz, Default - 30

	//Iterations of the primal-dual solver at each pyramid level.
	//Maximum value set to 100 at the finest level
	for (int i=5; i>=0; i--)
	{
		if (i >= ctf_levels - 1)
			num_max_iter[i] = 100;	
		else
			num_max_iter[i] = num_max_iter[i+1]-15;
	}

    //Compute gaussian mask
	float v_mask[5] = {1.f,4.f,6.f,4.f,1.f};
    for (unsigned int i=0; i<5; i++)
        for (unsigned int j=0; j<5; j++)
            g_mask[i+5*j] = v_mask[i]*v_mask[j]/256.f;

    //Matrices that store the original and filtered images with the image resolution
    colour_wf.setSize(480/cam_mode,640/cam_mode);
    depth_wf.setSize(480/cam_mode,640/cam_mode);

    //Resize vectors according to levels
    dx.resize(ctf_levels); dy.resize(ctf_levels); dz.resize(ctf_levels);

    const unsigned int width = colour_wf.getColCount();
    const unsigned int height = colour_wf.getRowCount();
    unsigned int s, cols_i, rows_i;

    for (unsigned int i = 0; i<ctf_levels; i++)
    {
        s = pow(2.f,int(ctf_levels-(i+1)));
        cols_i = cols/s; rows_i = rows/s;
        dx[ctf_levels-i-1].setSize(rows_i,cols_i);
        dy[ctf_levels-i-1].setSize(rows_i,cols_i);
        dz[ctf_levels-i-1].setSize(rows_i,cols_i);
    }

    //Resize pyramid
    const unsigned int pyr_levels = round(log2(width/cols)) + ctf_levels;
    colour.resize(pyr_levels);
    colour_old.resize(pyr_levels);
    depth.resize(pyr_levels);
    depth_old.resize(pyr_levels);
    xx.resize(pyr_levels);
    xx_old.resize(pyr_levels);
    yy.resize(pyr_levels);
    yy_old.resize(pyr_levels);

    for (unsigned int i = 0; i<pyr_levels; i++)
    {
        s = pow(2.f,int(i));
        colour[i].resize(height/s, width/s);
        colour_old[i].resize(height/s, width/s);
        colour[i].assign(0.0f);
        colour_old[i].assign(0.0f);
        depth[i].resize(height/s, width/s);
        depth_old[i].resize(height/s, width/s);
        depth[i].assign(0.0f);
        depth_old[i].assign(0.0f);
        xx[i].resize(height/s, width/s);
        xx_old[i].resize(height/s, width/s);
        xx[i].assign(0.0f);
        xx_old[i].assign(0.0f);
        yy[i].resize(height/s, width/s);
        yy_old[i].resize(height/s, width/s);
        yy[i].assign(0.0f);
        yy_old[i].assign(0.0f);
    }

    //Parameters of the variational method
    lambda_i = 0.04f;
    lambda_d = 0.35f;
    mu = 75.f;
}
Ejemplo n.º 25
0
void decoder(double *r,double*Y,double*S,double*N,int n,int Ysize,int ns,double *u_out)
{
    int i,j,k,z;
    int bb,u1,u2,s1,s2,s,bestJ,tblen;
    double gamma[ns][2],tempgamma[2],maxgamma[2] = {0,0};

    tblen = 5*log2(ns);

    int survivors[ns][tblen][2];

    for(z=0;z<ns;z++)
    {
        gamma[z][1] = gamma[z][0] = -10000;
    }

    gamma[0][0] = 0;

    for(i=0;i<n;i++)
    {
        for(j=0;j<ns;j++)
        {
            u1 = (int)N[j];
            s1 = (int)N[j+Ysize];

            u2 = (int)N[j+ns];
            s2 = (int)N[j+ns+Ysize];

            tempgamma[0] = gamma[s1][i%2];
            tempgamma[1] = gamma[s2][i%2];

            for(z=0;z<2;z++)
            {
                tempgamma[0] += r[z+(i<<1)]*M((int)Y[u1+(s1<<1)+(z*Ysize)]);
                tempgamma[1] += r[z+(i<<1)]*M((int)Y[u2+(s2<<1)+(z*Ysize)]);
            }

            bb = (tempgamma[0] > tempgamma[1]) ? 0 : 1;

            gamma[j][(i+1)%2] = tempgamma[bb] - maxgamma[i%2];
            survivors[j][i%tblen][0] = (int)N[j+ns*bb];
            survivors[j][i%tblen][1] = (int)N[j+ns*bb+Ysize];

            if(gamma[j][(i+1)%2] > maxgamma[i%2])
            {
                maxgamma[(i+1)%2] = gamma[j][(i+1)%2];
                bestJ = j;
            }
        }
        if(i>=tblen-1)
        {
            s = bestJ;
            for(z=0;z<tblen-1;z++)          /* Performance bottleneck*/
            {
                s = survivors[s][(i-z)%tblen][1];
            }
            u_out[i-tblen+1] = survivors[s][(i+1)%tblen][0];
        }
    }

    s = 0;
    i--;
    for(z=0;z<log2(ns);z++)
    {
        s = survivors[s][(i-z)%tblen][1];
    }
    for(z=log2(ns);z<tblen;z++)
    {
        u_out[i-z] = survivors[s][(i-z)%tblen][0];
        s = survivors[s][(i-z)%tblen][1];
    }
}
Ejemplo n.º 26
0
static QByteArray generateTrueTypeCMap(QFontEngine *fe)
{
    QByteArray cmap;
    const int glyphCount = fe->glyphCount();
    if (!glyphCount)
        return cmap;

    // cmap header
    APPEND(quint16, 0); // table version number
    APPEND(quint16, 1); // number of tables

    // encoding record
    APPEND(quint16, 3); // platform-id
    APPEND(quint16, 10); // encoding-id (ucs-4)
    const int cmapOffset = cmap.size() + sizeof(quint32);
    APPEND(quint32, cmapOffset); // offset to sub-table

    APPEND(quint16, 4); // subtable format
    const int cmapTableLengthOffset = cmap.size();
    APPEND(quint16, 0); // length in bytes, will fill in later
    APPEND(quint16, 0); // language field

    QList<CMapSegment> segments;
    CMapSegment currentSegment;
    currentSegment.start = 0xffff;
    currentSegment.end = 0;
    currentSegment.startGlyphIndex = 0;
    quint32 previousGlyphIndex = 0xfffffffe;
    bool inSegment = false;

    QGlyphLayoutArray<10> layout;
    for (uint uc = 0; uc < 0x10000; ++uc) {
        QChar ch(uc);
        int nglyphs = 10;

        bool validGlyph = fe->stringToCMap(&ch, 1, &layout, &nglyphs, /*flags*/ 0)
                          && nglyphs == 1 && layout.glyphs[0];

        // leaving a segment?
        if (inSegment && (!validGlyph || layout.glyphs[0] != previousGlyphIndex + 1)) {
            Q_ASSERT(currentSegment.start != 0xffff);
            // store the current segment
            currentSegment.end = uc - 1;
            segments.append(currentSegment);
            currentSegment.start = 0xffff;
            inSegment = false;
        }
        // entering a new segment?
        if (validGlyph && (!inSegment || layout.glyphs[0] != previousGlyphIndex + 1)) {
            currentSegment.start = uc;
            currentSegment.startGlyphIndex = layout.glyphs[0];
            inSegment = true;
        }

        if (validGlyph)
            previousGlyphIndex = layout.glyphs[0];
        else
            previousGlyphIndex = 0xfffffffe;
    }

    currentSegment.start = 0xffff;
    currentSegment.end = 0xffff;
    currentSegment.startGlyphIndex = 0;
    segments.append(currentSegment);

    if (QPF::debugVerbosity > 3)
        qDebug() << "segments:" << segments.count();

    Q_ASSERT(!inSegment);

    const quint16 entrySelector = int(log2(segments.count()));
    const quint16 searchRange = 2 * (1 << entrySelector);
    const quint16 rangeShift = segments.count() * 2 - searchRange;

    if (QPF::debugVerbosity > 3)
        qDebug() << "entrySelector" << entrySelector << "searchRange" << searchRange
                 << "rangeShift" << rangeShift;

    APPEND(quint16, segments.count() * 2); // segCountX2
    APPEND(quint16, searchRange);
    APPEND(quint16, entrySelector);
    APPEND(quint16, rangeShift);

    // end character codes
    for (int i = 0; i < segments.count(); ++i)
        APPEND(quint16, segments.at(i).end);

    APPEND(quint16, 0); // pad

    // start character codes
    for (int i = 0; i < segments.count(); ++i)
        APPEND(quint16, segments.at(i).start);

    // id deltas
    for (int i = 0; i < segments.count(); ++i)
        APPEND(quint16, segments.at(i).startGlyphIndex - segments.at(i).start);

    // id range offsets
    for (int i = 0; i < segments.count(); ++i)
        APPEND(quint16, 0);

    uchar *lengthPtr = reinterpret_cast<uchar *>(cmap.data()) + cmapTableLengthOffset;
    qToBigEndian<quint16>(cmap.size() - cmapOffset, lengthPtr);

    return cmap;
}
Ejemplo n.º 27
0
wchar_t EjectOSD::MaskToDriveLetter(DWORD mask) {
    return (wchar_t) (log2(mask) + 65);
}
Ejemplo n.º 28
0
bool arcan_verify_namespaces(bool report)
{
	bool working = true;

	if (report)
		arcan_warning("--- Verifying Namespaces: ---\n");

/* 1. check namespace mapping for holes */
	for (int i = 0; i < sizeof(
		namespaces.paths) / sizeof(namespaces.paths[0]); i++){
			if (namespaces.paths[i] == NULL){
				if (i != (int)log2(RESOURCE_SYS_LIBS)){
					working = false;
					if (report)
						arcan_warning("%s -- broken\n", lbls[i]);
					continue;
				}
			}

		if (report)
			arcan_warning("%s -- OK (%s)\n", lbls[i], namespaces.paths[i]);
	}

	if (report)
		arcan_warning("--- Namespace Verification Completed ---\n");

/* 2. missing; check permissions for each mounted space, i.e. we should be able
 * to write to state, we should be able to write to appl temporary etc.  also
 * check disk space for possible warning conditions (these should likely also
 * be emitted as system events)
 */

	if (working){
		char* toktmp = strdup(FRAMESERVER_MODESTRING);

/* modestring is static, atypestr can only be reduced in bytes used */
		if (!atypestr)
			atypestr = strdup(FRAMESERVER_MODESTRING);

		char* tokctx, (* tok) = strtok_r(toktmp, " ", &tokctx);
		if (tok && atypestr){
			char* base = arcan_expand_resource("", RESOURCE_SYS_BINS);
			size_t baselen = strlen(base);

/* fix for specialized "do we have default arcan_frameserver? then compact to
 * afsrv_ for archetype prefix" mode */
			size_t sfxlen = sizeof("arcan_frameserver") - 1;
			if (baselen >= sfxlen){
				if (strcmp(&base[baselen - sfxlen], "arcan_frameserver") == 0){
					const char* sfx = "afsrv";
					memcpy(&base[baselen - sfxlen], sfx, sizeof("afsrv"));
				}
			}

/* could / should do a more rigorous test of the corresponding afsrv, e.g.
 * executable, permission and linked shmif version */
			atypestr[0] = '\0';
			bool first = true;
			do{
				char* fn;
				char exp[2 + baselen + strlen(tok)];
				snprintf(exp, sizeof(exp), "%s_%s", base, tok);
				if (arcan_isfile(exp)){
					if (!first){
						strcat(atypestr, " ");
					}
					strcat(atypestr, tok);
					first = false;
				}
			} while ((tok = strtok_r(NULL, " ", &tokctx)));

			free(base);
		}
		free(toktmp);
	}

	return working;
}
Ejemplo n.º 29
0
/**
 * Transform the root list into a list of binonmial heaps.
 * It makes the amortized cost so good for a secuence of mixed insert() and deleteMin() calls.
 * Cost: O(log n)
 * Pre: this fib_heap has at least 1 element.
 * Post: list of binomial heaps
 **/
void fib_heap::consolidate()
{
	const int max_bin_heaps = 1.5 * (log2(n) + 1) ; //1.5*log n

	node_t* aux_array[max_bin_heaps];

	//Init array:
	for (int i = 0; i<max_bin_heaps; ++i) {
		aux_array[i] = nullptr;
	}

	node_t *aux1, *aux2;	//correspondence with MAR notes x <=> aux1 & y <=> aux2
	D(std::cerr << "Debug: consolidate loop starts" << std::endl);

	//We've gotta go over every node in the root list
	while (root_list != nullptr) {
		aux1 = root_list;

		remove_from_list(root_list,aux1);

		//Make aux1 an unitary circular list (link to itself only)
		aux1->right = aux1;
		aux1->left = aux1;

		//Inside this while, we make sure we are creating only one bin heap of every degree
		while (aux_array[aux1->degree] != nullptr) {
			D(std::cerr << "bin heap of degree " << aux1->degree << " already taken by " << aux_array[aux1->degree]->key << std::endl);
			D(std::cerr << "consolidate loop" << std::endl << std::endl);

			aux2 = aux_array[aux1->degree]; //Another node with the same degree as aux1

			//if aux1 is greater, it swaps them so that aux1 is always <= aux2
			if (aux1->key > aux2->key) {
				swap(aux1,aux2);
			}

			aux_array[aux1->degree] = nullptr;
			fib_heap_link(aux2,aux1);
		}
		aux_array[aux1->degree] = aux1;

	}

	//Now, we restore the heap and the min pointer
	for (int i = 0; i<max_bin_heaps; ++i) {
		node_t *x = aux_array[i];
		if (x != nullptr) {
			if (this->isEmpty()) {
				root_list = x;
			} else {
				concatenate_circular_lists(root_list,x);

				if (x->key < min->key)
					min = x;
			}
		}
	}

	D(std::cerr << "Debug: consolidate ok" << std::endl);
	D(std::cout << *this << std::endl);

}
Ejemplo n.º 30
0
void main() {
	vec3 outgoingLight = vec3( 0.0 );
	vec4 diffuseColor = vec4( diffuse, opacity );
	vec3 totalAmbientLight = vec3( 1.0 );
	vec3 shadowMask = vec3( 1.0 );
#if defined(USE_LOGDEPTHBUF) && defined(USE_LOGDEPTHBUF_EXT)

	gl_FragDepthEXT = log2(vFragDepth) * logDepthBufFC * 0.5;

#endif
#ifdef USE_MAP

	vec4 texelColor = texture2D( map, vUv );

	texelColor.xyz = inputToLinear( texelColor.xyz );

	diffuseColor *= texelColor;

#endif

#ifdef USE_COLOR

	diffuseColor.rgb *= vColor;

#endif
#ifdef USE_ALPHAMAP

	diffuseColor.a *= texture2D( alphaMap, vUv ).g;

#endif

#ifdef ALPHATEST

	if ( diffuseColor.a < ALPHATEST ) discard;

#endif

float specularStrength;

#ifdef USE_SPECULARMAP

	vec4 texelSpecular = texture2D( specularMap, vUv );
	specularStrength = texelSpecular.r;

#else

	specularStrength = 1.0;

#endif
#ifdef USE_AOMAP

	totalAmbientLight *= ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0;

#endif

#ifdef USE_SHADOWMAP

	for ( int i = 0; i < MAX_SHADOWS; i ++ ) {

		float texelSizeY =  1.0 / shadowMapSize[ i ].y;

		float shadow = 0.0;

#if defined( POINT_LIGHT_SHADOWS )

		bool isPointLight = shadowDarkness[ i ] < 0.0;

		if ( isPointLight ) {

			float realShadowDarkness = abs( shadowDarkness[ i ] );

			vec3 lightToPosition = vShadowCoord[ i ].xyz;

	#if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT )

			vec3 bd3D = normalize( lightToPosition );
			float dp = length( lightToPosition );

			adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D, texelSizeY ) ), shadowBias[ i ], shadow );


	#if defined( SHADOWMAP_TYPE_PCF )
			const float Dr = 1.25;
	#elif defined( SHADOWMAP_TYPE_PCF_SOFT )
			const float Dr = 2.25;
	#endif

			float os = Dr *  2.0 * texelSizeY;

			const vec3 Gsd = vec3( - 1, 0, 1 );

			adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + Gsd.zzz * os, texelSizeY ) ), shadowBias[ i ], shadow );
			adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + Gsd.zxz * os, texelSizeY ) ), shadowBias[ i ], shadow );
			adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + Gsd.xxz * os, texelSizeY ) ), shadowBias[ i ], shadow );
			adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + Gsd.xzz * os, texelSizeY ) ), shadowBias[ i ], shadow );
			adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + Gsd.zzx * os, texelSizeY ) ), shadowBias[ i ], shadow );
			adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + Gsd.zxx * os, texelSizeY ) ), shadowBias[ i ], shadow );
			adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + Gsd.xxx * os, texelSizeY ) ), shadowBias[ i ], shadow );
			adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + Gsd.xzx * os, texelSizeY ) ), shadowBias[ i ], shadow );
			adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + Gsd.zzy * os, texelSizeY ) ), shadowBias[ i ], shadow );
			adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + Gsd.zxy * os, texelSizeY ) ), shadowBias[ i ], shadow );

			adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + Gsd.xxy * os, texelSizeY ) ), shadowBias[ i ], shadow );
			adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + Gsd.xzy * os, texelSizeY ) ), shadowBias[ i ], shadow );
			adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + Gsd.zyz * os, texelSizeY ) ), shadowBias[ i ], shadow );
			adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + Gsd.xyz * os, texelSizeY ) ), shadowBias[ i ], shadow );
			adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + Gsd.zyx * os, texelSizeY ) ), shadowBias[ i ], shadow );
			adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + Gsd.xyx * os, texelSizeY ) ), shadowBias[ i ], shadow );
			adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + Gsd.yzz * os, texelSizeY ) ), shadowBias[ i ], shadow );
			adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + Gsd.yxz * os, texelSizeY ) ), shadowBias[ i ], shadow );
			adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + Gsd.yxx * os, texelSizeY ) ), shadowBias[ i ], shadow );
			adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + Gsd.yzx * os, texelSizeY ) ), shadowBias[ i ], shadow );

			shadow *= realShadowDarkness * ( 1.0 / 21.0 );

	#else 
			vec3 bd3D = normalize( lightToPosition );
			float dp = length( lightToPosition );

			adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D, texelSizeY ) ), shadowBias[ i ], shadow );

			shadow *= realShadowDarkness;

	#endif

		} else {

#endif 
			float texelSizeX =  1.0 / shadowMapSize[ i ].x;

			vec3 shadowCoord = vShadowCoord[ i ].xyz / vShadowCoord[ i ].w;


			bvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );
			bool inFrustum = all( inFrustumVec );

			bvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );

			bool frustumTest = all( frustumTestVec );

			if ( frustumTest ) {

	#if defined( SHADOWMAP_TYPE_PCF )


				/*
					for ( float y = -1.25; y <= 1.25; y += 1.25 )
						for ( float x = -1.25; x <= 1.25; x += 1.25 ) {
							vec4 rgbaDepth = texture2D( shadowMap[ i ], vec2( x * xPixelOffset, y * yPixelOffset ) + shadowCoord.xy );
							float fDepth = unpackDepth( rgbaDepth );
							if ( fDepth < shadowCoord.z )
								shadow += 1.0;
					}
					shadow /= 9.0;
				*/

				shadowCoord.z += shadowBias[ i ];

				const float ShadowDelta = 1.0 / 9.0;

				float xPixelOffset = texelSizeX;
				float yPixelOffset = texelSizeY;

				float dx0 = - 1.25 * xPixelOffset;
				float dy0 = - 1.25 * yPixelOffset;
				float dx1 = 1.25 * xPixelOffset;
				float dy1 = 1.25 * yPixelOffset;

				float fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy0 ) ) );
				if ( fDepth < shadowCoord.z ) shadow += ShadowDelta;

				fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy0 ) ) );
				if ( fDepth < shadowCoord.z ) shadow += ShadowDelta;

				fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy0 ) ) );
				if ( fDepth < shadowCoord.z ) shadow += ShadowDelta;

				fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, 0.0 ) ) );
				if ( fDepth < shadowCoord.z ) shadow += ShadowDelta;

				fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy ) );
				if ( fDepth < shadowCoord.z ) shadow += ShadowDelta;

				fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, 0.0 ) ) );
				if ( fDepth < shadowCoord.z ) shadow += ShadowDelta;

				fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy1 ) ) );
				if ( fDepth < shadowCoord.z ) shadow += ShadowDelta;

				fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy1 ) ) );
				if ( fDepth < shadowCoord.z ) shadow += ShadowDelta;

				fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy1 ) ) );
				if ( fDepth < shadowCoord.z ) shadow += ShadowDelta;

				shadow *= shadowDarkness[ i ];

	#elif defined( SHADOWMAP_TYPE_PCF_SOFT )


				shadowCoord.z += shadowBias[ i ];

				float xPixelOffset = texelSizeX;
				float yPixelOffset = texelSizeY;

				float dx0 = - 1.0 * xPixelOffset;
				float dy0 = - 1.0 * yPixelOffset;
				float dx1 = 1.0 * xPixelOffset;
				float dy1 = 1.0 * yPixelOffset;

				mat3 shadowKernel;
				mat3 depthKernel;

				depthKernel[ 0 ][ 0 ] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy0 ) ) );
				depthKernel[ 0 ][ 1 ] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, 0.0 ) ) );
				depthKernel[ 0 ][ 2 ] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy1 ) ) );
				depthKernel[ 1 ][ 0 ] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy0 ) ) );
				depthKernel[ 1 ][ 1 ] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy ) );
				depthKernel[ 1 ][ 2 ] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy1 ) ) );
				depthKernel[ 2 ][ 0 ] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy0 ) ) );
				depthKernel[ 2 ][ 1 ] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, 0.0 ) ) );
				depthKernel[ 2 ][ 2 ] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy1 ) ) );

				vec3 shadowZ = vec3( shadowCoord.z );
				shadowKernel[ 0 ] = vec3( lessThan( depthKernel[ 0 ], shadowZ ) );
				shadowKernel[ 0 ] *= vec3( 0.25 );

				shadowKernel[ 1 ] = vec3( lessThan( depthKernel[ 1 ], shadowZ ) );
				shadowKernel[ 1 ] *= vec3( 0.25 );

				shadowKernel[ 2 ] = vec3( lessThan( depthKernel[ 2 ], shadowZ ) );
				shadowKernel[ 2 ] *= vec3( 0.25 );

				vec2 fractionalCoord = 1.0 - fract( shadowCoord.xy * shadowMapSize[ i ].xy );

				shadowKernel[ 0 ] = mix( shadowKernel[ 1 ], shadowKernel[ 0 ], fractionalCoord.x );
				shadowKernel[ 1 ] = mix( shadowKernel[ 2 ], shadowKernel[ 1 ], fractionalCoord.x );

				vec4 shadowValues;
				shadowValues.x = mix( shadowKernel[ 0 ][ 1 ], shadowKernel[ 0 ][ 0 ], fractionalCoord.y );
				shadowValues.y = mix( shadowKernel[ 0 ][ 2 ], shadowKernel[ 0 ][ 1 ], fractionalCoord.y );
				shadowValues.z = mix( shadowKernel[ 1 ][ 1 ], shadowKernel[ 1 ][ 0 ], fractionalCoord.y );
				shadowValues.w = mix( shadowKernel[ 1 ][ 2 ], shadowKernel[ 1 ][ 1 ], fractionalCoord.y );

				shadow = dot( shadowValues, vec4( 1.0 ) ) * shadowDarkness[ i ];

	#else 
				shadowCoord.z += shadowBias[ i ];

				vec4 rgbaDepth = texture2D( shadowMap[ i ], shadowCoord.xy );
				float fDepth = unpackDepth( rgbaDepth );

				if ( fDepth < shadowCoord.z )
					shadow = shadowDarkness[ i ];

	#endif

			}

#ifdef SHADOWMAP_DEBUG

			if ( inFrustum ) {

				if ( i == 0 ) {

					outgoingLight *= vec3( 1.0, 0.5, 0.0 );

				} else if ( i == 1 ) {

					outgoingLight *= vec3( 0.0, 1.0, 0.8 );

				} else {

					outgoingLight *= vec3( 0.0, 0.5, 1.0 );

				}

			}

#endif

#if defined( POINT_LIGHT_SHADOWS )

		}

#endif

		shadowMask = shadowMask * vec3( 1.0 - shadow );

	}

#endif

	outgoingLight = diffuseColor.rgb * totalAmbientLight * shadowMask;
#ifdef USE_ENVMAP

	#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )

		vec3 cameraToVertex = normalize( vWorldPosition - cameraPosition );

		vec3 worldNormal = inverseTransformDirection( normal, viewMatrix );

		#ifdef ENVMAP_MODE_REFLECTION

			vec3 reflectVec = reflect( cameraToVertex, worldNormal );

		#else

			vec3 reflectVec = refract( cameraToVertex, worldNormal, refractionRatio );

		#endif

	#else

		vec3 reflectVec = vReflect;

	#endif

	#ifdef DOUBLE_SIDED
		float flipNormal = ( float( gl_FrontFacing ) * 2.0 - 1.0 );
	#else
		float flipNormal = 1.0;
	#endif

	#ifdef ENVMAP_TYPE_CUBE
		vec4 envColor = textureCube( envMap, flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );

	#elif defined( ENVMAP_TYPE_EQUIREC )
		vec2 sampleUV;
		sampleUV.y = saturate( flipNormal * reflectVec.y * 0.5 + 0.5 );
		sampleUV.x = atan( flipNormal * reflectVec.z, flipNormal * reflectVec.x ) * RECIPROCAL_PI2 + 0.5;
		vec4 envColor = texture2D( envMap, sampleUV );

	#elif defined( ENVMAP_TYPE_SPHERE )
		vec3 reflectView = flipNormal * normalize((viewMatrix * vec4( reflectVec, 0.0 )).xyz + vec3(0.0,0.0,1.0));
		vec4 envColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5 );
	#endif

	envColor.xyz = inputToLinear( envColor.xyz );

	#ifdef ENVMAP_BLENDING_MULTIPLY

		outgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );

	#elif defined( ENVMAP_BLENDING_MIX )

		outgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );

	#elif defined( ENVMAP_BLENDING_ADD )

		outgoingLight += envColor.xyz * specularStrength * reflectivity;

	#endif

#endif


	outgoingLight = linearToOutput( outgoingLight );

#ifdef USE_FOG

	#ifdef USE_LOGDEPTHBUF_EXT

		float depth = gl_FragDepthEXT / gl_FragCoord.w;

	#else

		float depth = gl_FragCoord.z / gl_FragCoord.w;

	#endif

	#ifdef FOG_EXP2

		float fogFactor = whiteCompliment( exp2( - fogDensity * fogDensity * depth * depth * LOG2 ) );

	#else

		float fogFactor = smoothstep( fogNear, fogFar, depth );

	#endif
	
	outgoingLight = mix( outgoingLight, fogColor, fogFactor );

#endif
	gl_FragColor = vec4( outgoingLight, diffuseColor.a );
}