static void spliceTest(CuTest *testCase, const char *input, const char *expected, uint64_t l, uint64_t r, int64_t **offs) { mafBlock_t *ib = maf_newMafBlockFromString(input, 3); mafBlock_t *eb = maf_newMafBlockFromString(expected, 3); bool cleanOffs = false; if (offs == NULL) { cleanOffs = true; offs = createOffsets(maf_mafBlock_getNumberOfSequences(ib)); } mafBlock_t *ob = spliceBlock(ib, l, r, offs); CuAssertTrue(testCase, mafBlocksAreEqual(eb, ob)); if ((l == 0) && (r == maf_mafBlock_getSequenceFieldLength(ib) - 1)) { CuAssertTrue(testCase, ib == ob); } // clean up if (cleanOffs) { destroyOffsets(offs, maf_mafBlock_getNumberOfSequences(ib)); } if (ib != ob) maf_destroyMafBlockList(ob); maf_destroyMafBlockList(ib); maf_destroyMafBlockList(eb); }
// function implementation int main(int argc, char * argv[]) { char t1[DLEN+1], t2[DLEN+1], t3[DLEN+1], t4[DLEN+1]; double s1, s2, s3, s4; int i = 0, j = 0; //clock_t start, stop; double start, stop; FILE * fp; int *o1, *o2, *o3, *o4, *answer; uint64_t val1[4], val2[4]; int fd[4], rc; attr[0].type = PERF_TYPE_HARDWARE; attr[0].config = PERF_COUNT_HW_CPU_CYCLES; /* generic PMU event*/ attr[0].disabled = 0; fd[0] = perf_event_open(&attr[0], getpid(), -1, -1, 0); if (fd[0] < 0) { perror("Opening performance counter"); } attr[1].type = PERF_TYPE_HARDWARE; attr[1].config = PERF_COUNT_HW_BRANCH_MISSES; /* generic PMU event*/ attr[1].disabled = 0; fd[1] = perf_event_open(&attr[1], getpid(), -1, -1, 0); if (fd[1] < 0) { perror("Opening performance counter"); } attr[2].type = PERF_TYPE_HARDWARE; attr[2].config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS; /* generic PMU event*/ attr[2].disabled = 0; fd[2] = perf_event_open(&attr[2], getpid(), -1, -1, 0); if (fd[2] < 0) { perror("Opening performance counter"); } attr[3].type = PERF_TYPE_HARDWARE; attr[3].config = PERF_COUNT_HW_INSTRUCTIONS; /* generic PMU event*/ attr[3].disabled = 0; fd[3] = perf_event_open(&attr[3], getpid(), -1, -1, 0); if (fd[3] < 0) { perror("Opening performance counter"); } // argument check if(argc != 5) { printf("argument error!\n"); return -1; } // selectivity s1 = atof(argv[1]); s2 = atof(argv[2]); s3 = atof(argv[3]); s4 = atof(argv[4]); // allocate memory for offset, answer storage o1 = malloc(sizeof(int)*LOOP); o2 = malloc(sizeof(int)*LOOP); o3 = malloc(sizeof(int)*LOOP); o4 = malloc(sizeof(int)*LOOP); answer = malloc(sizeof(int)*LOOP); // create random seed unsigned int iseed = (unsigned int)time(NULL); srand(iseed); // create data for each function (size = DLEN) createData(s1, t1); createData(s2, t2); createData(s3, t3); createData(s4, t4); // create offset data for all functions (size = LOOP) createOffsets(o1); createOffsets(o2); createOffsets(o3); createOffsets(o4); // start printf("Loop start!\n"); fflush(stdout); start = get_timestamp(0.0f); // Tell Linux to start counting events asm volatile ("nop;"); // pseudo-barrier rc = read(fd[0], &val1[0], sizeof(val1[0])); assert(rc); rc = read(fd[1], &val1[1], sizeof(val1[1])); assert(rc); rc = read(fd[2], &val1[2], sizeof(val1[2])); assert(rc); rc = read(fd[3], &val1[3], sizeof(val1[3])); assert(rc); asm volatile ("nop;"); // pseudo-barrier // actual branch code // you need to substitute this part for your own branch which you want to measure. for(i = 0; i < LOOP; i++) { if(t1[o1[i]] && (t2[o2[i]] && (t3[o3[i]] && t4[o4[i]]))) { answer[j++] = i; } } // Read the counter asm volatile("nop;"); // pseudo-barrier rc = read(fd[0], &val2[0], sizeof(val2[0])); assert(rc); rc = read(fd[1], &val2[1], sizeof(val2[1])); assert(rc); rc = read(fd[2], &val2[2], sizeof(val2[2])); assert(rc); rc = read(fd[3], &val2[3], sizeof(val2[3])); assert(rc); assert(rc); asm volatile ("nop;"); // pseudo-barrier // Close the counter close(fd[0]); close(fd[1]); close(fd[2]); close(fd[3]); stop = get_timestamp(start); printf("Loop stop!\n"); printf("Elapsed time: %.9lf seconds\n", stop); printf("CPU Cycles: %lu \n", val2[0] - val1[0]); printf("Instructions: %lu \n", val2[3] - val1[3]); printf("IPC: %lf\n", ((double)val2[3] - val1[3]) / (val2[0] - val1[0])); printf("Branch misses: %lu \n", val2[1] - val1[1]); printf("Branch instructions: %lu \n", val2[2] - val1[2]); printf("Branch mispred. rate: %lf%%\n", 100.0*((double)val2[1] - val1[1]) / (val2[2] - val1[2])); printf("\n"); printf("overall selectivity = %10.9f\n", (double)j / (double)LOOP); printf("theoretical selectivity = %10.9f\n", s1 * s2 * s3 * s4); // we need to use the answer just in case so that optimizer does not optimize too much. // i.e. optimizer might think that we don't need to calculate answers if we do not use them. fp = fopen("/dev/null", "w"); for(i = 0; i < j; i++) { fprintf(fp, "%d ", answer[i]); } fclose(fp); // free offset memory free(o1); free(o2); free(o3); free(o4); // free answer memory free(answer); return 0; }
mafBlock_t *processBlockForSplice(mafBlock_t *b, uint64_t blockNumber, const char *seq, uint64_t start, uint64_t stop, bool store) { // walks mafBlock_t b, returns a mafBlock_t (using the linked list feature) of all spliced out bits. // if store is true, will return a mafBlock_t linked list of all sub-blocks. If store is false, // will report each sub-block (maf_mafBlock_print()) as it comes in and immediatly destroy that block. /* printf("\n\nprocessBlockForSplice(block=%"PRIu64", seq=%s, start=%"PRIu64", stop=%"PRIu64")\n", blockNumber, seq, start, stop); maf_mafBlock_print(b); */ bool *targetColumns = NULL; uint64_t len = 0, sum = 0; mafBlock_t *head = NULL, *mb = NULL; sum = getTargetColumns(&targetColumns, &len, b, seq, start, stop); // printTargetColumns(targetColumns, len); int64_t **offsets = createOffsets(maf_mafBlock_getNumberOfSequences(b)); uint64_t l = 0, r = 0, ri = 0; uint64_t spliceNumber = 0; char *id = (char*) de_malloc(kMaxStringLength); while (l < len) { if (!targetColumns[l]) { // find the left most element ++l; r = l; continue; } while (targetColumns[r] && r < len) { // find the end of the right ++r; } // set ri equal to the index of the last element ri = r - 1; if (store) { // used in unit tests if (head == NULL) { head = spliceBlock(b, l, ri, offsets); mb = head; } else { if (mb != b) { // manipulated blocks should have this extra tag attached sprintf(id, " splice_id=%" PRIu64 "_%" PRIu64, blockNumber, spliceNumber); maf_mafBlock_appendToAlignmentBlock(mb, id); } maf_mafBlock_setNext(mb, spliceBlock(b, l, ri, offsets)); mb = maf_mafBlock_getNext(mb); ++spliceNumber; } } else { // used in production mb = spliceBlock(b, l, ri, offsets); if (mb != b) { sprintf(id, " splice_id=%" PRIu64 "_%" PRIu64, blockNumber, spliceNumber); maf_mafBlock_appendToAlignmentBlock(mb, id); } maf_mafBlock_print(mb); if (mb != b) { maf_destroyMafBlockList(mb); } ++spliceNumber; } l = r; if (l == len - 1) { break; } } // clean up free(id); free(targetColumns); destroyOffsets(offsets, maf_mafBlock_getNumberOfSequences(b)); return head; }
static void test_splice_0(CuTest *testCase) { int64_t **offs = NULL; // int testcount = 0; // test 0 // printf("test %d\n", testcount++); offs = createOffsets(3); /* for (uint64_t i = 0; i < 3; ++i) { */ /* printf("offs[%"PRIu64"][0] = %"PRIu64"\n", i, offs[i][0]); */ /* printf("offs[%"PRIu64"][1] = %"PRIu64"\n", i, offs[i][1]); */ /* } */ spliceTest(testCase, "a score=0\n" "s theTarget.chr0 0 13 + 158545518 gcagctgaaaaca\n" "s name.chr1 0 10 + 100 ATGT---ATGCCG\n" "s name2.chr1 0 10 + 100 ATGT---ATGCCG\n", "a score=0\n" "s theTarget.chr0 2 11 + 158545518 agctgaaaaca\n" "s name.chr1 2 8 + 100 GT---ATGCCG\n" "s name2.chr1 2 8 + 100 GT---ATGCCG\n", 2, 12, offs); /* printf("##########\n"); */ /* for (uint64_t i = 0; i < 3; ++i) { */ /* printf("offs[%"PRIu64"][0] = %"PRIu64"\n", i, offs[i][0]); */ /* printf("offs[%"PRIu64"][1] = %"PRIu64"\n", i, offs[i][1]); */ /* } */ CuAssertTrue(testCase, offs[0][0] == 12); // seq field coord CuAssertTrue(testCase, offs[0][1] == 12); // non-gap offset for (uint64_t i = 1; i < 3; ++i) { CuAssertTrue(testCase, offs[i][0] == 12); CuAssertTrue(testCase, offs[i][1] == 9); } destroyOffsets(offs, 3); // test 1 // printf("test %d\n", testcount++); spliceTest(testCase, "a score=0\n" "s theTarget.chr0 0 13 + 158545518 gcagctgaaaaca\n" "s name.chr1 0 10 + 100 ATGT---ATGCCG\n" "s name2.chr1 0 10 + 100 ATGT---ATGCCG\n", "a score=0\n" "s theTarget.chr0 4 9 + 158545518 ctgaaaaca\n" "s name.chr1 4 6 + 100 ---ATGCCG\n" "s name2.chr1 4 6 + 100 ---ATGCCG\n", 4, 12, NULL); // test 2 // printf("test %d\n", testcount++); spliceTest(testCase, "a score=0\n" "s theTarget.chr0 0 13 + 158545518 gcagctgaaaaca\n" "s name.chr1 0 3 + 100 ATG----------\n" "s name2.chr1 0 10 + 100 ATGT---ATGCCG\n", "a score=0\n" "s theTarget.chr0 4 9 + 158545518 ctgaaaaca\n" "s name2.chr1 4 6 + 100 ---ATGCCG\n", 4, 12, NULL); // test 3 // printf("test %d\n", testcount++); spliceTest(testCase, "a score=0\n" "s theTarget.chr0 0 13 + 158545518 gcagctgaaaaca\n" "s name.chr1 0 10 + 100 ATGG---ATGCCG\n" "s name2.chr1 0 10 + 100 ATGT---ATGCCG\n", "a score=0\n" "s theTarget.chr0 6 7 + 158545518 gaaaaca\n" "s name.chr1 4 6 + 100 -ATGCCG\n" "s name2.chr1 4 6 + 100 -ATGCCG\n", 6, 12, NULL); // test 4 // printf("test %d\n", testcount++); spliceTest(testCase, "a score=0\n" "s theTarget.chr0 0 13 + 158545518 gcagctgaaaaca\n" "s name.chr1 0 10 + 100 ATGG---ATGCCG\n" "s name2.chr1 0 10 + 100 ATGT---ATGCCG\n", "a score=0\n" "s theTarget.chr0 12 1 + 158545518 a\n" "s name.chr1 9 1 + 100 G\n" "s name2.chr1 9 1 + 100 G\n", 12, 12, NULL); // test 5 // printf("test %d\n", testcount++); spliceTest(testCase, "a score=0\n" "s theTarget.chr0 0 13 + 158545518 gcagctgaaaaca\n" "s name.chr1 0 10 + 100 ATGT---ATGCCG\n" "s name2.chr1 0 10 + 100 ATGT---ATGCCG\n", "a score=0\n" "s theTarget.chr0 0 13 + 158545518 gcagctgaaaaca\n" "s name.chr1 0 10 + 100 ATGT---ATGCCG\n" "s name2.chr1 0 10 + 100 ATGT---ATGCCG\n", 0, 12, NULL); // test 6 // printf("test %d\n", testcount++); spliceTest(testCase, "a score=0\n" "s theTarget.chr0 0 13 + 158545518 gcag--ctgaaaaca\n" "s name.chr1 0 15 + 100 ATGTATATTATGCCG\n" "s name2.chr1 0 15 + 100 ATGTATATAATGCCG\n", "a score=0\n" "s theTarget.chr0 0 4 + 158545518 gcag\n" "s name.chr1 0 4 + 100 ATGT\n" "s name2.chr1 0 4 + 100 ATGT\n", 0, 3, NULL); // test 7 // printf("test %d\n", testcount++); offs = createOffsets(3); spliceTest(testCase, "a score=0\n" "s theTarget.chr0 0 13 + 158545518 gcag--ctgaaaaca\n" "s name.chr1 0 15 + 100 ATGTATATTATGCCG\n" "s name2.chr1 0 15 + 100 ATGTATATAATGCCG\n", "a score=0\n" "s theTarget.chr0 4 9 + 158545518 --ctgaaaaca\n" "s name.chr1 4 11 + 100 ATATTATGCCG\n" "s name2.chr1 4 11 + 100 ATATAATGCCG\n", 4, 14, offs); CuAssertTrue(testCase, offs[0][0] == 14); // seq field coord CuAssertTrue(testCase, offs[0][1] == 12); // non-gap offset for (uint64_t i = 1; i < 3; ++i) { CuAssertTrue(testCase, offs[i][0] == 14); CuAssertTrue(testCase, offs[i][1] == 14); } destroyOffsets(offs, 3); // test 8 // printf("test %d\n", testcount++); spliceTest(testCase, "a score=0\n" "s theTarget.chr0 0 13 + 158545518 gcagctgaaaaca\n" "s name.chr1 0 13 + 100 ATGTATTATGCCG\n" "s name2.chr1 0 13 + 100 ATGTATAATGCCG\n", "a score=0\n" "s theTarget.chr0 5 6 + 158545518 tgaaaa\n" "s name.chr1 5 6 + 100 TTATGC\n" "s name2.chr1 5 6 + 100 TAATGC\n", 5, 10, NULL); // test 9 // printf("test %d\n", testcount++); offs = createOffsets(3); spliceTest(testCase, "a score=0\n" "s theTarget.chr0 0 13 + 158545518 gcagctgaaaaca\n" "s name.chr1 0 13 + 100 ATGTATTATGCCG\n" "s name2.chr1 0 13 + 100 ATGTATAATGCCG\n", "a score=0\n" "s theTarget.chr0 0 13 + 158545518 gcagctgaaaaca\n" "s name.chr1 0 13 + 100 ATGTATTATGCCG\n" "s name2.chr1 0 13 + 100 ATGTATAATGCCG\n", 0, 12, offs); for (uint64_t i = 0; i < 3; ++i) { // SPECIAL CASE! // since the block is passed back directly, since no splice is performed, // there is no update made to the offset array. This makes sense because // the array will not be used again. CuAssertTrue(testCase, offs[i][0] == 0); CuAssertTrue(testCase, offs[i][1] == -1); } destroyOffsets(offs, 3); }