Example #1
0
inline
void
adjustHeap(diagonalLine *L, int32 p, int32 n, uint32 qsLen) {
  uint32  q = L[p]._qsPos;
  uint32  d = L[p]._dsPos;
  uint32  l = qsLen - q - 1 + d;
  int32  c = (p << 1) + 1;  //  let c be the left child of p

  while (c < n) {

    //  Find the larger of the two children
    //
    if ((c+1 < n) && compareLines(L+c, L+c+1, qsLen))
      c++;

    //  Does the node in question fit here?
    //
    if (compareLines(l, q, L+c, qsLen) == false)
      break;

    //  Else, swap the parent and the child
    //
    L[p]._qsPos      = L[c]._qsPos;
    L[p]._dsPos      = L[c]._dsPos;

    //  Move down the tree
    //
    p = c;
    c = (p << 1) + 1;
  }

  L[p]._qsPos      = q;
  L[p]._dsPos      = d;
}
int IntersectionEventNode_compareData(IntersectionEventNode* node1,
                                      IntersectionEventNode* node2) {
  if (compareLines(node1->l1, node2->l1) < 0) {
    return -1;
  } else if (compareLines(node1->l1, node2->l1) == 0) {
    if (compareLines(node1->l2, node2->l2) < 0) {
      return -1;
    } else if (compareLines(node1->l2, node2->l2) == 0) {
      return 0;
    } else {
      return 1;
    }
  } else {
    return 1;
  }
}
QList<QLineF> Snapper::findSnappingLines(const SnapLineMap &snappingLineMap,
        Qt::Orientation orientation,
        double snapLine,
        double lowerLimit,
        double upperLimit,
        QList<QRectF> *boundingRects) const
{
    QList<QLineF> lineList;

    SnapLineMapIterator snappingLineIterator(snappingLineMap);
    while (snappingLineIterator.hasNext()) {
        snappingLineIterator.next();

        if (compareLines(snapLine, snappingLineIterator.key())) { // near distance snapping lines
            lineList += createSnapLine(orientation,
                                       snappingLineIterator.key(),
                                       lowerLimit,
                                       upperLimit,
                                       snappingLineIterator.value().first);
            if (boundingRects != 0)
                boundingRects->append(snappingLineIterator.value().first);
        }
    }

    return lineList;
}
inline void IntersectionEventList_appendNode(
    IntersectionEventList* intersectionEventList, Line* l1, Line* l2,
    IntersectionType intersectionType) {
  assert(compareLines(l1, l2) < 0);

  IntersectionEventNode* newNode = malloc(sizeof(IntersectionEventNode));
  if (newNode == NULL) {
    return;
  }

  newNode->l1 = l1;
  newNode->l2 = l2;
  newNode->intersectionType = intersectionType;
  newNode->next = NULL;
  if (intersectionEventList->head == NULL) {
    intersectionEventList->head = newNode;
  } else {
    intersectionEventList->tail->next = newNode;
  }
  intersectionEventList->tail = newNode;
  intersectionEventList->count++;
}
Example #5
0
bool compareBlocks(HWND view1, HWND view2, const UserSettings& settings, diff_info& blockDiff1, diff_info& blockDiff2)
{
	diff_info* pBlockDiff1 = &blockDiff1;
	diff_info* pBlockDiff2 = &blockDiff2;

	if (blockDiff1.len > blockDiff2.len)
	{
		std::swap(view1, view2);
		std::swap(pBlockDiff1, pBlockDiff2);
	}

	chunk_info chunk1(pBlockDiff1->off, pBlockDiff1->len);
	chunk_info chunk2(pBlockDiff2->off, pBlockDiff2->len);

	getWords(view1, settings, chunk1);
	getWords(view2, settings, chunk2);

	// Compare the two chunks
	const std::vector<diff_info> chunkDiff = DiffCalc<Word>(chunk1.words, chunk2.words)();

	const int chunkDiffSize = static_cast<int>(chunkDiff.size());

	if (chunkDiffSize == 0)
		return false;

	std::vector<std::vector<int>> linesConvergence(chunk1.lineCount, std::vector<int>(chunk2.lineCount, 0));

	// Use the MATCH results to synchronize line numbers (count the match length of each line)
	int wordOffset = 0;
	for (int i = 0; i < chunkDiffSize; ++i)
	{
		const diff_info& cd = chunkDiff[i];

		if (cd.type == diff_type::DIFF_DELETE)
		{
			wordOffset -= cd.len;
		}
		else if (cd.type == diff_type::DIFF_INSERT)
		{
			wordOffset += cd.len;
		}
		else // diff_type::DIFF_MATCH
		{
			for (int wordIdx = cd.off; wordIdx < (cd.off + cd.len); ++wordIdx)
			{
				const Word& word1 = chunk1.words[wordIdx];
				const Word& word2 = chunk2.words[wordIdx + wordOffset];

				if (word1.type != charType::SPACECHAR)
					linesConvergence[word1.line][word2.line] += word1.length;
			}
		}
	}

	// Select the line with the most matches (as length)
	for (int line1 = 0; line1 < chunk1.lineCount; ++line1)
	{
		if (pBlockDiff1->isMoved(line1))
			continue;

		int maxConvergence = 0;
		int line2 = 0;

		for (int i = 0; i < chunk2.lineCount; ++i)
		{
			if (!pBlockDiff2->isMoved(i) && linesConvergence[line1][i] > maxConvergence)
			{
				line2 = i;
				maxConvergence = linesConvergence[line1][i];
			}
		}

		// Make sure that the line is matched and the other line is not already matched
		if (maxConvergence == 0 || chunk2.lineMappings[line2] != -1)
			continue;

		int line1Size = 0;
		for (int i = chunk1.lineStartWordIdx[line1]; i < chunk1.lineEndWordIdx[line1]; ++i)
		{
			const Word& word1 = chunk1.words[i];

			if (word1.type != charType::SPACECHAR)
				line1Size += word1.length;
		}

		// Is enough portion of the line matched to be significant?
		if (line1Size && maxConvergence > (line1Size / 3))
		{
			chunk1.lineMappings[line1] = line2;
			chunk2.lineMappings[line2] = line1;
		}
	}

	compareLines(*pBlockDiff1, *pBlockDiff2, chunk1, chunk2);

	return true;
}
int main(int argc, char **argv)
{
    bool nufftMode = false;
    
	int arg;
	while ((arg = getopt(argc, argv, "nh")) != -1) {
		switch (arg) {
            case 'n':
                nufftMode = true;
                break;
			default:
			case 'h':
				usage(argv);
		}
	}

	unsigned numFiles = argc - optind;
	if(numFiles < 2) {
		usage(argv);
	}
	
    if(nufftMode && (numFiles != 2)) {
        printf("***NUFFT mode requires two input files.\n");
        exit(1);
    }
    
	/* open TextParsers for each input file */
	char *fileName[numFiles];
	TextParser *parser[numFiles];
	for(unsigned dex=0; dex<numFiles; dex++) {
		fileName[dex] = argv[optind + dex];
		parser[dex] = new TextParser(fileName[dex]);
	}
	
	/*
	 * The header of all outputs looks like this:
	 *
	 * Library     : MatrixFFT
	 * FFT type    : Two-dimension complex
	 * Precision   : Single
	 * Signal type : Chirp
	 * Loops       : 10
	 * Threads     : 8
	 * Options     : Don't time first loop, In-place
	 * System      : Version 10.6 (Build 10A110)
	 * CPU         : Intel(R) Xeon(R) CPU X5482 @ 3.20GHz
	 * Built as    : 64 bit
	 * Complex     : Interleaved
	 * Test time   : 14:02:29  Oct 6 2008
	 *
	 * "Loops", "Threads", and "Options" lines are optional. 
	 * Do basic validation by getting "Library Type" for each file.
	 */
	char libType[numFiles][LINE_LENGTH_MAX];
	for(unsigned dex=0; dex<numFiles; dex++) {
		if(fineLineWithTitle(*parser[dex], "Library", libType[dex])) {
			printf("***%s is not an FFT output file\n", fileName[dex]);
			exit(1);
		}
	}
	
	/* 
	 * Make sure precisions, FFT types, and signal types match; 
	 * log them as well as log test time for the first file.
	 */
	char lineBuf[LINE_LENGTH_MAX];
	bool match;
	for(unsigned dex=1; dex<numFiles; dex++) {
		if(compareLines(*parser[0], *parser[dex], "FFT type", match, lineBuf)) {
			printf("***No FFT type line found\n");
			exit(1);
		}
		if(!match) {
			printf("***%s and %s measure different FFT types\n", fileName[0], fileName[dex]);
			exit(1);
		}
	}
	printf("%s\n", lineBuf);
	
	bool isConvolve = false;
	if(strstr(lineBuf, "Convolve")) {
		isConvolve = true;
	}
	
	for(unsigned dex=1; dex<numFiles; dex++) {
		if(compareLines(*parser[0], *parser[dex], "Precision", match, lineBuf)) {
			printf("***No Precision line found\n");
			exit(1);
		}
		if(!match) {
			printf("***%s and %s measure different Precision\n", fileName[0], fileName[dex]);
			exit(1);
		}
	}
	printf("%s\n", lineBuf);

	for(unsigned dex=1; dex<numFiles; dex++) {
		if(compareLines(*parser[0], *parser[dex], "Signal type", match, lineBuf)) {
			printf("***No Signal type line found\n");
			exit(1);
		}
		if(!match) {
			printf("***%s and %s measure different Signal types\n", fileName[0], fileName[dex]);
			exit(1);
		}
	}
	printf("%s\n", lineBuf);

	/* Optional "Threads" line - print it */
	if(parser[0]->findLine("Threads", lineBuf)) {
		printf("%s\n", lineBuf);
	}
	
	/* and rewind this one in any case; we may be past the Test time line */
	parser[0]->setCursor(0);
	
	/* 
	 * print following required fields:
	 *    system version (S/W)
	 *    CPU
	 *    Built as (32/64 bit)
	 *    Complex format
	 *    Test time 
	 *
	 * NOTE: the Complex Format line anly applies to MatrixFFT; we generally
	 * reuse data from one run of FFTW and vDSP for both Split and Interleaved
	 * format MFFT builds. So, the MFFT file really needs to be specified
	 * first to get the correct COmplex format in the collated output. 
	 */
	if(!parser[0]->findLine("System", lineBuf)) {
		printf("***No System found\n");
		exit(1);
	}
	printf("%s\n", lineBuf);
	if(!parser[0]->findLine("CPU", lineBuf)) {
		printf("***No CPU found\n");
		exit(1);
	}
	printf("%s\n", lineBuf);
	if(!parser[0]->findLine("Built as", lineBuf)) {
		printf("***No Built as found\n");
		exit(1);
	}
	printf("%s\n", lineBuf);
	if(!parser[0]->findLine("Complex", lineBuf)) {
		printf("***No Complex found\n");
		exit(1);
	}
	printf("%s\n", lineBuf);
	if(!parser[0]->findLine("Test time", lineBuf)) {
		printf("***No Test Time found\n");
		exit(1);
	}
	printf("%s\n\n", lineBuf);
	
	/* 
	 * The output we're parsing looks like this 2-D:
	 *
     *     Width  | Height |   Samples  | Wall time (s) |  CTGs 
     * -----------+--------+------------+---------------+---------
     *       1024 |   1024 |    1048576 |   0.606012    | 3.46058
	 *		   ...
	 *
	 * And for 1-D:
	 *
	 *     Samples | Wall time (s) |   CTGs 
	 *  -----------+---------------+--------
     *        1024 |   0.000013    | 3.86415
	 *
	 * For convolve:
	 *
	 *  Image Rows | Image Cols | Kernel size | Convolution time (s)
     *  -----------+------------+-------------+---------------------
     *
     * For NUFFT:
     *
     *   Samples | Wall time (s) | ms/loop 
     *  ---------+---------------+----------
     *      2^5  |     0.002     |  0.16
     * 
     *      1000   |     1000   |        3    |    0.07004
	 *
	 * So, we generally use the column header line to figure out what kind of output we're 
	 * dealing with.
	 */
	if(!isConvolve && !nufftMode) {
		if(!parser[0]->findLine("Samples", lineBuf)) {
			printf("***Malformed input file (no Samples line)\n");
			exit(1);
		}
	}
	
	unsigned totalTokens = 0;		/* expected tokens per line */
	unsigned ctgToken = 0;			/* index of CTGs/time token */
	unsigned matchTokens = 0;		/* % of tokens that must match exactly */
	bool is2Dim = false;
	
	const char **tokens = NULL;
	unsigned numTokens = parser[0]->parseLine(lineBuf, tokens);
	char *numStrings[3] = {NULL, NULL, NULL};
	
	if(isConvolve) {
		is2Dim = true;
		totalTokens = 7;
		ctgToken = 6;
		matchTokens = 6;
	}
    else if(nufftMode) {
        is2Dim = false;
        totalTokens = 5;
        matchTokens = 2;
        ctgToken = 4;       // not CTGs, but ms/loop, and we print it as a string 
    }
	else {
		switch(numTokens) {
			case 7:
				/* 1-dim */
				is2Dim = false;
				totalTokens = 5;
				ctgToken = 4;
				matchTokens = 2;
				break;
			case 11:
				/* 2-dim */
				is2Dim = true;
				totalTokens = 9;
				ctgToken = 8;
				matchTokens = 6;
				break;
			default:
				printf("***Malformed input file (3)\n");
				exit(1);
		}
	}
	parser[0]->freeTokens(numTokens, tokens);
	
	/* Skip ahead to first actual data in all files */
	for(unsigned dex=0; dex<numFiles; dex++) {
		if(!parser[dex]->findLine("-----------+", lineBuf)) {
			printf("***Malformed input file %s (1)\n", fileName[dex]);
			exit(1);
		}
	}
	
	if(isConvolve) {
		printf(" Image Rows | Image Cols | Kernel size ");
		for(unsigned dex=0; dex<numFiles; dex++) {
			printf("| %6s time (s) ", libType[dex]);
		}
		printf("\n");
		printf(" -----------+------------+-------------");
		for(unsigned dex=0; dex<numFiles; dex++) {
			printf("+-----------------");
		}
		printf("\n");
	}
    else if(nufftMode) {
        printf("             reference    optimized\n");
        printf("  Samples |   ms/loop   |  ms/loop    ratio\n");
        printf(" ---------+-------------+-----------+--------\n");
    }
	else if(is2Dim) {
		printf("  Width | Height | Samples ");
		for(unsigned dex=0; dex<numFiles; dex++) {
			char *title = centerStr(libType[dex], "CTGs", 11);
			printf("|%s", title);
			free(title);
		}
		printf("\n");
		printf(" -------+--------+---------");
		for(unsigned dex=0; dex<numFiles; dex++) {
			printf("+-----------");
		}
		printf("\n");
	}
	else {
		printf("  Samples ");
		for(unsigned dex=0; dex<numFiles; dex++) {
			char *title = centerStr(libType[dex], "CTGs", 11);
			printf("|%s", title);
			free(title);
		}
		printf("\n");
		printf(" ---------");
		for(unsigned dex=0; dex<numFiles; dex++) {
			printf("+-----------");
		}
		printf("\n");
	}
	
	while(1) {
		unsigned numTokensArr[numFiles];
		const char **tokensArr[numFiles];

		/* We quit when any file runs out of data */
		bool outOfData = false;
		for(unsigned dex=0; dex<numFiles; dex++) {
			if(parser[dex]->getTokens(numTokensArr[dex], tokensArr[dex])) {
				/* no more data */
				outOfData = true;
				break;
			}
			if(numTokensArr[dex] == 0) {
				/* empty line */
				outOfData = true;
				break;
			}
		}
		if(outOfData) {
			break;
		}
		
		/* verify all files have the right number of tokens */
		for(unsigned dex=0; dex<numFiles; dex++) {
			if(numTokensArr[dex] != totalTokens) {
				printf("***Malformed input file %s (2)\n", fileName[dex]);
				exit(1);
			}
		}
		
		/* the first matchTokens tokens must match exactly */
		for(unsigned fileDex=1; fileDex<numFiles; fileDex++) {
			for(unsigned tokenDex=0; tokenDex<matchTokens; tokenDex++) {
				if(strcmp(tokensArr[0][tokenDex], tokensArr[fileDex][tokenDex])) {
					/* maybe they are numbers printed with different representations.. */
					size_t num1 = fftParseStringRep(tokensArr[0][tokenDex]);
					size_t num2 = fftParseStringRep(tokensArr[fileDex][tokenDex]);
					if((num1 != 0) && (num1 != num2)) {
						printf("***Mismatched input files\n");
						exit(1);
					}
				}
			}
		}
		
		if(isConvolve) {
			printf("   %6s   |   %6s   |  %6s     ", tokensArr[0][0], tokensArr[0][2], tokensArr[0][4]);
			for(unsigned dex=0; dex<numFiles; dex++) {
				printf("|  %10s     ", tokensArr[dex][ctgToken]);
			}
			printf("\n");
		}
        else if(nufftMode) {
            /*
             * Though we print the ms/loop values as uninterpreted strings, we have to parse
             * them into floats in order to calculate the ratio.
             */
            float f0 = strtof(tokensArr[0][ctgToken], NULL);
            float f1 = strtof(tokensArr[1][ctgToken], NULL);
            float ratio = f0 / f1;
            printf(" %6s   |  %8s   | %8s  | %5.1f\n", 
                tokensArr[0][0],
                tokensArr[0][ctgToken], tokensArr[1][ctgToken], ratio);
            
        }
		else {
			/* 
			 * Convert all numbers to canonical form, no matter how they appear in
			 * input files
			 */
			size_t n = fftParseStringRep(tokensArr[0][0]);
			numStrings[0] = fftStringRepPow2(n);
			if(is2Dim) {
				n = fftParseStringRep(tokensArr[0][2]);
				numStrings[1] = fftStringRepPow2(n);
				n = fftParseStringRep(tokensArr[0][4]);
				numStrings[2] = fftStringRepPow2(n);
			}
			if(is2Dim) {
				printf(" %-6s | %-6s |  %-6s ", numStrings[0], numStrings[1], numStrings[2]);
				for(unsigned dex=0; dex<numFiles; dex++) {
					printf("| %8s  ", tokensArr[dex][ctgToken]);
				}
				printf("\n");
			}
			else {
				printf("   %-6s ", numStrings[0]);
				for(unsigned dex=0; dex<numFiles; dex++) {
					printf("| %7s   ", tokensArr[dex][ctgToken]);
				}
				printf("\n");
			}
			free(numStrings[0]);
			if(is2Dim) {
				free(numStrings[1]);
				free(numStrings[2]);
			}
		}
		for(unsigned dex=0; dex<numFiles; dex++) {
			parser[dex]->freeTokens(numTokensArr[dex], tokensArr[dex]);
		}
	}
	printf("\n");
	
	/* clean up */
	for(unsigned dex=0; dex<numFiles; dex++) {
		delete parser[dex];
	}

	return 0;
}
// Detect if lines l1 and l2 will intersect between now and the next time step.
inline IntersectionType intersect(Line *l1, Line *l2, double time) {
  assert(compareLines(l1, l2) < 0);

  if (!rectanglesOverlap(l1, l2)) {
    return NO_INTERSECTION;
  }

  Vec p1 = {.x = l2->p3.x - l1->delta.x, .y = l2->p3.y - l1->delta.y};
  Vec p2 = {.x = l2->p4.x - l1->delta.x, .y = l2->p4.y - l1->delta.y};

  if (intersectLines(l1->p1, l1->p2, l2->p1, l2->p2)) {
    return ALREADY_INTERSECTED;
  }

  int num_line_intersections = 0;
  bool top_intersected = false;
  bool bot_intersected = false;

  if (intersectLines(l1->p1, l1->p2, p1, p2)) {
    num_line_intersections++;
  }
  if (intersectLines(l1->p1, l1->p2, p1, l2->p1)) {
    num_line_intersections++;
    top_intersected = true;
  }
  if (intersectLines(l1->p1, l1->p2, p2, l2->p2)) {
    num_line_intersections++;
    bot_intersected = true;
  }

  if (num_line_intersections == 2) {
    return L2_WITH_L1;
  }

  if (pointInParallelogram(l1->p1, l2->p1, l2->p2, p1, p2) &&
      pointInParallelogram(l1->p2, l2->p1, l2->p2, p1, p2)) {
    return L1_WITH_L2;
  }

  if (num_line_intersections == 0) {
    return NO_INTERSECTION;
  }

  Vec v1 = Vec_makeFromLine(*l1);
  Vec v2 = Vec_makeFromLine(*l2);

  double angle = Vec_angle(v1, v2);

  if ((top_intersected && angle < 0) ||
      (bot_intersected && angle > 0)) {
    return L2_WITH_L1;
  }

  return L1_WITH_L2;
}

// Check if a point is in the parallelogram.
inline bool pointInParallelogram(Vec point, Vec p1, Vec p2, Vec p3, Vec p4) {
  double d1 = direction(p1, p2, point);
  double d2 = direction(p3, p4, point);
  double d3 = direction(p1, p3, point);
  double d4 = direction(p2, p4, point);
  return d1 * d2 < 0 && d3 * d4 < 0;
}

// Check if two lines intersect.
inline bool intersectLines(Vec p1, Vec p2, Vec p3, Vec p4) {
  return side(p1, p2, p3) != side(p1, p2, p4) &&
         side(p3, p4, p1) != side(p3, p4, p2);
}

// Obtain the intersection point for two intersecting line segments.
inline Vec getIntersectionPoint(Vec p1, Vec p2, Vec p3, Vec p4) {
  double u;

  u = ((p4.x - p3.x) * (p1.y - p3.y) -
       (p4.y - p3.y) * (p1.x - p3.x)) /
      ((p4.y - p3.y) * (p2.x - p1.x) -
       (p4.x - p3.x) * (p2.y - p1.y));

  Vec p;
  p.x = p1.x + (p2.x - p1.x) * u;
  p.y = p1.y + (p2.y - p1.y) * u;

  return p;
}