/** * Check if the EVDEV supports EV_ABS or EV_REL.. */ gcc_pure static bool IsPointerDevice(int fd) { assert(fd >= 0); unsigned long features[BitsToInts<unsigned long>(std::max(EV_ABS, EV_REL))]; if (ioctl(fd, EVIOCGBIT(0, sizeof(features)), features) < 0) return false; return CheckBit(features, EV_ABS) || CheckBit(features, EV_REL); }
/// <summary> /// read the value of an individual pin. /// </summary> /// <param name="pin">1 - 16</param> /// <returns>0 = logic level low, 1 = logic level high</returns> bool ABElectronics_IOPi::ReadPin(byte pin) { pin = (byte)(pin - 1); if (pin >= 0 && pin < 8) { portaval = ReadI2CByte(GPIOA); return CheckBit(portaval, pin); } else if (pin >= 8 && pin < 16) { portbval = ReadI2CByte(GPIOB); return CheckBit(portbval, (byte)(pin - 8)); } else { // default } }
static int CompressAndCrosscheckClusterVis( int clusternum ) { int optimized = 0; byte compressed[MAX_MAP_LEAFS/8]; // // compress the bit string // byte *uncompressed = uncompressedvis + clusternum*leafbytes; for ( int i = 0; i < portalclusters; i++ ) { if ( i == clusternum ) continue; if ( CheckBit( uncompressed, i ) ) { byte *other = uncompressedvis + i*leafbytes; if ( !CheckBit( other, clusternum ) ) { ClearBit( uncompressed, i ); optimized++; } } } int numbytes = CompressVis( uncompressed, compressed ); byte *dest = vismap_p; vismap_p += numbytes; if (vismap_p > vismap_end) Error ("Vismap expansion overflow"); dvis->bitofs[clusternum][DVIS_PVS] = dest-vismap; memcpy( dest, compressed, numbytes ); // check vis data DecompressVis( vismap + dvis->bitofs[clusternum][DVIS_PVS], compressed ); return optimized; }
Bool CheckKmerInBloomFilter(BloomFilter* const bf, const Kmer word) { uint128_t last_hash = bf->seed; uint idx; uint128_t hash; for (idx = 0; idx < bf->num_hash_functions; idx++) { if (MurmurHash3_128((char*)&word, sizeof(Kmer), last_hash, &hash) == FALSE) { PrintThenDie("could not ascertain hash for kmer"); } if (CheckBit(bf->bs, hash % bf->num_bits) == 0) { return FALSE; } last_hash = hash; } return TRUE; }
/* =============== ClusterMerge Merges the portal visibility for a leaf =============== */ void ClusterMerge (int clusternum) { leaf_t *leaf; // byte portalvector[MAX_PORTALS/8]; byte portalvector[MAX_PORTALS/4]; // 4 because portal bytes is * 2 byte uncompressed[MAX_MAP_LEAFS/8]; int i, j; int numvis; portal_t *p; int pnum; // OR together all the portalvis bits memset (portalvector, 0, portalbytes); leaf = &leafs[clusternum]; for (i=0 ; i<leaf->numportals ; i++) { p = leaf->portals[i]; if (p->status != stat_done) Error ("portal not done %d %d %d\n", i, p, portals); for (j=0 ; j<portallongs ; j++) ((long *)portalvector)[j] |= ((long *)p->portalvis)[j]; pnum = p - portals; SetBit( portalvector, pnum ); } // convert portal bits to leaf bits numvis = LeafVectorFromPortalVector (portalvector, uncompressed); if ( CheckBit( uncompressed, clusternum ) ) Warning("WARNING: Cluster portals saw into cluster\n"); SetBit( uncompressed, clusternum ); numvis++; // count the leaf itself // save uncompressed for PHS calculation memcpy (uncompressedvis + clusternum*leafbytes, uncompressed, leafbytes); qprintf ("cluster %4i : %4i visible\n", clusternum, numvis); totalvis += numvis; }
/* ============== LeafVectorFromPortalVector ============== */ int LeafVectorFromPortalVector (byte *portalbits, byte *leafbits) { int i; portal_t *p; int c_leafs; memset (leafbits, 0, leafbytes); for (i=0 ; i<g_numportals*2 ; i++) { if ( CheckBit( portalbits, i ) ) { p = portals+i; SetBit( leafbits, p->leaf ); } } c_leafs = CountBits (leafbits, portalclusters); return c_leafs; }
void AddKmerToBloomFilter(BloomFilter* const bf, const Kmer word) { uint128_t last_hash = bf->seed; uint idx; uint128_t hash; Bool is_added = FALSE; for (idx = 0; idx < bf->num_hash_functions; idx++){ if (MurmurHash3_128((char*)&word, sizeof(Kmer), last_hash, &hash) == FALSE) { PrintThenDie("could not ascertain hash for kmer"); } if(SetBit(bf->bs, hash % bf->num_bits) == FALSE){ assert(CheckBit(bf->bs, hash % bf->num_bits) > 0); bf->num_set_bits += 1; is_added = TRUE; } last_hash = hash; } if (is_added == TRUE) { bf->num_entries_added += 1; } }
/*This implements the MC21 perfect matching*/ match_size_t FindPerfectMatch(Match_t *M,SparseGraph *G){ unsigned int match_size=0; assert(G && M); node_t n = G->order; node_t *colind=G->colind;colind--; node_t *rowptr=G->rowptr;rowptr--; node_t *m = M->m;m--; BitArray_t *col_marker = CreateBitArray(n); BitArray_t *matched_row = CreateBitArray(n); node_t *p = (node_t *) malloc(sizeof(node_t)*n);p--; node_t *m_inv = (node_t *) malloc(sizeof(node_t)*n);m_inv--; node_t i,j,k,i1,jend;node_t m_inv_prev;char aug_extend=0; match_size=0; for(i=1;i<=n;i++){ m_inv[i]=0; } for(j=1;j<=n;j++){ if(m[j]){ m_inv[m[j]]=j; match_size++; } } for(i=1;i<=n;i++){ /*Augmenting path at any unmatched node*/ if(m_inv[i]){ continue; } i1 = i; p[i1]=0; jend=0; ResetAllBits(col_marker); while(i1 && !jend){ for(k=0;k<(rowptr[i1+1]-rowptr[i1]);k++){ j = colind[rowptr[i1]+k]; if(!m[j]){ jend=j; break; } } if(jend){ /*Found an unmatched node*/ break; } aug_extend=0; for(k=0;k<(rowptr[i1+1]-rowptr[i1]) && !jend;k++){ j = colind[rowptr[i1]+k]; if(!CheckBit(col_marker,j) && m[j]){ p[m[j]]=i1; m_inv[m[j]]=j; SetBit(col_marker,j); i1 = m[j]; aug_extend = 1; break; } } if(!aug_extend){ /*Unable to find a unmarked matched node*/ i1 = p[i1]; } } if(i1){ /*Augmenting path is found so augment*/ j = jend; printf("Augmenting the path {"); while(i1){ m_inv_prev = m_inv[i1]; m[j] = i1; m_inv[i1] = j; printf("(%u,%u)",i1,j); j = m_inv_prev; i1 = p[i1]; } printf("}\n"); match_size++; printf("Match Size: %u\n",match_size); }else{ /*the matching is maximum*/ break; } } FreeBitArray(col_marker); FreeBitArray(matched_row); free(++m_inv); free(++p); printf("Done freeing\n"); return match_size; }
size_t WeightedMatching(RowStarts *rowptr,ColIndices *colind,ValueType *C, ValueType *C1,ValueType *dist,ValueType *u,ValueType *v,Indices *p, Indices *m_inv,Indices *m, Indices n,CompareFunction cmpFunc){ size_t i,j,i1,jend,k,m_inv_prev; size_t match_size=0; ValueType curr_shortest_path = (ValueType)0; ValueType curr_aug_path = GetMaxTypeValue<ValueType>(); ValueType dist1; Indices itrace; BitArray_t *col_marker = CreateBitArray(n); BitArray_t *heap_marker = CreateBitArray(n); C--;m--;C1--;dist--;u--;v--;p--;m_inv--; rowptr--;colind--; #if BINARY_HEAP Heap *bin_heap = NewBinaryHeap(cmpFunc,n,GetDistKeyID); ValueType *dist_ptr = NULL; #endif assert(C1 && dist && u && v && p); ComputeInitialExtremeMatch<ValueType,Indices>(u,v,C1,C,m,m_inv,colind,rowptr,n,dist); match_size=0; for(i=1;i<=n;i++){ if(m_inv[i]){ match_size++; continue; } /* *Aim is to find a value for jend such that the path *from i-->jend is the shortest */ i1 = i; p[i1] = 0; jend=0; itrace=i; ResetAllBits(col_marker); ResetAllBits(heap_marker); #if BINARY_HEAP bin_heap->n = 0; dist_base = (unsigned long)&(dist[1]); #endif curr_shortest_path=(ValueType)0; curr_aug_path=GetMaxTypeValue<ValueType>(); while(1){ for(k=rowptr[i1];k<rowptr[i1+1];k++){ j = colind[k]; if(CheckBit(col_marker,j)){ continue; } dist1 = curr_shortest_path + C1[k]; /*Prune any dist1's > curr_aug_path, since *all the costs>0 */ if(*((long long int *)&dist1) < *((long long int *)&curr_aug_path)){ if(!m[j]){ /*we need itrace because, the last i1 which *we explore may not actually give the shortest *augmenting path.*/ jend = j; itrace = i1; curr_aug_path = dist1; }else if(*((long long int *)&dist1) < *((long long int *)&(dist[j]))){ /*Update the dist*/ dist[j] = dist1; p[m[j]] = i1; #if SIMPLE_HEAP SetBit(heap_marker,j); #elif BINARY_HEAP if(CheckBit(heap_marker,j)){ DecreaseKey(bin_heap,j); }else{ InsertHeap(bin_heap,&(dist[j])); SetBit(heap_marker,j); } #endif } } } if(*((long long int *)&curr_aug_path) <= *((long long int *)&curr_shortest_path)){ break; } /*We now have a heap of matched cols, so pick the min*/ #ifdef SIMPLE_HEAP j = SimplePickMin(heap_marker,dist,n); if(j){ curr_shortest_path = dist[j]; UnsetBit(heap_marker,j); #elif BINARY_HEAP dist_ptr = (ValueType *) HeapDelete(bin_heap); if(dist_ptr){ assert((unsigned long)dist_ptr >= (unsigned long)&dist[1]); j = ((((unsigned long)dist_ptr - (unsigned long)&dist[1]))/sizeof(double))+1; assert(j>=1 && j<=n); curr_shortest_path = dist[j]; UnsetBit(heap_marker,j); #endif SetBit(col_marker,j); i1 = m[j]; }else{ break; } } if(jend){ /*We found a shortest augmenting path*/ j=jend; node_t itrace_prev; //printf("Shortest augmenting Path {"); while(itrace){ m_inv_prev = m_inv[itrace]; m[j] = itrace; m_inv[itrace]=j; //printf("(%u,%u)",itrace,j); j=m_inv_prev; itrace_prev = itrace; itrace = p[itrace]; if(itrace){ // printf("(%u,%u)",itrace_prev,m_inv_prev); } } match_size++; //printf("}\n"); /*Update the cost with new match m*/ for(j=1;j<=n;j++){ if(CheckBit(col_marker,j)){ u[j] = (u[j]+dist[j])-curr_aug_path; /*Reset the dist values*/ } } for(i1=1;i1<=n;i1++){ if(!m_inv[i1]) continue; j = m_inv[i1]; for(k=rowptr[i1];k<rowptr[i1+1];k++){ if(colind[k] == j){ v[i1] = C[k] - u[j]; } } } /*Update the cost*/ for(i1=1;i1<=n;i1++){ for(k=rowptr[i1];k<rowptr[i1+1];k++){ j = colind[k]; C1[k] = C[k]-(u[j]+v[i1]); } /*The index should be j rather than i1 but just *avoiding another loop*/ dist[i1] = GetMaxTypeValue<double>(); } } } FreeBitArray(col_marker); FreeBitArray(heap_marker); #ifdef BINARY_HEAP FreeHeap(bin_heap); #endif return match_size; } /*O(n) time picking the maximum from the heap_marker */ node_t SimplePickMin(BitArray_t *bit_heap,double *dist,node_t n){ node_t min_j=0;node_t j; double curr_min = MAX_DOUBLE_VALUE; for(j=1;j<=n;j++){ if(CheckBit(bit_heap,j) && dist[j] < curr_min){ min_j = j; curr_min = dist[j]; } } return min_j; }
void NvCheckForErrors(void) { UINT32 val=PMC_Read(INTR_0); /* Has an interrupt been raised ???? */ /*if(val==0) return;*/ /* Info("An Interrupt has been raised.\n");*/ CheckBit(val,PMC,INTR_0_PAUDIO); CheckBit(val,PMC,INTR_0_PDMA); CheckBit(val,PMC,INTR_0_PFIFO); CheckBit(val,PMC,INTR_0_PGRAPH); CheckBit(val,PMC,INTR_0_PRM); CheckBit(val,PMC,INTR_0_PTIMER); CheckBit(val,PMC,INTR_0_PFB); CheckBit(val,PMC,INTR_0_SOFTWARE); val=PGRAPH_Read(INTR_0); CheckBit(val,PGRAPH,INTR_0_RESERVED); CheckBit(val,PGRAPH,INTR_0_CONTEXT_SWITCH); /* CheckBit(val,PGRAPH,INTR_0_VBLANK);*/ CheckBit(val,PGRAPH,INTR_0_RANGE); CheckBit(val,PGRAPH,INTR_0_METHOD_COUNT); CheckBit(val,PGRAPH,INTR_0_SOFTWARE); CheckBit(val,PGRAPH,INTR_0_COMPLEX_CLIP); CheckBit(val,PGRAPH,INTR_0_NOTIFY); val=PFIFO_Read(INTR_0); CheckBit(val,PFIFO,INTR_0_CACHE_ERROR); CheckBit(val,PFIFO,INTR_0_RUNOUT); CheckBit(val,PFIFO,INTR_0_RUNOUT_OVERFLOW); }
//2 utf8 dom //1 utf8 //0 not utf8 int IsUtf8(char* buf,int size) { int i; int u8 = 0; int u8len = 0; int firstbyte = 0; const char BOM[3] = {0xef,0xbb,0xbf}; if(size == 0) { return 0; } if(size >= 3 && strncmp(buf,BOM,3) == 0) { return 2; } for(i=0;i<size;i++) { //should be binrary file. if(buf[i] == 0) { return 0; } if(firstbyte == 0) { //pure ascii if((buf[i]&0xff) <= 127) { u8 = 0; u8len = 0; } //unknow char else if((buf[i]&0xff) > 0xef) { u8 = 0; u8len = 0; } else { firstbyte = 1; //111***** if(CheckBit(buf[i],7) == 1 && CheckBit(buf[i],6) == 1) { u8 = 1; u8len++; } else { i++; firstbyte = 0; u8 = 0; u8len = 0; } } } else { if((buf[i]&0xff) <= 127 || (buf[i]&0xff) > 0xef) { firstbyte = 0; if(u8 == 1 && u8len % 3 != 0) { u8 = 0; } else if(u8 == 1 && u8len % 3 == 0) { //so we mark it utf8 break; } } else { u8len++; } } } //check tail loop if(u8 == 1 && u8len % 3 != 0) { u8 = 0; } return u8; }
//----------------------------------------------------------------------------- // Using the PVS, compute the visible fog volumes from each leaf //----------------------------------------------------------------------------- static void CalcVisibleFogVolumes() { byte uncompressed[MAX_MAP_LEAFS/8]; int i, j, k; // Clear the contents flags for water testing for (i = 0; i < numleafs; ++i) { dleafs[i].contents &= ~CONTENTS_TESTFOGVOLUME; g_LeafMinDistToWater[i] = 65535; } for (i = 0; i < numleafs; ++i) { // If we've already discovered that this leaf needs testing, // no need to go through the work again... if (dleafs[i].contents & CONTENTS_TESTFOGVOLUME) { Assert((dleafs[i].contents & (CONTENTS_SLIME | CONTENTS_WATER)) == 0); continue; } // Don't bother checking fog volumes from solid leaves if (dleafs[i].contents & CONTENTS_SOLID) continue; // Look only for leaves which are visible from leaves that have fluid in them. if ( dleafs[i].leafWaterDataID == -1 ) continue; // Don't bother about looking from CONTENTS_SLIME; we're not going to treat that as interesting. // because slime is opaque if ( dleafs[i].contents & CONTENTS_SLIME ) continue; // First get the vis data.. int cluster = dleafs[i].cluster; if (cluster < 0) continue; DecompressVis( &dvisdata[dvis->bitofs[cluster][DVIS_PVS]], uncompressed ); // Iterate over all potentially visible clusters from this leaf for (j = 0; j < dvis->numclusters; ++j) { // Don't need to bother if this is the same as the current cluster if (j == cluster) continue; if ( !CheckBit( uncompressed, j ) ) continue; // Found a visible cluster, now iterate over all leaves // inside that cluster for (k = 0; k < g_ClusterLeaves[j].leafCount; ++k) { int nClusterLeaf = g_ClusterLeaves[j].leafs[k]; // Don't bother checking fog volumes from solid leaves if ( dleafs[nClusterLeaf].contents & CONTENTS_SOLID ) continue; // Don't bother checking from any leaf that's got fluid in it if ( dleafs[nClusterLeaf].leafWaterDataID != -1 ) continue; // Here, we've found a case where a non-liquid leaf is visible from a liquid leaf // So, in this case, we have to do the expensive test during rendering. dleafs[nClusterLeaf].contents |= CONTENTS_TESTFOGVOLUME; } } } }
static float CalcDistanceFromLeafToWater( int leafNum ) { byte uncompressed[MAX_MAP_LEAFS/8]; int j, k; // If we know that this one doesn't see a water surface then don't bother doing anything. if( ((dleafs[leafNum].contents & CONTENTS_TESTFOGVOLUME) == 0) && ( dleafs[leafNum].leafWaterDataID == -1 ) ) return 65535; // FIXME: make a define for this. // First get the vis data.. int cluster = dleafs[leafNum].cluster; if (cluster < 0) return 65535; // FIXME: make a define for this. DecompressVis( &dvisdata[dvis->bitofs[cluster][DVIS_PVS]], uncompressed ); float minDist = 65535.0f; // FIXME: make a define for this. Vector leafMin, leafMax; leafMin[0] = ( float )dleafs[leafNum].mins[0]; leafMin[1] = ( float )dleafs[leafNum].mins[1]; leafMin[2] = ( float )dleafs[leafNum].mins[2]; leafMax[0] = ( float )dleafs[leafNum].maxs[0]; leafMax[1] = ( float )dleafs[leafNum].maxs[1]; leafMax[2] = ( float )dleafs[leafNum].maxs[2]; /* CUtlVector<listplane_t> temp; // build a convex solid out of the planes so that we can get at the triangles. for( j = dleafs[i].firstleafbrush; j < dleafs[i].firstleafbrush + dleafs[i].numleafbrushes; j++ ) { dbrush_t *pBrush = &dbrushes[j]; for( k = pBrush->firstside; k < pBrush->firstside + pBrush->numsides; k++ ) { dbrushside_t *pside = dbrushsides + k; dplane_t *pplane = dplanes + pside->planenum; AddListPlane( &temp, pplane->normal[0], pplane->normal[1], pplane->normal[2], pplane->dist ); } CPhysConvex *pConvex = physcollision->ConvexFromPlanes( (float *)temp.Base(), temp.Count(), VPHYSICS_MERGE ); ConvertConvexToCollide( &pConvex, temp.RemoveAll(); } */ // Iterate over all potentially visible clusters from this leaf for (j = 0; j < dvis->numclusters; ++j) { // Don't need to bother if this is the same as the current cluster if (j == cluster) continue; // If the cluster isn't in our current pvs, then get out of here. if ( !CheckBit( uncompressed, j ) ) continue; // Found a visible cluster, now iterate over all leaves // inside that cluster for (k = 0; k < g_ClusterLeaves[j].leafCount; ++k) { int nClusterLeaf = g_ClusterLeaves[j].leafs[k]; // Don't bother testing the ones that don't see a water boundary. if( ((dleafs[nClusterLeaf].contents & CONTENTS_TESTFOGVOLUME) == 0) && ( dleafs[nClusterLeaf].leafWaterDataID == -1 ) ) continue; // Find the minimum distance between each surface on the boundary of the leaf // that we have the pvs for and each water surface in the leaf that we are testing. int nFirstFaceID = dleafs[nClusterLeaf].firstleafface; for( int leafFaceID = 0; leafFaceID < dleafs[nClusterLeaf].numleaffaces; ++leafFaceID ) { int faceID = dleaffaces[nFirstFaceID + leafFaceID]; dface_t *pFace = &dfaces[faceID]; if( pFace->texinfo == -1 ) continue; texinfo_t *pTexInfo = &texinfo[pFace->texinfo]; if( pTexInfo->flags & SURF_WARP ) { // Woo hoo!!! We found a water face. // compare the bounding box of the face with the bounding // box of the leaf that we are looking from and see // what the closest distance is. // FIXME: this could be a face/face distance between the water // face and the bounding volume of the leaf. // Get the bounding box of the face Vector faceMin, faceMax; GetBoundsForFace( faceID, faceMin, faceMax ); float dist = GetMinDistanceBetweenBoundingBoxes( leafMin, leafMax, faceMin, faceMax ); if( dist < minDist ) { minDist = dist; } } } } } return minDist; }
/* ================ CalcPAS Calculate the PAS (Potentially Audible Set) by ORing together all the PVS visible from a leaf ================ */ void CalcPAS (void) { int i, j, k, l, index; int bitbyte; long *dest, *src; byte *scan; int count; byte uncompressed[MAX_MAP_LEAFS/8]; byte compressed[MAX_MAP_LEAFS/8]; Msg ("Building PAS...\n"); count = 0; for (i=0 ; i<portalclusters ; i++) { scan = uncompressedvis + i*leafbytes; memcpy (uncompressed, scan, leafbytes); for (j=0 ; j<leafbytes ; j++) { bitbyte = scan[j]; if (!bitbyte) continue; for (k=0 ; k<8 ; k++) { if (! (bitbyte & (1<<k)) ) continue; // OR this pvs row into the phs index = ((j<<3)+k); if (index >= portalclusters) Error ("Bad bit in PVS"); // pad bits should be 0 src = (long *)(uncompressedvis + index*leafbytes); dest = (long *)uncompressed; for (l=0 ; l<leaflongs ; l++) ((long *)uncompressed)[l] |= src[l]; } } for (j=0 ; j<portalclusters ; j++) { if ( CheckBit( uncompressed, j ) ) { count++; } } // // compress the bit string // j = CompressVis (uncompressed, compressed); dest = (long *)vismap_p; vismap_p += j; if (vismap_p > vismap_end) Error ("Vismap expansion overflow"); dvis->bitofs[i][DVIS_PAS] = (byte *)dest-vismap; memcpy (dest, compressed, j); } Msg ("Average clusters audible: %i\n", count/portalclusters); }
size_t WeightedMatching(RowStarts rowptr,ColIndices colind,ValueTypePtr C, ValueTypePtr dist,ValueTypePtr u,ValueTypePtr v,Indices *p, Indices *m_inv,Indices *m, Indices n,CompareFunction cmpFunc){ typedef typename std::iterator_traits<ValueTypePtr>::value_type ValueType; Indices i,j,i1,jend,k,m_inv_prev; Indices match_size=0; Indices k0,j0; ValueType curr_shortest_path = (ValueType)0; ValueType curr_aug_path = GetMaxTypeValue<ValueType>(curr_aug_path); ValueType dist1; Indices itrace; /*Cost of the edges in the match if *$(i,j) \in M$ then $clabel[i] = C[i][j]$*/ Indices *clabel = new Indices[n]; Indices *aug_label = new Indices[n]; Indices *update_stack = new Indices[n]; Indices update_stack_index; /*Save The Operations on the Heap.*/ Indices save_heap_index; Indices *save_heap_op = new Indices[n]; #ifdef TURN_ON_SAVE_HEAP double close_factor = (double)1.0 + (double)1.0e-16; #endif /*Force the write back to memory to avoid floating point issues*/ ValueType force_mem_write[3]; #ifndef NO_LOCAL_PROFILING CreateProfilingClocks(); #endif /*Core Profiling Clock*/ Clock *core_clk = CreateClock(); #ifdef USE_BIT_ARRAY BitArray_t *col_marker = CreateBitArray(n); BitArray_t *heap_marker = CreateBitArray(n); #else Indices *col_marker = new Indices[n]; unsigned int *heap_marker = NULL; col_marker--; for(i=1;i<=n;i++){ /*Do we need Initialization?*/ col_marker[i] = (Indices)0; } #endif #if BINARY_HEAP Heap *bin_heap = NewBinaryHeap(cmpFunc,n,GetDistKeyID); ValueType *dist_ptr = NULL; heap_marker = bin_heap->keyMap; #endif /*Algorithm Uses 1-Indexing to be consistent*/ C--;m--;dist--;u--;v--;p--;m_inv--; rowptr--;colind--;clabel--;save_heap_op--; update_stack--;aug_label--; assert(dist && u && v && p); ComputeInitialExtremeMatch<ValueType,Indices>(u,v,clabel,C,m,m_inv,colind, rowptr,n,dist); match_size=0; StartClock(core_clk); for(i=1;i<=n;i++){ if(m_inv[i]){ match_size++; continue; } /* *Aim is to find a value for jend such that the path *from i-->jend is the shortest */ i1 = i; p[i1] = 0; jend=0; itrace=i; #ifdef USE_BIT_ARRAY ResetAllBits(col_marker); ResetAllBits(heap_marker); #endif #if BINARY_HEAP bin_heap->n = 0; dist_base = (unsigned long)&(dist[1]); #endif curr_shortest_path=(ValueType)0; curr_aug_path=GetMaxTypeValue<ValueType>(curr_aug_path); save_heap_index = (Indices)0; update_stack_index = (Indices)0; while(1){ for(k=rowptr[i1]+1;k<(rowptr[i1+1]+1);k++){ j = colind[k]+1; #ifdef USE_BIT_ARRAY if(CheckBit(col_marker,j)){ #else if(col_marker[j]==i){ #endif continue; } force_mem_write[k%3] = C[k]-(v[i1]+u[j]); dist1 = curr_shortest_path + force_mem_write[k%3]; /*Prune any dist1's > curr_aug_path, since *all the costs>0 */ if(dist1 < curr_aug_path){ if(!m[j]){ /*we need itrace because, the last i1 which *we explore may not actually give the shortest *augmenting path.*/ jend = j; itrace = i1; curr_aug_path = dist1; aug_label[j] = k; }else if(dist1 < dist[j]){ /*Update the dist*/ dist[j] = dist1; p[m[j]] = i1; aug_label[j] = k; #if SIMPLE_HEAP #ifdef USE_BIT_ARRAY SetBit(heap_marker,j); #else heap_marker[j] = i; #endif #elif BINARY_HEAP /*SIMPLE_HEAP*/ #ifdef USE_BIT_ARRAY if(CheckBit(heap_marker,j)){ #else if(heap_marker[j]){ #endif #ifndef NO_LOCAL_PROFILING StartClock(hupdate_clk); #endif /*Call the decrease Key Operation*/ DecreaseKey(bin_heap,j); #ifndef NO_LOCAL_PROFILING StopClock(hupdate_clk); hupdate_ticks += GetClockTicks(hupdate_clk); #endif } #ifdef TURN_ON_SAVE_HEAP else if(curr_shortest_path && dist[j] <= (curr_shortest_path)*(close_factor)){ /*If dist[j] is close to root push it in *save_heap_op*/ assert(save_heap_index < n); save_heap_op[++save_heap_index] = j; } #endif else{ #ifndef NO_LOCAL_PROFILING StartClock(hins_clk); #endif InsertHeap(bin_heap,&(dist[j])); #ifndef NO_LOCAL_PROFILING StopClock(hins_clk); hins_ticks += GetClockTicks(hins_clk); #endif #ifdef USE_BIT_ARRAY SetBit(heap_marker,j); #endif } #endif /*SIMPLE_HEAP*/ } } } if(curr_aug_path <= curr_shortest_path){ break; } /*We now have a heap of matched cols, so pick the min*/ #ifdef SIMPLE_HEAP j = SimplePickMin(heap_marker,dist,n); if(j){ curr_shortest_path = dist[j]; UnsetBit(heap_marker,j); #elif BINARY_HEAP #ifndef NO_LOCAL_PROFILING StartClock(hdel_clk); #endif if(save_heap_index){ j = save_heap_op[save_heap_index]; save_heap_index--; curr_shortest_path = dist[j]; #ifdef USE_BIT_ARRAY SetBit(col_marker,j); #else col_marker[j] = (Indices)i; update_stack[++update_stack_index]=j; #endif /*#ifdef USE_BIT_ARRAY*/ i1 = m[j]; }else if(dist_ptr = (ValueType *) HeapDelete(bin_heap)) { #ifndef NO_LOCAL_PROFILING StopClock(hdel_clk); hdel_ticks += GetClockTicks(hdel_clk); #endif assert((unsigned long)dist_ptr >= (unsigned long)&dist[1]); j = ((((unsigned long)dist_ptr - (unsigned long)&dist[1]))/sizeof(ValueType))+1; assert(j>=1 && j<=n); curr_shortest_path = dist[j]; heap_marker[j] = 0; /*Setting the keyMap in Heap to 0*/ #endif /*#ifdef SIMPLE_HEAP */ #ifdef USE_BIT_ARRAY SetBit(col_marker,j); update_stack[++update_stack_index]=j; #else col_marker[j] = (Indices)i; update_stack[++update_stack_index]=j; #endif /*#ifdef USE_BIT_ARRAY*/ i1 = m[j]; }else{ break; } } /*We found a shortest augmenting path*/ if(jend){ unsigned long **harray = bin_heap->heapArray; #ifndef NO_LOCAL_PROFILING StartClock(dual_clk); #endif /*NOTE1: We need a very fast way to update *the dual variables and also reset the dist[] *we avoid linear scan where ever we can to update *these dual variables*/ while(update_stack_index){ /*Update u[j]: while*/ j=update_stack[update_stack_index--]; u[j] = (u[j]+dist[j])-curr_aug_path; if(m[j]){ /*See NOTE1*/ i1 = m[j]; v[i1] = C[clabel[i1]] - u[j]; } dist[j] = MAX_DOUBLE_VALUE; if(bin_heap->n){ dist_ptr = (double *)harray[bin_heap->n]; j = ((((unsigned long)dist_ptr - (unsigned long)&dist[1]))/sizeof(ValueType))+1; heap_marker[j] = 0; *((double *)harray[bin_heap->n]) = MAX_DOUBLE_VALUE; bin_heap->n -= 1 ; } } /*Update u[j]: while*/ /*Uncomment if you need to print augmenting path*/ /*node_t itrace_prev;*/ /*printf("Shortest augmenting Path {");*/ j=jend; while(itrace){ m_inv_prev = m_inv[itrace]; m[j] = itrace; m_inv[itrace]=j; /*See NOTE1(above)*/ clabel[itrace] = aug_label[j]; v[itrace] = C[clabel[itrace]] - u[j]; /*printf("(%u,%u)",itrace,j);*/ j=m_inv_prev; /*itrace_prev = itrace;*/ itrace = p[itrace]; /* if(itrace){ printf("(%u,%u)",itrace_prev,m_inv_prev); }*/ } /*printf("}\n");*/ /*There may some dist[] still in the heap*/ while(bin_heap->n){ dist_ptr = (double *)harray[bin_heap->n]; j = ((((unsigned long)dist_ptr - (unsigned long)&dist[1]))/sizeof(ValueType))+1; heap_marker[j] = 0; *((double *)harray[bin_heap->n]) = MAX_DOUBLE_VALUE; bin_heap->n -= 1; } match_size++; /*End Dual Update*/ #ifndef NO_LOCAL_PROFILING StopClock(dual_clk); dual_ticks += GetClockTicks(dual_clk); #endif } /*if(jend) : Found Augmeting Path*/ } /*for(i=1;i<=n;i++): Main Outer Loop*/ StopClock(core_clk); WeightedMatchTicks = GetClockTicks(core_clk); #ifndef NO_LOCAL_PROFILING printf("Profile Summary\n"); printf("HINS=(%d) HDEL=(%d) HUPDATE=(%d)\n",(int)hins_ticks,(int)hdel_ticks, (int)hupdate_ticks); printf("DUAL=(%d) \n",(int)dual_ticks); #endif #ifdef USE_BIT_ARRAY FreeBitArray(col_marker); FreeBitArray(heap_marker); #else col_marker++; delete col_marker; #endif #ifdef SIMPLE_HEAP heap_marker++; delete heap_marker; #endif aug_label++; delete aug_label; save_heap_op++; delete save_heap_op; clabel++; delete clabel; #ifdef BINARY_HEAP FreeHeap(bin_heap); #endif return match_size; } /*O(n) time picking the maximum from the heap_marker */ node_t SimplePickMin(BitArray_t *bit_heap,double *dist,node_t n){ node_t min_j=0;node_t j; double curr_min = HUGE_VAL; for(j=1;j<=n;j++){ if(CheckBit(bit_heap,j) && dist[j] < curr_min){ min_j = j; curr_min = dist[j]; } } return min_j; } #ifdef BINARY_HEAP inline keyid_t GetDistKeyID(void *dist_ptr){ assert((unsigned long)dist_ptr >= dist_base); return (((((unsigned long)dist_ptr-dist_base))/sizeof(double))+1); } #endif BitArray_t* CreateBitArray(unsigned int size){ div_t d = div(size,SIZE_OF_BYTE_IN_BITS); BitArray_t *bits = (BitArray_t *)malloc(sizeof(BitArray_t)*1); assert(bits); bits->size = (d.rem > 0)?(d.quot+1):d.quot; bits->ba = (char *)malloc(sizeof(char)*(bits->size)); assert(bits->ba); memset(bits->ba,'\0',bits->size); return bits; }