/* Called with 'buf_size == 0' if buf is in fact a pointer _directly_ into the flash, XIP-style */ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, unsigned char *buf, uint32_t buf_size, struct jffs2_summary *s) { struct jffs2_unknown_node *node; struct jffs2_unknown_node crcnode; uint32_t ofs, prevofs; uint32_t hdr_crc, buf_ofs, buf_len; int err; int noise = 0; #ifdef CONFIG_JFFS2_FS_WRITEBUFFER int cleanmarkerfound = 0; #endif ofs = jeb->offset; prevofs = jeb->offset - 1; D1(printk(KERN_DEBUG "jffs2_scan_eraseblock(): Scanning block at 0x%x\n", ofs)); //printk("jffs2_scan_eraseblock(): Scanning block at 0x%x\n", ofs); #ifdef CONFIG_JFFS2_FS_WRITEBUFFER if (jffs2_cleanmarker_oob(c)) { int ret = jffs2_check_nand_cleanmarker(c, jeb); D2(printk(KERN_NOTICE "jffs_check_nand_cleanmarker returned %d\n",ret)); /* Even if it's not found, we still scan to see if the block is empty. We use this information to decide whether to erase it or not. */ switch (ret) { case 0: cleanmarkerfound = 1; break; case 1: break; case 2: return BLK_STATE_BADBLOCK; case 3: return BLK_STATE_ALLDIRTY; /* Block has failed to erase min. once */ default: return ret; } } #endif if (jffs2_sum_active()) { struct jffs2_sum_marker *sm; void *sumptr = NULL; uint32_t sumlen; //printk("******** SUMMARY ACTIVE *****\n"); if (!buf_size) { /* XIP case. Just look, point at the summary if it's there */ sm = (void *)buf + c->sector_size - sizeof(*sm); if (je32_to_cpu(sm->magic) == JFFS2_SUM_MAGIC) { sumptr = buf + je32_to_cpu(sm->offset); sumlen = c->sector_size - je32_to_cpu(sm->offset); } } else { /* If NAND flash, read a whole page of it. Else just the end */ if (c->wbuf_pagesize) buf_len = c->wbuf_pagesize; else buf_len = sizeof(*sm); /* Read as much as we want into the _end_ of the preallocated buffer */ err = jffs2_fill_scan_buf(c, buf + buf_size - buf_len, jeb->offset + c->sector_size - buf_len, buf_len); if (err) return err; sm = (void *)buf + buf_size - sizeof(*sm); if (je32_to_cpu(sm->magic) == JFFS2_SUM_MAGIC) { sumlen = c->sector_size - je32_to_cpu(sm->offset); sumptr = buf + buf_size - sumlen; /* Now, make sure the summary itself is available */ if (sumlen > buf_size) { /* Need to kmalloc for this. */ sumptr = kmalloc(sumlen, GFP_KERNEL); if (!sumptr) return -ENOMEM; memcpy(sumptr + sumlen - buf_len, buf + buf_size - buf_len, buf_len); } if (buf_len < sumlen) { /* Need to read more so that the entire summary node is present */ err = jffs2_fill_scan_buf(c, sumptr, jeb->offset + c->sector_size - sumlen, sumlen - buf_len); if (err) return err; } } } if (sumptr) { err = jffs2_sum_scan_sumnode(c, jeb, sumptr, sumlen, &pseudo_random); if (buf_size && sumlen > buf_size) kfree(sumptr); /* If it returns with a real error, bail. If it returns positive, that's a block classification (i.e. BLK_STATE_xxx) so return that too. If it returns zero, fall through to full scan. */ if (err) return err; } } buf_ofs = jeb->offset; //printk("%s: 20, buf_ofs=%08x\n", __FUNCTION__, buf_ofs); if (!buf_size) { /* This is the XIP case -- we're reading _directly_ from the flash chip */ buf_len = c->sector_size; } else { buf_len = EMPTY_SCAN_SIZE(c->sector_size); //gdebug = 4; //printk("%s:%d: Calling jffs2_fill_scan_buf(%08x, %d)\n", __FUNCTION__, __LINE__, buf_ofs, buf_len); err = jffs2_fill_scan_buf(c, buf, buf_ofs, buf_len); //gdebug = 0; if (err) return err; } /* We temporarily use 'ofs' as a pointer into the buffer/jeb */ ofs = 0; /* Scan only 4KiB of 0xFF before declaring it's empty */ while(ofs < EMPTY_SCAN_SIZE(c->sector_size) && *(uint32_t *)(&buf[ofs]) == 0xFFFFFFFF) ofs += 4; if (ofs == EMPTY_SCAN_SIZE(c->sector_size)) { #ifdef CONFIG_JFFS2_FS_WRITEBUFFER if (jffs2_cleanmarker_oob(c)) { /* scan oob, take care of cleanmarker */ int ret; //printk("%s:%d Calling jffs2_check_oob_empty\n", __FUNCTION__, __LINE__); ret = jffs2_check_oob_empty(c, jeb, cleanmarkerfound); D2(printk(KERN_NOTICE "jffs2_check_oob_empty returned %d\n",ret)); switch (ret) { case 0: return cleanmarkerfound ? BLK_STATE_CLEANMARKER : BLK_STATE_ALLFF; case 1: return BLK_STATE_ALLDIRTY; default: return ret; } } #endif D1(printk(KERN_DEBUG "Block at 0x%08x is empty (erased)\n", jeb->offset)); if (c->cleanmarker_size == 0) return BLK_STATE_CLEANMARKER; /* don't bother with re-erase */ else return BLK_STATE_ALLFF; /* OK to erase if all blocks are like this */ } if (ofs) { D1(printk(KERN_DEBUG "Free space at %08x ends at %08x\n", jeb->offset, jeb->offset + ofs)); if ((err = jffs2_prealloc_raw_node_refs(c, jeb, 1))) return err; if ((err = jffs2_scan_dirty_space(c, jeb, ofs))) return err; } /* Now ofs is a complete physical flash offset as it always was... */ ofs += jeb->offset; //printk("%s:%d, ofs=%08x, jeb->offset=%08x\n", __FUNCTION__, __LINE__, ofs, jeb->offset); //noise = 10; dbg_summary("no summary found in jeb 0x%08x. Apply original scan.\n",jeb->offset); scan_more: while(ofs < jeb->offset + c->sector_size) { //printk("%s:%d, scan_more top: ofs=%08x\n", __FUNCTION__, __LINE__, ofs); jffs2_dbg_acct_paranoia_check_nolock(c, jeb); /* Make sure there are node refs available for use */ err = jffs2_prealloc_raw_node_refs(c, jeb, 2); if (err) return err; cond_resched(); if (ofs & 3) { printk(KERN_WARNING "Eep. ofs 0x%08x not word-aligned!\n", ofs); ofs = PAD(ofs); continue; } if (ofs == prevofs) { printk(KERN_WARNING "ofs 0x%08x has already been seen. Skipping\n", ofs); if ((err = jffs2_scan_dirty_space(c, jeb, 4))) return err; ofs += 4; continue; } prevofs = ofs; if (jeb->offset + c->sector_size < ofs + sizeof(*node)) { D1(printk(KERN_DEBUG "Fewer than %zd bytes left to end of block. (%x+%x<%x+%zx) Not reading\n", sizeof(struct jffs2_unknown_node), jeb->offset, c->sector_size, ofs, sizeof(*node))); if ((err = jffs2_scan_dirty_space(c, jeb, (jeb->offset + c->sector_size)-ofs))) return err; break; } if (buf_ofs + buf_len < ofs + sizeof(*node)) { buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs); D1(printk(KERN_DEBUG "Fewer than %zd bytes (node header) left to end of buf. Reading 0x%x at 0x%08x\n", sizeof(struct jffs2_unknown_node), buf_len, ofs)); //printk("%s:%d: Calling jffs2_fill_scan_buf(%08x, %d)\n", __FUNCTION__, __LINE__, ofs, buf_len); err = jffs2_fill_scan_buf(c, buf, ofs, buf_len); if (err) return err; buf_ofs = ofs; } node = (struct jffs2_unknown_node *)&buf[ofs-buf_ofs]; if (*(uint32_t *)(&buf[ofs-buf_ofs]) == 0xffffffff) { uint32_t inbuf_ofs; uint32_t empty_start; empty_start = ofs; ofs += 4; D1(printk(KERN_DEBUG "Found empty flash at 0x%08x\n", ofs)); more_empty: inbuf_ofs = ofs - buf_ofs; while (inbuf_ofs < buf_len) { if (*(uint32_t *)(&buf[inbuf_ofs]) != 0xffffffff) { printk(KERN_WARNING "Empty flash at 0x%08x ends at 0x%08x\n", empty_start, ofs); if ((err = jffs2_scan_dirty_space(c, jeb, ofs-empty_start))) return err; goto scan_more; } inbuf_ofs+=4; ofs += 4; } /* Ran off end. */ D1(printk(KERN_DEBUG "Empty flash to end of buffer at 0x%08x\n", ofs)); /* If we're only checking the beginning of a block with a cleanmarker, bail now */ if (buf_ofs == jeb->offset && jeb->used_size == PAD(c->cleanmarker_size) && c->cleanmarker_size && !jeb->dirty_size && !ref_next(jeb->first_node)) { D1(printk(KERN_DEBUG "%d bytes at start of block seems clean... assuming all clean\n", EMPTY_SCAN_SIZE(c->sector_size))); return BLK_STATE_CLEANMARKER; } /* See how much more there is to read in this eraseblock... */ buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs); if (!buf_len) { /* No more to read. Break out of main loop without marking this range of empty space as dirty (because it's not) */ D1(printk(KERN_DEBUG "Empty flash at %08x runs to end of block. Treating as free_space\n", empty_start)); break; } D1(printk(KERN_DEBUG "Reading another 0x%x at 0x%08x\n", buf_len, ofs)); //printk("%s:%d: Calling jffs2_fill_scan_buf(%08x, %d)\n", __FUNCTION__, __LINE__, buf_ofs, buf_len); err = jffs2_fill_scan_buf(c, buf, ofs, buf_len); if (err) return err; buf_ofs = ofs; goto more_empty; } if (ofs == jeb->offset && je16_to_cpu(node->magic) == KSAMTIB_CIGAM_2SFFJ) { printk(KERN_WARNING "Magic bitmask is backwards at offset 0x%08x. Wrong endian filesystem?\n", ofs); if ((err = jffs2_scan_dirty_space(c, jeb, 4))) return err; ofs += 4; continue; } if (je16_to_cpu(node->magic) == JFFS2_DIRTY_BITMASK) { // D1(printk(KERN_DEBUG "Dirty bitmask at 0x%08x\n", ofs)); if ((err = jffs2_scan_dirty_space(c, jeb, 4))) return err; ofs += 4; continue; } if (je16_to_cpu(node->magic) == JFFS2_OLD_MAGIC_BITMASK) { printk(KERN_WARNING "Old JFFS2 bitmask found at 0x%08x\n", ofs); printk(KERN_WARNING "You cannot use older JFFS2 filesystems with newer kernels\n"); if ((err = jffs2_scan_dirty_space(c, jeb, 4))) return err; ofs += 4; continue; } if (je16_to_cpu(node->magic) != JFFS2_MAGIC_BITMASK) { /* OK. We're out of possibilities. Whinge and move on */ noisy_printk(&noise, "jffs2_scan_eraseblock(): Magic bitmask 0x%04x not found at 0x%08x: 0x%04x instead\n", JFFS2_MAGIC_BITMASK, ofs, je16_to_cpu(node->magic)); if ((err = jffs2_scan_dirty_space(c, jeb, 4))) return err; ofs += 4; continue; } /* We seem to have a node of sorts. Check the CRC */ crcnode.magic = node->magic; crcnode.nodetype = cpu_to_je16( je16_to_cpu(node->nodetype) | JFFS2_NODE_ACCURATE); crcnode.totlen = node->totlen; hdr_crc = crc32(0, &crcnode, sizeof(crcnode)-4); if (hdr_crc != je32_to_cpu(node->hdr_crc)) { noisy_printk(&noise, "jffs2_scan_eraseblock(): Node at 0x%08x {0x%04x, 0x%04x, 0x%08x) has invalid CRC 0x%08x (calculated 0x%08x)\n", ofs, je16_to_cpu(node->magic), je16_to_cpu(node->nodetype), je32_to_cpu(node->totlen), je32_to_cpu(node->hdr_crc), hdr_crc); if ((err = jffs2_scan_dirty_space(c, jeb, 4))) return err; ofs += 4; continue; } if (ofs + je32_to_cpu(node->totlen) > jeb->offset + c->sector_size) { /* Eep. Node goes over the end of the erase block. */ printk(KERN_WARNING "Node at 0x%08x with length 0x%08x would run over the end of the erase block\n", ofs, je32_to_cpu(node->totlen)); printk(KERN_WARNING "Perhaps the file system was created with the wrong erase size?\n"); if ((err = jffs2_scan_dirty_space(c, jeb, 4))) return err; ofs += 4; continue; } if (!(je16_to_cpu(node->nodetype) & JFFS2_NODE_ACCURATE)) { /* Wheee. This is an obsoleted node */ D2(printk(KERN_DEBUG "Node at 0x%08x is obsolete. Skipping\n", ofs)); if ((err = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(node->totlen))))) return err; ofs += PAD(je32_to_cpu(node->totlen)); continue; } switch(je16_to_cpu(node->nodetype)) { case JFFS2_NODETYPE_INODE: if (buf_ofs + buf_len < ofs + sizeof(struct jffs2_raw_inode)) { buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs); D1(printk(KERN_DEBUG "Fewer than %zd bytes (inode node) left to end of buf. Reading 0x%x at 0x%08x\n", sizeof(struct jffs2_raw_inode), buf_len, ofs)); //printk("%s:%d: Calling jffs2_fill_scan_buf(%08x, %d)\n", __FUNCTION__, __LINE__, buf_ofs, buf_len); err = jffs2_fill_scan_buf(c, buf, ofs, buf_len); if (err) return err; buf_ofs = ofs; node = (void *)buf; } err = jffs2_scan_inode_node(c, jeb, (void *)node, ofs, s); if (err) return err; ofs += PAD(je32_to_cpu(node->totlen)); break; case JFFS2_NODETYPE_DIRENT: if (buf_ofs + buf_len < ofs + je32_to_cpu(node->totlen)) { buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs); D1(printk(KERN_DEBUG "Fewer than %d bytes (dirent node) left to end of buf. Reading 0x%x at 0x%08x\n", je32_to_cpu(node->totlen), buf_len, ofs)); //printk("%s:%d: Calling jffs2_fill_scan_buf(%08x, %d)\n", __FUNCTION__, __LINE__, buf_ofs, buf_len); err = jffs2_fill_scan_buf(c, buf, ofs, buf_len); if (err) return err; buf_ofs = ofs; node = (void *)buf; } err = jffs2_scan_dirent_node(c, jeb, (void *)node, ofs, s); if (err) return err; ofs += PAD(je32_to_cpu(node->totlen)); break; #ifdef CONFIG_JFFS2_FS_XATTR case JFFS2_NODETYPE_XATTR: if (buf_ofs + buf_len < ofs + je32_to_cpu(node->totlen)) { buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs); D1(printk(KERN_DEBUG "Fewer than %d bytes (xattr node)" " left to end of buf. Reading 0x%x at 0x%08x\n", je32_to_cpu(node->totlen), buf_len, ofs)); err = jffs2_fill_scan_buf(c, buf, ofs, buf_len); if (err) return err; buf_ofs = ofs; node = (void *)buf; } err = jffs2_scan_xattr_node(c, jeb, (void *)node, ofs, s); if (err) return err; ofs += PAD(je32_to_cpu(node->totlen)); break; case JFFS2_NODETYPE_XREF: if (buf_ofs + buf_len < ofs + je32_to_cpu(node->totlen)) { buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs); D1(printk(KERN_DEBUG "Fewer than %d bytes (xref node)" " left to end of buf. Reading 0x%x at 0x%08x\n", je32_to_cpu(node->totlen), buf_len, ofs)); err = jffs2_fill_scan_buf(c, buf, ofs, buf_len); if (err) return err; buf_ofs = ofs; node = (void *)buf; } err = jffs2_scan_xref_node(c, jeb, (void *)node, ofs, s); if (err) return err; ofs += PAD(je32_to_cpu(node->totlen)); break; #endif /* CONFIG_JFFS2_FS_XATTR */ case JFFS2_NODETYPE_CLEANMARKER: D1(printk(KERN_DEBUG "CLEANMARKER node found at 0x%08x\n", ofs)); if (je32_to_cpu(node->totlen) != c->cleanmarker_size) { printk(KERN_NOTICE "CLEANMARKER node found at 0x%08x has totlen 0x%x != normal 0x%x\n", ofs, je32_to_cpu(node->totlen), c->cleanmarker_size); if ((err = jffs2_scan_dirty_space(c, jeb, PAD(sizeof(struct jffs2_unknown_node))))) return err; ofs += PAD(sizeof(struct jffs2_unknown_node)); } else if (jeb->first_node) { printk(KERN_NOTICE "CLEANMARKER node found at 0x%08x, not first node in block (0x%08x)\n", ofs, jeb->offset); if ((err = jffs2_scan_dirty_space(c, jeb, PAD(sizeof(struct jffs2_unknown_node))))) return err; ofs += PAD(sizeof(struct jffs2_unknown_node)); } else { jffs2_link_node_ref(c, jeb, ofs | REF_NORMAL, c->cleanmarker_size, NULL); ofs += PAD(c->cleanmarker_size); } break; case JFFS2_NODETYPE_PADDING: if (jffs2_sum_active()) jffs2_sum_add_padding_mem(s, je32_to_cpu(node->totlen)); if ((err = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(node->totlen))))) return err; ofs += PAD(je32_to_cpu(node->totlen)); break; default: switch (je16_to_cpu(node->nodetype) & JFFS2_COMPAT_MASK) { case JFFS2_FEATURE_ROCOMPAT: printk(KERN_NOTICE "Read-only compatible feature node (0x%04x) found at offset 0x%08x\n", je16_to_cpu(node->nodetype), ofs); c->flags |= JFFS2_SB_FLAG_RO; if (!(jffs2_is_readonly(c))) return -EROFS; if ((err = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(node->totlen))))) return err; ofs += PAD(je32_to_cpu(node->totlen)); break; case JFFS2_FEATURE_INCOMPAT: printk(KERN_NOTICE "Incompatible feature node (0x%04x) found at offset 0x%08x\n", je16_to_cpu(node->nodetype), ofs); return -EINVAL; case JFFS2_FEATURE_RWCOMPAT_DELETE: D1(printk(KERN_NOTICE "Unknown but compatible feature node (0x%04x) found at offset 0x%08x\n", je16_to_cpu(node->nodetype), ofs)); if ((err = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(node->totlen))))) return err; ofs += PAD(je32_to_cpu(node->totlen)); break; case JFFS2_FEATURE_RWCOMPAT_COPY: { D1(printk(KERN_NOTICE "Unknown but compatible feature node (0x%04x) found at offset 0x%08x\n", je16_to_cpu(node->nodetype), ofs)); jffs2_link_node_ref(c, jeb, ofs | REF_PRISTINE, PAD(je32_to_cpu(node->totlen)), NULL); /* We can't summarise nodes we don't grok */ jffs2_sum_disable_collecting(s); ofs += PAD(je32_to_cpu(node->totlen)); break; } } } } if (jffs2_sum_active()) { if (PAD(s->sum_size + JFFS2_SUMMARY_FRAME_SIZE) > jeb->free_size) { dbg_summary("There is not enough space for " "summary information, disabling for this jeb!\n"); jffs2_sum_disable_collecting(s); } } D1(printk(KERN_DEBUG "Block at 0x%08x: free 0x%08x, dirty 0x%08x, unchecked 0x%08x, used 0x%08x, wasted 0x%08x\n", jeb->offset,jeb->free_size, jeb->dirty_size, jeb->unchecked_size, jeb->used_size, jeb->wasted_size)); /* mark_node_obsolete can add to wasted !! */ if (jeb->wasted_size) { jeb->dirty_size += jeb->wasted_size; c->dirty_size += jeb->wasted_size; c->wasted_size -= jeb->wasted_size; jeb->wasted_size = 0; } return jffs2_scan_classify_jeb(c, jeb); }
int main(int argc, char* argv[]) { bool verb; /* verbosity flag */ bool abc; /* absorbing boundary conditions flag */ bool free; /* free surface flag*/ bool snap; /* wavefield snapshots flag */ bool dens; int jsnap;/* save wavefield every *jsnap* time steps */ /* I/O files */ sf_file Fw,Fs,Fr; sf_file Fd,Fu; sf_file Fv=NULL; /* velocity */ sf_file Fe=NULL; /* density */ /* cube axes */ sf_axis at,az,ax,as,ar; int it,iz,ix,is,ir, iop; int nt,nz,nx,ns,nr,nz2,nx2; float z0,dz,x0,dx,idx,idz,dt,dt2; /* arrays */ pt2d *ss, *rr; /* source/receiver locations */ float *ww=NULL; /* wavelet */ float *dd=NULL; /* data */ float **vv=NULL; /* velocity */ float **ee=NULL; /* density */ float *fzs,*fxs, *fzr,*fxr; int *jzs,*jxs, *jzr,*jxr; float *ws00,*ws01,*ws10,*ws11; float *wr00,*wr01,*wr10,*wr11; float **um,**uo,**up,**ud,**vp,**ro,**tt,**ut; float *bzl,*bzh,*bxl,*bxh; /* boundary */ int nop=2; /* Laplacian operator size */ float c0, c1, c2; /* Laplacian operator coefficients */ float co,c1x,c2x,c1z,c2z; int nbz,nbx; /* boundary size */ float tz, tx; /* sponge boundary decay coefficients */ float dp; float ws; /* injected data */ int ompchunk; /* OpenMP data chunk size */ /*------------------------------------------------------------*/ /* init RSF */ sf_init(argc,argv); if(! sf_getint("ompchunk",&ompchunk)) ompchunk=1; if(! sf_getbool("verb",&verb)) verb=false; if(! sf_getbool( "abc",&abc )) abc=false; if(! sf_getbool("snap",&snap)) snap=false; if(! sf_getbool("free",&free)) free=false; if(! sf_getbool("dens",&dens)) dens=false; Fw = sf_input ("in" ); /* wavelet */ Fv = sf_input ("vel"); /* velocity */ Fs = sf_input ("sou"); /* sources */ Fr = sf_input ("rec"); /* receivers */ Fu = sf_output("wfl"); /* wavefield */ Fd = sf_output("out"); /* data */ if(dens) Fe = sf_input("den"); /* density */ /* read axes*/ at=sf_iaxa(Fw,1); sf_setlabel(at,"t"); if(verb) sf_raxa(at); /* time */ az=sf_iaxa(Fv,1); sf_setlabel(az,"z"); if(verb) sf_raxa(az); /* depth */ ax=sf_iaxa(Fv,2); sf_setlabel(ax,"x"); if(verb) sf_raxa(ax); /* space */ as=sf_iaxa(Fs,2); sf_setlabel(as,"s"); if(verb) sf_raxa(as); /* source */ ar=sf_iaxa(Fr,2); sf_setlabel(ar,"r"); if(verb) sf_raxa(ar); /* receiver */ nt=sf_n(at); dt=sf_d(at); nz=sf_n(az); nx=sf_n(ax); ns=sf_n(as); nr=sf_n(ar); /* configure wavefield snapshots */ if(snap) { if(! sf_getint("jsnap",&jsnap)) jsnap=nt; } /*------------------------------------------------------------*/ /* expand domain for absorbing boundary conditions */ if(abc) { if(! sf_getint("nbz",&nbz)) nbz=nop; if(nbz<nop) nbz=nop; if(! sf_getint("nbx",&nbx)) nbx=nop; if(nbx<nop) nbx=nop; if(! sf_getfloat("tz",&tz)) tz=0.025; if(! sf_getfloat("tx",&tx)) tx=0.025; } else { nbz=nop; nbx=nop; } /* expanded domain ( az+2 nz, ax+2 nx ) */ nz2=nz+2*nbz; dz=sf_d(az); z0=sf_o(az)-nbz*dz; nx2=nx+2*nbx; dx=sf_d(ax); x0=sf_o(ax)-nbx*dx; sf_setn(az,nz2); sf_seto(az,z0); if(verb) sf_raxa(az); sf_setn(ax,nx2); sf_seto(ax,x0); if(verb) sf_raxa(ax); /*------------------------------------------------------------*/ /* setup output data header */ sf_oaxa(Fd,ar,1); sf_oaxa(Fd,at,2); /* setup output wavefield header */ if(snap) { sf_setn(at,nt/jsnap); sf_setd(at,dt*jsnap); sf_oaxa(Fu,az,1); sf_oaxa(Fu,ax,2); sf_oaxa(Fu,at,3); } /* Laplacian coefficients */ c0=-30./12.; c1=+16./12.; c2=- 1./12.; dt2 = dt*dt; idz = 1/dz; idx = 1/dx; co = c0 * (idx*idx+idz*idz); c1x= c1 * idx*idx; c2x= c2 * idx*idx; c1z= c1 * idz*idz; c2z= c2 * idz*idz; /*------------------------------------------------------------*/ /* allocate arrays */ ww=sf_floatalloc (nt); sf_floatread(ww ,nt ,Fw); vv=sf_floatalloc2(nz,nx); sf_floatread(vv[0],nz*nx,Fv); ee=sf_floatalloc2(nz,nx); if(dens) { sf_floatread(ee[0],nz*nx,Fe); } else { for (iz=0; iz<nz; iz++) { for (ix=0; ix<nx; ix++) { ee[ix][iz]=1; } } } /* allocate source/receiver point arrays */ ss = (pt2d*) sf_alloc(ns,sizeof(*ss)); rr = (pt2d*) sf_alloc(nr,sizeof(*rr)); pt2dread1(Fs,ss,ns,3); /* read 3 elements (x,z,v) */ pt2dread1(Fr,rr,nr,2); /* read 2 elements (x,z) */ dd=sf_floatalloc(nr); for(ir=0;ir<nr;ir++) { dd[ir]=0; } jzs=sf_intalloc(ns); fzs=sf_floatalloc(ns); jzr=sf_intalloc(nr); fzr=sf_floatalloc(nr); jxs=sf_intalloc(ns); fxs=sf_floatalloc(ns); jxr=sf_intalloc(nr); fxr=sf_floatalloc(nr); ws00 = sf_floatalloc(ns); wr00 = sf_floatalloc(nr); ws01 = sf_floatalloc(ns); wr01 = sf_floatalloc(nr); ws10 = sf_floatalloc(ns); wr10 = sf_floatalloc(nr); ws11 = sf_floatalloc(ns); wr11 = sf_floatalloc(nr); /*------------------------------------------------------------*/ for (is=0;is<ns;is++) { if(ss[is].z >= z0 && ss[is].z < z0 + (nz2-1)*dz && ss[is].x >= x0 && ss[is].x < x0 + (nx2-1)*dx) { jzs[is] = (int)( (ss[is].z-z0)/dz); fzs[is] = (ss[is].z-z0)/dz - jzs[is]; jxs[is] = (int)( (ss[is].x-x0)/dx); fxs[is] = (ss[is].x-x0)/dx - jxs[is]; } else { jzs[is] = 0; jxs[is] = 0; fzs[is] = 1; fxs[is] = 0; ss[is].v= 0; } ws00[is] = (1-fzs[is])*(1-fxs[is]); ws01[is] = ( fzs[is])*(1-fxs[is]); ws10[is] = (1-fzs[is])*( fxs[is]); ws11[is] = ( fzs[is])*( fxs[is]); } for (ir=0;ir<nr;ir++) { if(rr[ir].z >= z0 && rr[ir].z < z0 + (nz2-1)*dz && rr[ir].x >= x0 && rr[ir].x < x0 + (nx2-1)*dx) { jzr[ir] = (int)( (rr[ir].z-z0)/dz); fzr[ir] = (rr[ir].z-z0)/dz - jzr[ir]; jxr[ir] = (int)( (rr[ir].x-x0)/dx); fxr[ir] = (rr[ir].x-x0)/dx - jxr[ir]; rr[ir].v=1; } else { jzr[ir] = 0; fzr[ir] = 1; rr[ir].v= 0; } wr00[ir] = (1-fzr[ir])*(1-fxr[ir]); wr01[ir] = ( fzr[ir])*(1-fxr[ir]); wr10[ir] = (1-fzr[ir])*( fxr[ir]); wr11[ir] = ( fzr[ir])*( fxr[ir]); } /*------------------------------------------------------------*/ /* allocate temporary arrays */ um=sf_floatalloc2(nz2,nx2); uo=sf_floatalloc2(nz2,nx2); up=sf_floatalloc2(nz2,nx2); ud=sf_floatalloc2(nz2,nx2); tt=sf_floatalloc2(nz2,nx2); #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,ompchunk) private(iz,ix) shared(nx2,nz2,um,uo,up,ud,tt) #endif for (iz=0; iz<nz2; iz++) { for (ix=0; ix<nx2; ix++) { um[ix][iz]=0; uo[ix][iz]=0; up[ix][iz]=0; ud[ix][iz]=0; tt[ix][iz]=1; } } /*------------------------------------------------------------*/ /* velocity in the expanded domain (vp=vv^2)*/ vp=sf_floatalloc2(nz2,nx2); ro=sf_floatalloc2(nz2,nx2); #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,ompchunk) private(iz,ix) shared(nz,nx,vp,ro,vv,ee) #endif for (iz=0; iz<nz; iz++) { for (ix=0; ix<nx; ix++) { vp[nbx+ix][nbz+iz] = vv[ix][iz] * vv[ix][iz]; ro[nbx+ix][nbz+iz] = ee[ix][iz]; } } /* fill boundaries */ for (iz=0; iz<nbz; iz++) { for (ix=0; ix<nx2; ix++) { vp[ix][ iz ] = vp[ix][ nbz ]; vp[ix][nz2-iz-1] = vp[ix][nz2-nbz-1]; ro[ix][ iz ] = ro[ix][ nbz ]; ro[ix][nz2-iz-1] = ro[ix][nz2-nbz-1]; } } for (iz=0; iz<nz2; iz++) { for (ix=0; ix<nbx; ix++) { vp[ ix ][iz] = vp[ nbx ][iz]; vp[nx2-ix-1][iz] = vp[nx2-nbx-1][iz]; ro[ ix ][iz] = ro[ nbx ][iz]; ro[nx2-ix-1][iz] = ro[nx2-nbx-1][iz]; } } /*------------------------------------------------------------*/ /* free surface */ if(abc && free) { for (iz=0; iz<nbz; iz++) { for (ix=0; ix<nx2; ix++) { vp[ix][iz]=0; } } } /*------------------------------------------------------------*/ /* sponge ABC setup */ if(abc) { for (iz=0; iz<nbz; iz++) { for (ix=0; ix<nx2; ix++) { tt[ix][ iz ] = exp( - (tz*(nbz-iz))*(tz*(nbz-iz)) ); tt[ix][nz2-iz-1] = tt[ix][iz]; } } for (iz=0; iz<nz2; iz++) { for (ix=0; ix<nbx; ix++) { tt[ ix ][iz] = exp( - (tx*(nbx-ix))*(tx*(nbx-ix)) ); tt[nx2-ix-1][iz] = tt[ix][iz]; } } } /* one-way ABC setup */ bzl=sf_floatalloc(nx2); bzh=sf_floatalloc(nx2); bxl=sf_floatalloc(nz2); bxh=sf_floatalloc(nz2); for (ix=0;ix<nx2;ix++) { dp = vp[ix][ nop ] *dt/dz; bzl[ix] = (1-dp)/(1+dp); dp = vp[ix][nz2-nop-1] *dt/dz; bzh[ix] = (1-dp)/(1+dp); } for (iz=0;iz<nz2;iz++) { dp = vp[ nop ][iz] *dt/dx; bxl[iz] = (1-dp)/(1+dp); dp = vp[nx2-nop-1][iz] *dt/dx; bxh[iz] = (1-dp)/(1+dp); } /*------------------------------------------------------------*/ /* * MAIN LOOP */ if(verb) fprintf(stderr,"\n"); for (it=0; it<nt; it++) { if(verb) fprintf(stderr,"\b\b\b\b\b%d",it); if(dens) { /* variable density */ #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,ompchunk) private(iz,ix) shared(nop,nx2,nz2,ud,uo,ro,co,c1x,c1z,c2x,c2z,idx,idz) #endif for( ix=nop; ix<nx2-nop; ix++) { for(iz=nop; iz<nz2-nop; iz++) { /* 4th order Laplacian operator */ ud[ix][iz] = co * uo[ix ][iz ] + c1x*(uo[ix-1][iz ] + uo[ix+1][iz ]) + c2x*(uo[ix-2][iz ] + uo[ix+2][iz ]) + c1z*(uo[ix ][iz-1] + uo[ix ][iz+1]) + c2z*(uo[ix ][iz-2] + uo[ix ][iz+2]); /* density terms */ ud[ix][iz] -= ( D1(uo,ix,iz,idz) * D1(ro,ix,iz,idz) + D2(uo,ix,iz,idx) * D2(ro,ix,iz,idx) ) / ro[ix][iz]; } } } else { /* constant density */ #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,ompchunk) private(iz,ix) shared(nop,nx2,nz2,ud,uo,co,c1x,c1z,c2x,c2z) #endif for( ix=nop; ix<nx2-nop; ix++) { for(iz=nop; iz<nz2-nop; iz++) { /* 4th order Laplacian operator */ ud[ix][iz] = co * uo[ix ][iz ] + c1x*(uo[ix-1][iz ] + uo[ix+1][iz ]) + c2x*(uo[ix-2][iz ] + uo[ix+2][iz ]) + c1z*(uo[ix ][iz-1] + uo[ix ][iz+1]) + c2z*(uo[ix ][iz-2] + uo[ix ][iz+2]); } } } /* inject wavelet */ for (is=0;is<ns;is++) { ws = ww[it] * ss[is].v; ud[ jxs[is] ][ jzs[is] ] -= ws * ws00[is]; ud[ jxs[is] ][ jzs[is]+1] -= ws * ws01[is]; ud[ jxs[is]+1][ jzs[is] ] -= ws * ws10[is]; ud[ jxs[is]+1][ jzs[is]+1] -= ws * ws11[is]; } #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,ompchunk) private(ix,iz) shared(nx2,nz2,ud,uo,um,up,vp,dt2) #endif for( ix=0; ix<nx2; ix++) { for(iz=0; iz<nz2; iz++) { /* time step and velocity scale*/ up[ix][iz] = 2*uo[ix][iz] - um[ix][iz] + ud[ix][iz] * vp[ix][iz] * dt2; } } /* circulate arrays */ ut=um; um=uo; uo=up; up=ut; /* one-way ABC apply */ if(abc) { #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,ompchunk) private(ix,iz,iop) shared(nx2,nz2,nop,uo,um,bzl,bzh) #endif for(ix=0;ix<nx2;ix++) { for(iop=0;iop<nop;iop++) { iz = nop-iop; uo [ix][iz ] = um[ix][iz+1] +(um[ix][iz ] - uo[ix][iz+1]) * bzl[ix]; iz = nz2-nop+iop-1; uo [ix][iz ] = um[ix][iz-1] +(um[ix][iz ] - uo[ix][iz-1]) * bzh[ix]; } } #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,1) private(ix,iz,iop) shared(nx2,nz2,nop,uo,um,bzl,bzh) #endif for(iop=0;iop<nop;iop++) { for(iz=0;iz<nz2;iz++) { ix = nop-iop; uo [ix ][iz] = um[ix+1][iz] +(um[ix ][iz] - uo[ix+1][iz]) * bxl[iz]; ix = nx2-nop+iop-1; uo [ix ][iz] = um[ix-1][iz] +(um[ix ][iz] - uo[ix-1][iz]) * bxh[iz]; } } } /* sponge ABC apply */ if(abc) { #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,ompchunk) private(ix,iz) shared(nx2,nz2,uo,um,ud,tt) #endif for( ix=0; ix<nx2; ix++) { for(iz=0; iz<nz2; iz++) { uo[ix][iz] *= tt[ix][iz]; um[ix][iz] *= tt[ix][iz]; ud[ix][iz] *= tt[ix][iz]; } } } /* write wavefield */ if(snap && it%jsnap==0) { sf_floatwrite(uo[0],nz2*nx2,Fu); } /* collect data */ #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,1) private(ir) shared(dd,rr,uo,jzr,wr00,wr01,wr10,wr11) #endif for (ir=0;ir<nr;ir++) { dd[ir] = uo[ jxr[ir] ][ jzr[ir] ] * wr00[ir] + uo[ jxr[ir] ][ jzr[ir]+1] * wr01[ir] + uo[ jxr[ir]+1][ jzr[ir] ] * wr10[ir] + uo[ jxr[ir]+1][ jzr[ir]+1] * wr11[ir]; dd[ir] *= rr[ir].v; } /* write data */ sf_floatwrite(dd,nr,Fd); } if(verb) fprintf(stderr,"\n"); exit (0); }
D2 GS() const {return D2(g.GS());}
inline void callFunction(mxArray* plhs[], const mxArray*prhs[], const long nlhs,const long nrhs) { if (!mexCheckType<T>(prhs[0])) mexErrMsgTxt("type of argument 1 is not consistent"); if (!mxIsStruct(prhs[1])) mexErrMsgTxt("argument 2 should be struct"); if (nrhs == 3) if (!mxIsStruct(prhs[2])) mexErrMsgTxt("argument 3 should be struct"); Data<T> *X; const mwSize* dimsX=mxGetDimensions(prhs[0]); long n=static_cast<long>(dimsX[0]); long M=static_cast<long>(dimsX[1]); if (mxIsSparse(prhs[0])) { double * X_v=static_cast<double*>(mxGetPr(prhs[0])); mwSize* X_r=mxGetIr(prhs[0]); mwSize* X_pB=mxGetJc(prhs[0]); mwSize* X_pE=X_pB+1; long* X_r2, *X_pB2, *X_pE2; T* X_v2; createCopySparse<T>(X_v2,X_r2,X_pB2,X_pE2, X_v,X_r,X_pB,X_pE,M); X = new SpMatrix<T>(X_v2,X_r2,X_pB2,X_pE2,n,M,X_pB2[M]); } else { T* prX = reinterpret_cast<T*>(mxGetPr(prhs[0])); X= new Matrix<T>(prX,n,M); } long NUM_THREADS = getScalarStructDef<long>(prhs[1],"numThreads",-1); #ifdef _OPENMP NUM_THREADS = NUM_THREADS == -1 ? omp_get_num_procs() : NUM_THREADS; #else NUM_THREADS=1; #endif long batch_size = getScalarStructDef<long>(prhs[1],"batchsize", 256*(NUM_THREADS+1)); mxArray* pr_D = mxGetField(prhs[1],0,"D"); Trainer<T>* trainer; if (!pr_D) { long K = getScalarStruct<long>(prhs[1],"K"); trainer = new Trainer<T>(K,batch_size,NUM_THREADS); } else { T* prD = reinterpret_cast<T*>(mxGetPr(pr_D)); const mwSize* dimsD=mxGetDimensions(pr_D); long nD=static_cast<long>(dimsD[0]); long K=static_cast<long>(dimsD[1]); if (n != nD) mexErrMsgTxt("sizes of D are not consistent"); Matrix<T> D1(prD,n,K); if (nrhs == 3) { mxArray* pr_A = mxGetField(prhs[2],0,"A"); if (!pr_A) mexErrMsgTxt("field A is not provided"); T* prA = reinterpret_cast<T*>(mxGetPr(pr_A)); const mwSize* dimsA=mxGetDimensions(pr_A); long xA=static_cast<long>(dimsA[0]); long yA=static_cast<long>(dimsA[1]); if (xA != K || yA != K) mexErrMsgTxt("Size of A is not consistent"); Matrix<T> A(prA,K,K); mxArray* pr_B = mxGetField(prhs[2],0,"B"); if (!pr_B) mexErrMsgTxt("field B is not provided"); T* prB = reinterpret_cast<T*>(mxGetPr(pr_B)); const mwSize* dimsB=mxGetDimensions(pr_B); long xB=static_cast<long>(dimsB[0]); long yB=static_cast<long>(dimsB[1]); if (xB != n || yB != K) mexErrMsgTxt("Size of B is not consistent"); Matrix<T> B(prB,n,K); long iter = getScalarStruct<long>(prhs[2],"iter"); trainer = new Trainer<T>(A,B,D1,iter,batch_size,NUM_THREADS); } else { trainer = new Trainer<T>(D1,batch_size,NUM_THREADS); } } ParamDictLearn<T> param; param.lambda = getScalarStruct<T>(prhs[1],"lambda"); param.lambda2 = getScalarStructDef<T>(prhs[1],"lambda2",10e-10); param.iter=getScalarStruct<long>(prhs[1],"iter"); param.t0 = getScalarStructDef<T>(prhs[1],"t0",1e-5); param.mode =(constraint_type)getScalarStructDef<long>(prhs[1],"mode",PENALTY); param.posAlpha = getScalarStructDef<bool>(prhs[1],"posAlpha",false); param.posD = getScalarStructDef<bool>(prhs[1],"posD",false); param.expand= getScalarStructDef<bool>(prhs[1],"expand",false); param.modeD=(constraint_type_D)getScalarStructDef<long>(prhs[1],"modeD",L2); param.whiten = getScalarStructDef<bool>(prhs[1],"whiten",false); param.clean = getScalarStructDef<bool>(prhs[1],"clean",true); param.verbose = getScalarStructDef<bool>(prhs[1],"verbose",true); param.gamma1 = getScalarStructDef<T>(prhs[1],"gamma1",0); param.gamma2 = getScalarStructDef<T>(prhs[1],"gamma2",0); param.rho = getScalarStructDef<T>(prhs[1],"rho",T(1.0)); param.stochastic = getScalarStructDef<bool>(prhs[1],"stochastic_deprecated", false); param.modeParam = static_cast<mode_compute>(getScalarStructDef<long>(prhs[1],"modeParam",0)); param.batch = getScalarStructDef<bool>(prhs[1],"batch",false); param.iter_updateD = getScalarStructDef<T>(prhs[1],"iter_updateD",param.batch ? 5 : 1); param.log = getScalarStructDef<bool>(prhs[1],"log_deprecated", false); if (param.log) { mxArray *stringData = mxGetField(prhs[1],0, "logName_deprecated"); if (!stringData) mexErrMsgTxt("Missing field logName_deprecated"); long stringLength = mxGetN(stringData)+1; param.logName= new char[stringLength]; mxGetString(stringData,param.logName,stringLength); } trainer->train(*X,param); if (param.log) mxFree(param.logName); Matrix<T> D; trainer->getD(D); long K = D.n(); plhs[0] = createMatrix<T>(n,K); T* prD2 = reinterpret_cast<T*>(mxGetPr(plhs[0])); Matrix<T> D2(prD2,n,K); D2.copy(D); if (nlhs == 2) { mwSize dims[1] = {1}; long nfields=3; const char *names[] = {"A", "B", "iter"}; plhs[1]=mxCreateStructArray(1, dims,nfields, names); mxArray* prA = createMatrix<T>(K,K); T* pr_A= reinterpret_cast<T*>(mxGetPr(prA)); Matrix<T> A(pr_A,K,K); trainer->getA(A); mxSetField(plhs[1],0,"A",prA); mxArray* prB = createMatrix<T>(n,K); T* pr_B= reinterpret_cast<T*>(mxGetPr(prB)); Matrix<T> B(pr_B,n,K); trainer->getB(B); mxSetField(plhs[1],0,"B",prB); mxArray* priter = createScalar<T>(); *mxGetPr(priter) = static_cast<T>(trainer->getIter()); mxSetField(plhs[1],0,"iter",priter); } delete(trainer); delete(X); }
/* * Switch ethernet frame when in layer 3 mode (i.e. using IP * layer to do the routing). * * There is a large amount of overlap between this function and * vsw_switch_l2_frame. At some stage we need to revisit and refactor * both these functions. */ void vsw_switch_l3_frame(vsw_t *vswp, mblk_t *mp, int caller, vsw_port_t *arg, mac_resource_handle_t mrh) { struct ether_header *ehp; mblk_t *bp = NULL; vsw_fdbe_t *fp; D1(vswp, "%s: enter (caller %d)", __func__, caller); /* * In layer 3 mode should only ever be switching packets * between IP layer and vnet devices. So make sure thats * who is invoking us. */ if ((caller != VSW_LOCALDEV) && (caller != VSW_VNETPORT)) { DERR(vswp, "%s: unexpected caller (%d)", __func__, caller); freemsgchain(mp); return; } /* process the chain of packets */ bp = mp; while (bp) { ehp = (struct ether_header *)bp->b_rptr; mp = vsw_get_same_dest_list(ehp, &bp); ASSERT(mp != NULL); D2(vswp, "%s: mblk data buffer %lld : actual data size %lld", __func__, MBLKSIZE(mp), MBLKL(mp)); /* * Find fdb entry for the destination * and hold a reference to it. */ fp = vsw_fdbe_find(vswp, &ehp->ether_dhost); if (fp != NULL) { D2(vswp, "%s: sending to target port", __func__); (void) vsw_portsend(fp->portp, mp); /* Release the reference on the fdb entry */ VSW_FDBE_REFRELE(fp); } else { /* * Destination not in FDB * * If the destination is broadcast or * multicast forward the packet to all * (VNETPORTs, PHYSDEV, LOCALDEV), * except the caller. */ if (IS_BROADCAST(ehp)) { D2(vswp, "%s: BROADCAST pkt", __func__); (void) vsw_forward_all(vswp, mp, caller, arg); } else if (IS_MULTICAST(ehp)) { D2(vswp, "%s: MULTICAST pkt", __func__); (void) vsw_forward_grp(vswp, mp, caller, arg); } else { /* * Unicast pkt from vnet that we don't have * an FDB entry for, so must be destinded for * the outside world. Attempt to send up to the * IP layer to allow it to deal with it. */ if (caller == VSW_VNETPORT) { vsw_mac_rx(vswp, mrh, mp, VSW_MACRX_FREEMSG); } } } } D1(vswp, "%s: exit", __func__); }
/* * Forward pkts to any devices or interfaces which have registered * an interest in them (i.e. multicast groups). */ static int vsw_forward_grp(vsw_t *vswp, mblk_t *mp, int caller, vsw_port_t *arg) { struct ether_header *ehp = (struct ether_header *)mp->b_rptr; mfdb_ent_t *entp = NULL; mfdb_ent_t *tpp = NULL; vsw_port_t *port; uint64_t key = 0; mblk_t *nmp = NULL; mblk_t *ret_m = NULL; boolean_t check_if = B_TRUE; /* * Convert address to hash table key */ KEY_HASH(key, &ehp->ether_dhost); D1(vswp, "%s: key 0x%llx", __func__, key); /* * If pkt came from either a vnet or down the stack (if we are * plumbed) and we are in layer 2 mode, then we send the pkt out * over the physical adapter, and then check to see if any other * vnets are interested in it. */ if ((vswp->smode & VSW_LAYER2) && ((caller == VSW_VNETPORT) || (caller == VSW_LOCALDEV))) { nmp = vsw_dupmsgchain(mp); if (nmp) { if ((ret_m = vsw_tx_msg(vswp, nmp, caller, arg)) != NULL) { DERR(vswp, "%s: dropping pkt(s) consisting of " "%ld bytes of data for physical device", __func__, MBLKL(ret_m)); freemsgchain(ret_m); } } } READ_ENTER(&vswp->mfdbrw); if (mod_hash_find(vswp->mfdb, (mod_hash_key_t)key, (mod_hash_val_t *)&entp) != 0) { D3(vswp, "%s: no table entry found for addr 0x%llx", __func__, key); } else { /* * Send to list of devices associated with this address... */ for (tpp = entp; tpp != NULL; tpp = tpp->nextp) { /* dont send to ourselves */ if ((caller == VSW_VNETPORT) && (tpp->d_addr == (void *)arg)) { port = (vsw_port_t *)tpp->d_addr; D3(vswp, "%s: not sending to ourselves" " : port %d", __func__, port->p_instance); continue; } else if ((caller == VSW_LOCALDEV) && (tpp->d_type == VSW_LOCALDEV)) { D2(vswp, "%s: not sending back up stack", __func__); continue; } if (tpp->d_type == VSW_VNETPORT) { port = (vsw_port_t *)tpp->d_addr; D3(vswp, "%s: sending to port %ld for addr " "0x%llx", __func__, port->p_instance, key); nmp = vsw_dupmsgchain(mp); if (nmp) { /* * The vswp->mfdbrw is protecting the * portp from getting destroyed here. * So, no ref_cnt is incremented here. */ (void) vsw_portsend(port, nmp); } } else { vsw_mac_rx(vswp, NULL, mp, VSW_MACRX_COPYMSG); D2(vswp, "%s: sending up stack" " for addr 0x%llx", __func__, key); check_if = B_FALSE; } } } RW_EXIT(&vswp->mfdbrw); /* * If the pkt came from either a vnet or from physical device, * and if we havent already sent the pkt up the stack then we * check now if we can/should (i.e. the interface is plumbed * and in promisc mode). */ if ((check_if) && ((caller == VSW_VNETPORT) || (caller == VSW_PHYSDEV))) { vsw_mac_rx(vswp, NULL, mp, VSW_MACRX_PROMISC | VSW_MACRX_COPYMSG); } freemsgchain(mp); D1(vswp, "%s: exit", __func__); return (0); }
/* * Program the macaddress and vlans of a port. * * Returns 0 on sucess, 1 on failure. */ static int vsw_set_port_hw_addr(vsw_port_t *port) { vsw_t *vswp = port->p_vswp; mac_diag_t diag; uint8_t *macaddr; uint16_t vid = VLAN_ID_NONE; int rv; uint16_t mac_flags = MAC_UNICAST_TAG_DISABLE | MAC_UNICAST_STRIP_DISABLE; D1(vswp, "%s: enter", __func__); ASSERT(RW_WRITE_HELD(&port->maccl_rwlock)); if (port->p_mch == NULL) return (0); /* * If the port has a specific 'pvid', then * register with that vlan-id, otherwise register * with VLAN_ID_NONE. */ if (port->pvid != vswp->default_vlan_id) { vid = port->pvid; } macaddr = (uint8_t *)port->p_macaddr.ether_addr_octet; if (!(vswp->smode & VSW_LAYER2_PROMISC)) { mac_flags |= MAC_UNICAST_HW; } if (port->addr_set == B_FALSE) { port->p_muh = NULL; rv = mac_unicast_add(port->p_mch, macaddr, mac_flags, &port->p_muh, vid, &diag); if (rv != 0) { cmn_err(CE_WARN, "vsw%d: Failed to program" "macaddr,vid(%s, %d) err=%d", vswp->instance, ether_sprintf((void *)macaddr), vid, rv); return (rv); } port->addr_set = B_TRUE; D2(vswp, "%s:programmed macaddr(%s) vid(%d) into device %s", __func__, ether_sprintf((void *)macaddr), vid, vswp->physname); } /* Add vlans to the MAC layer */ vsw_mac_add_vlans(vswp, port->p_mch, macaddr, mac_flags, port->vids, port->nvids); /* Configure bandwidth to the MAC layer */ vsw_maccl_set_bandwidth(NULL, port, VSW_VNETPORT, port->p_bandwidth); mac_rx_set(port->p_mch, vsw_port_rx_cb, (void *)port); D1(vswp, "%s: exit", __func__); return (rv); }
/* * Remove a multicast entry from the hashtable. * * Search hash table based on address. If match found, scan * list of ports associated with address. If specified port * found remove it from list. */ int vsw_del_mcst(vsw_t *vswp, uint8_t devtype, uint64_t addr, void *arg) { mfdb_ent_t *ment = NULL; mfdb_ent_t *curr_p, *prev_p; void *tgt = NULL; D1(vswp, "%s: enter", __func__); if (devtype == VSW_VNETPORT) { tgt = (vsw_port_t *)arg; D2(vswp, "%s: removing port %d from mFDB for address" " 0x%llx", __func__, ((vsw_port_t *)tgt)->p_instance, addr); } else { D2(vswp, "%s: removing entry", __func__); tgt = (void *)vswp; } WRITE_ENTER(&vswp->mfdbrw); if (mod_hash_find(vswp->mfdb, (mod_hash_key_t)addr, (mod_hash_val_t *)&ment) != 0) { D2(vswp, "%s: address 0x%llx not in table", __func__, addr); RW_EXIT(&vswp->mfdbrw); return (1); } prev_p = curr_p = ment; while (curr_p != NULL) { if (curr_p->d_addr == (void *)tgt) { if (devtype == VSW_VNETPORT) { D2(vswp, "%s: port %d found", __func__, ((vsw_port_t *)tgt)->p_instance); } else { D2(vswp, "%s: instance found", __func__); } if (prev_p == curr_p) { /* * head of list, if no other element is in * list then destroy this entry, otherwise * just replace it with updated value. */ ment = curr_p->nextp; if (ment == NULL) { (void) mod_hash_destroy(vswp->mfdb, (mod_hash_val_t)addr); } else { (void) mod_hash_replace(vswp->mfdb, (mod_hash_key_t)addr, (mod_hash_val_t)ment); } } else { /* * Not head of list, no need to do * replacement, just adjust list pointers. */ prev_p->nextp = curr_p->nextp; } break; } prev_p = curr_p; curr_p = curr_p->nextp; } RW_EXIT(&vswp->mfdbrw); D1(vswp, "%s: exit", __func__); if (curr_p == NULL) return (1); kmem_free(curr_p, sizeof (mfdb_ent_t)); return (0); }
void test() { cout << " zDate Class Demo \n\n"; // default constructor, Jan 1 0000 zDate a; cout << a << endl; // Various versions of the constructors zDate x(zDate::oct,20,1962); cout << x << endl; // constructor with a julian zDate z( 2450000L ); cout << z << endl; // make a date with system date (tests copy constructor) zDate s(zDate::Today()); cout << s << endl; // init with the day of year zDate y(33, 1996); cout << y << endl; // init from current system time time_t secs_now = time(NULL); zDate n(localtime(&secs_now)); cout << n << endl; // using date addition and subtraction zDate adder = x + 10; cout << adder << endl; adder = adder - 25; cout << adder << endl; //using subtraction of two date objects zDate a1(zDate::Today()); zDate a2 = a1 + 14; cout << (a1 - a2) << endl; cout << (a2 += 10) << endl; a1++; cout << "Tommorrow= " << a1 << endl; a1 = zDate(zDate::jul, 14, 1991); cout << "a1 (7-14-91) < a2 (" << a2 << ")? ==> " << ((a1 < a2) ? "TRUE" : "FALSE") << endl; cout << "a1 (7-14-91) > a2 ("<< a2 << ")? ==> " << ((a1 > a2) ? "TRUE" : "FALSE") << endl; cout << "a1 (7-14-91) < 8-01-91 ? ==> " << ((a1 < zDate(zDate::aug, 1, 1991)) ? "TRUE" : "FALSE") << endl; cout << "a1 (7-14-91) > 8-01-91 ? ==> " << ((a1 > zDate(zDate::aug, 1, 1991)) ? "TRUE" : "FALSE") << endl; cout << "a1 (7-14-91) == 7-14-91 ? ==> " << ((a1==zDate(zDate::jul, 14, 1991)) ? "TRUE" : "FALSE") << endl; zDate a3 = a1; cout << "a1 (" << a1 << ") == a3 (" << a3 << ") ? ==> " << ((a1==a3) ? "TRUE" : "FALSE") << endl; zDate a4 = a1; ++a4; cout << "a1 ("<< a1 <<") == a4 (" << a4 << ") ? ==> " << ((a1==a4) ? "TRUE" : "FALSE") << endl; zDate a5(zDate::Today()); cout << "Today is: " << a5 << endl; a4 = zDate::Today(); cout << "Today (a4) is: " << a4 << endl; cout << "Today + 4 is: " << (a4 += 4) << endl; a4 = zDate::Today(); cout << "Today - 4 is: " << (a4 -= 4) << endl; cout << "=========== Leap Year Test ===========\n"; a1 = zDate(zDate::jan, 15, 1992); cout << a1 << "\t" << ((a1.IsLeapYear()) ? "Leap" : "non-Leap"); cout << "\t" << "day of year: " << a1.DayOfYear() << endl; a1 = zDate(zDate::feb, 16, 1993); cout << a1 << "\t" << ((a1.IsLeapYear()) ? "Leap" : "non-Leap"); cout << "\t" << "day of year: " << a1.DayOfYear() << endl; zDate v4(zDate::Today()); cout << "---------- Add Stuff -----------\n"; cout << "Start => " << v4 << endl; cout << "Add 4 Weeks => " << v4.AddWeeks(4) << endl; cout << "Sub 52 Weeks => " << v4.AddWeeks(-52) << endl; cout << "Add 2 Years => " << v4.AddYears(2) << endl; cout << flush; cout << "---------- Misc Stuff -----------\n"; cout << "The date aboves' day of the month is => " << v4.Day() << endl; cout << "There are " << v4.DaysInMonth() << " days in this month.\n"; cout << "This day happens to be " << v4.DayOfWeek() << " day of week" << endl; cout << "on the " << v4.WeekOfYear() << " week of the year," << endl; cout << "on the " << v4.WeekOfMonth() << " week of the month, " << endl; cout << "which is the "<< (int)v4.Month() << "nth month in the year.\n"; cout << "The year alone is " << v4.Year() << endl; cout << "And this is the " << v4.DayOfYear() << " day of year" << endl; cout << "of a year with " << v4.DaysInYear() << " days in it" << endl; cout << "which makes exatcly " << v4.WeeksInYear() << " weeks" << endl; zDate birthday(zDate::jul, 16, 1973); cout << "The age test: i was born on " << birthday << " which makes me " << v4.Age(birthday) << " years old" << endl; zDate D2(zDate::jul, 4, 1776); int I1 = 4; cout << "Before: I1 = " << I1 << ", D2 = " << D2 << endl; cout << "---------- Postfix '++' test -----------\n"; cout << "Test : I1++ = " << I1++ << ", D2++ = " << D2++ << endl; cout << "After: I1 = " << I1 << ", D2 = " << D2 << endl; cout << "---------- Prefix '++' test -----------\n"; cout << "Test : ++I1 = " << ++I1 << ", ++D2 = " << ++D2 << endl; cout << "After: I1 = " << I1 << ", D2 = " << D2 << endl; cout << "---------- Postfix '--' test -----------\n"; cout << "Test : I1-- = " << I1-- << ", D2-- = " << D2-- << endl; cout << "After: I1 = " << I1 << ", D2 = " << D2 << endl; cout << "---------- Prefix '--' test -----------\n"; cout << "Test : --I1 = " << --I1 << ", --D2 = " << --D2 << endl; cout << "After: I1 = " << I1 << ", D2 = " << D2 << endl; cout << "Last day of this year is dayno " << zDate(zDate::dec, 31, 1996).DayOfYear() << endl; cout << "Last day of prev year is dayno " << zDate(zDate::dec, 31, 1995).DayOfYear() << endl; cout << "Today the moon is " << zDate::Today().MoonPhase() << endl; zDate today = zDate::Today(); cout << "DST for " << today.Year() << " starts on " << today.BeginDST() << " and ends on " << today.EndDST() << endl; cout << "Today, " << today << ", DST is " << (today.IsDST() ? "" : "not") << "in effect" << endl; zDate date1(zDate::aug, 31, 1996); cout << "Adding 6 months to " << date1 << " results in " << date1.AddMonths(6) << endl; zDate date2(zDate::mar, 31, 1996); cout << "Subtracting 1 month from " << date2 << " results in " << date2.AddMonths(-1) << endl; zDate date3(zDate::jul, 4, 1776); cout << "Adding 2400 months to " << date3 << " results in " << date3.AddMonths(2400) << endl; cout << "Today's day number is " << zDate::Today().DayNumber() << endl; zDate date4(zDate::feb, 29, 1996); cout << date4 << " subtract two years = " << date4.AddYears(-2) << endl; cout << "In 1996, DST began on " << zDate::BeginDST(1996) << endl; zDate date5(zDate::sep, 26, 1996); cout << "Moon phase on " << date5 << " was " << date5.MoonPhase() << endl; zDate date6(zDate::oct, 3, 1996); cout << date6 << " + 55 days is " << (date6 + 55) << endl; zDate date7(zDate::oct, 4, 1996); cout << date7 << " + 217 days is "; date7 += 217; cout << date7 << endl; date7 = zDate(zDate::oct, 4, 1996); cout << "Same date - (-217) days is "; date7 -= -217; cout << date7 << endl; cout << "For 1996, Easter is on " << zDate::Easter(1996) << endl; }
void Render::addContainer() { glm::vec3 A1(0.0f, 0.0f, 0.0f); glm::vec3 B1(1.0f, 0.0f, 0.0f); glm::vec3 C1(1.0f, 0.0f, 1.0f); glm::vec3 D1(0.0f, 0.0f, 1.0f); glm::vec3 A2(0.0f, 1.0f, 0.0f); glm::vec3 B2(1.0f, 1.0f, 0.0f); glm::vec3 C2(1.0f, 1.0f, 1.0f); glm::vec3 D2(0.0f, 1.0f, 1.0f); glm::vec3 normal(0.0f, 0.0f, 0.0f); vertices.push_back(A1); normals.push_back(normal); vertices.push_back(B1); normals.push_back(normal); vertices.push_back(A1); normals.push_back(normal); vertices.push_back(D1); normals.push_back(normal); vertices.push_back(B1); normals.push_back(normal); vertices.push_back(C1); normals.push_back(normal); vertices.push_back(D1); normals.push_back(normal); vertices.push_back(C1); normals.push_back(normal); vertices.push_back(A2); normals.push_back(normal); vertices.push_back(B2); normals.push_back(normal); vertices.push_back(A2); normals.push_back(normal); vertices.push_back(D2); normals.push_back(normal); vertices.push_back(B2); normals.push_back(normal); vertices.push_back(C2); normals.push_back(normal); vertices.push_back(D2); normals.push_back(normal); vertices.push_back(C2); normals.push_back(normal); vertices.push_back(A1); normals.push_back(normal); vertices.push_back(A2); normals.push_back(normal); vertices.push_back(B1); normals.push_back(normal); vertices.push_back(B2); normals.push_back(normal); vertices.push_back(C1); normals.push_back(normal); vertices.push_back(C2); normals.push_back(normal); vertices.push_back(D1); normals.push_back(normal); vertices.push_back(D2); normals.push_back(normal); }
void Trr2kNNTN ( UpperOrLower uplo, Orientation orientationOfC, T alpha, const DistMatrix<T>& A, const DistMatrix<T>& B, const DistMatrix<T>& C, const DistMatrix<T>& D, T beta, DistMatrix<T>& E ) { #ifndef RELEASE CallStackEntry entry("internal::Trr2kNNTN"); if( E.Height() != E.Width() || A.Width() != C.Height() || A.Height() != E.Height() || C.Width() != E.Height() || B.Width() != E.Width() || D.Width() != E.Width() || A.Width() != B.Height() || C.Height() != D.Height() ) throw std::logic_error("Nonconformal Trr2kNNTN"); #endif const Grid& g = E.Grid(); DistMatrix<T> AL(g), AR(g), A0(g), A1(g), A2(g); DistMatrix<T> BT(g), B0(g), BB(g), B1(g), B2(g); DistMatrix<T> CT(g), C0(g), CB(g), C1(g), C2(g); DistMatrix<T> DT(g), D0(g), DB(g), D1(g), D2(g); DistMatrix<T,MC, STAR> A1_MC_STAR(g); DistMatrix<T,MR, STAR> B1Trans_MR_STAR(g); DistMatrix<T,STAR,MC > C1_STAR_MC(g); DistMatrix<T,MR, STAR> D1Trans_MR_STAR(g); A1_MC_STAR.AlignWith( E ); B1Trans_MR_STAR.AlignWith( E ); C1_STAR_MC.AlignWith( E ); D1Trans_MR_STAR.AlignWith( E ); LockedPartitionRight( A, AL, AR, 0 ); LockedPartitionDown ( B, BT, BB, 0 ); LockedPartitionDown ( C, CT, CB, 0 ); LockedPartitionDown ( D, DT, DB, 0 ); while( AL.Width() < A.Width() ) { LockedRepartitionRight ( AL, /**/ AR, A0, /**/ A1, A2 ); LockedRepartitionDown ( BT, B0, /**/ /**/ B1, BB, B2 ); LockedRepartitionDown ( CT, C0, /**/ /**/ C1, CB, C2 ); LockedRepartitionDown ( DT, D0, /**/ /**/ D1, DB, D2 ); //--------------------------------------------------------------------// A1_MC_STAR = A1; C1_STAR_MC = C1; B1Trans_MR_STAR.TransposeFrom( B1 ); D1Trans_MR_STAR.TransposeFrom( D1 ); LocalTrr2k ( uplo, TRANSPOSE, orientationOfC, TRANSPOSE, alpha, A1_MC_STAR, B1Trans_MR_STAR, C1_STAR_MC, D1Trans_MR_STAR, beta, E ); //--------------------------------------------------------------------// SlideLockedPartitionDown ( DT, D0, D1, /**/ /**/ DB, D2 ); SlideLockedPartitionDown ( CT, C0, C1, /**/ /**/ CB, C2 ); SlideLockedPartitionDown ( BT, B0, B1, /**/ /**/ BB, B2 ); SlideLockedPartitionRight ( AL, /**/ AR, A0, A1, /**/ A2 ); } }
TEST_F(fisheyeTest, stereoCalibrateFixIntrinsic) { const int n_images = 34; const std::string folder =combine(datasets_repository_path, "calib-3_stereo_from_JY"); std::vector<std::vector<cv::Point2d> > leftPoints(n_images); std::vector<std::vector<cv::Point2d> > rightPoints(n_images); std::vector<std::vector<cv::Point3d> > objectPoints(n_images); cv::FileStorage fs_left(combine(folder, "left.xml"), cv::FileStorage::READ); CV_Assert(fs_left.isOpened()); for(int i = 0; i < n_images; ++i) fs_left[cv::format("image_%d", i )] >> leftPoints[i]; fs_left.release(); cv::FileStorage fs_right(combine(folder, "right.xml"), cv::FileStorage::READ); CV_Assert(fs_right.isOpened()); for(int i = 0; i < n_images; ++i) fs_right[cv::format("image_%d", i )] >> rightPoints[i]; fs_right.release(); cv::FileStorage fs_object(combine(folder, "object.xml"), cv::FileStorage::READ); CV_Assert(fs_object.isOpened()); for(int i = 0; i < n_images; ++i) fs_object[cv::format("image_%d", i )] >> objectPoints[i]; fs_object.release(); cv::Matx33d R; cv::Vec3d T; int flag = 0; flag |= cv::fisheye::CALIB_RECOMPUTE_EXTRINSIC; flag |= cv::fisheye::CALIB_CHECK_COND; flag |= cv::fisheye::CALIB_FIX_SKEW; flag |= cv::fisheye::CALIB_FIX_INTRINSIC; cv::Matx33d K1 (561.195925927249, 0, 621.282400272412, 0, 562.849402029712, 380.555455380889, 0, 0, 1); cv::Matx33d K2 (560.395452535348, 0, 678.971652040359, 0, 561.90171021422, 380.401340535339, 0, 0, 1); cv::Vec4d D1 (-7.44253716539556e-05, -0.00702662033932424, 0.00737569823650885, -0.00342230256441771); cv::Vec4d D2 (-0.0130785435677431, 0.0284434505383497, -0.0360333869900506, 0.0144724062347222); cv::fisheye::stereoCalibrate(objectPoints, leftPoints, rightPoints, K1, D1, K2, D2, imageSize, R, T, flag, cv::TermCriteria(3, 12, 0)); cv::Matx33d R_correct( 0.9975587205950972, 0.06953016383322372, 0.006492709911733523, -0.06956823121068059, 0.9975601387249519, 0.005833595226966235, -0.006071257768382089, -0.006271040135405457, 0.9999619062167968); cv::Vec3d T_correct(-0.099402724724121, 0.00270812139265413, 0.00129330292472699); EXPECT_MAT_NEAR(R, R_correct, 1e-10); EXPECT_MAT_NEAR(T, T_correct, 1e-10); }
int main(void){ // hier komt de test /* int i = 0, j; char letter = 'a'; char buffer[3]; std::string* hulp; for(; i < h_nodes; i++){ for(j = 0; j < v_nodes; j++){ sprintf(buffer, "%c%d" , letter, j); hulp = new std::string(buffer); new Node(*hulp); delete hulp; } letter++; if(letter > 'z'){ letter = 'a'; } } printf("%p\n", Node::getParticularNode(std::string("a1"))); Node::getParticularNode(std::string("a1"))->print(); printf("%p\n", Node::getParticularNode(std::string("b1"))); Node::getParticularNode(std::string("b1"))->print(); Node::deleteAllNodes(); printf("%p\n", Node::getParticularNode(std::string("a1"))); Node::getParticularNode(std::string("a1"))->print(); */ Node A1("A1"); A1.addNeighbournode("B1", 4); A1.addNeighbournode("B2", 2); Node B1("B1"); B1.addNeighbournode("C1", 2); Node B2("B2"); B2.addNeighbournode("C3", 1); B2.setState(nodeUsed); Node C1("C1"); C1.addNeighbournode("D1", 1); Node C2("C2"); C2.addNeighbournode("D2", 3); C2.addNeighbournode("D3", 6); Node C3("C3"); C3.addNeighbournode("C2", 1); C3.addNeighbournode("D4", 3); Node D1("D1"); D1.addNeighbournode("D2", 9); Node D2("D2"); D2.addNeighbournode("D1", 9); D2.addNeighbournode("C2", 3); Node D3("D3"); D3.addNeighbournode("D4", 2); Node D4("D4"); D4.addNeighbournode("D3", 2); dijkstra planner; planner.calculateRoute(&A1, &D4); planner.printpath(); return 0; }
/* * Add or remove multicast address(es). * * Returns 0 on success, 1 on failure. */ int vsw_add_rem_mcst(vnet_mcast_msg_t *mcst_pkt, vsw_port_t *port) { mcst_addr_t *mcst_p = NULL; vsw_t *vswp = port->p_vswp; uint64_t addr = 0x0; int i; D1(vswp, "%s: enter", __func__); D2(vswp, "%s: %d addresses", __func__, mcst_pkt->count); for (i = 0; i < mcst_pkt->count; i++) { /* * Convert address into form that can be used * as hash table key. */ KEY_HASH(addr, &(mcst_pkt->mca[i])); /* * Add or delete the specified address/port combination. */ if (mcst_pkt->set == 0x1) { D3(vswp, "%s: adding multicast address 0x%llx for " "port %ld", __func__, addr, port->p_instance); if (vsw_add_mcst(vswp, VSW_VNETPORT, addr, port) == 0) { /* * Update the list of multicast * addresses contained within the * port structure to include this new * one. */ mcst_p = kmem_zalloc(sizeof (mcst_addr_t), KM_NOSLEEP); if (mcst_p == NULL) { DERR(vswp, "%s: unable to alloc mem", __func__); (void) vsw_del_mcst(vswp, VSW_VNETPORT, addr, port); return (1); } mcst_p->nextp = NULL; mcst_p->addr = addr; ether_copy(&mcst_pkt->mca[i], &mcst_p->mca); /* * Program the address into HW. If the addr * has already been programmed then the MAC * just increments a ref counter (which is * used when the address is being deleted) */ if (vsw_mac_multicast_add(vswp, port, mcst_p, VSW_VNETPORT)) { (void) vsw_del_mcst(vswp, VSW_VNETPORT, addr, port); kmem_free(mcst_p, sizeof (*mcst_p)); return (1); } mutex_enter(&port->mca_lock); mcst_p->nextp = port->mcap; port->mcap = mcst_p; mutex_exit(&port->mca_lock); } else { DERR(vswp, "%s: error adding multicast " "address 0x%llx for port %ld", __func__, addr, port->p_instance); return (1); } } else { /* * Delete an entry from the multicast hash * table and update the address list * appropriately. */ if (vsw_del_mcst(vswp, VSW_VNETPORT, addr, port) == 0) { D3(vswp, "%s: deleting multicast address " "0x%llx for port %ld", __func__, addr, port->p_instance); mcst_p = vsw_del_addr(VSW_VNETPORT, port, addr); ASSERT(mcst_p != NULL); /* * Remove the address from HW. The address * will actually only be removed once the ref * count within the MAC layer has dropped to * zero. I.e. we can safely call this fn even * if other ports are interested in this * address. */ vsw_mac_multicast_remove(vswp, port, mcst_p, VSW_VNETPORT); kmem_free(mcst_p, sizeof (*mcst_p)); } else { DERR(vswp, "%s: error deleting multicast " "addr 0x%llx for port %ld", __func__, addr, port->p_instance); return (1); } } } D1(vswp, "%s: exit", __func__); return (0); }
/* * Program the macaddress and vlans of a port. * * Returns 0 on sucess, 1 on failure. */ static int vsw_set_if_hw_addr(vsw_t *vswp) { mac_diag_t diag; uint8_t *macaddr; uint8_t primary_addr[ETHERADDRL]; uint16_t vid = VLAN_ID_NONE; int rv; uint16_t mac_flags = MAC_UNICAST_TAG_DISABLE | MAC_UNICAST_STRIP_DISABLE; D1(vswp, "%s: enter", __func__); ASSERT(RW_WRITE_HELD(&vswp->maccl_rwlock)); if (vswp->mch == NULL) return (0); macaddr = (uint8_t *)vswp->if_addr.ether_addr_octet; /* check if it is the primary macaddr of the card. */ mac_unicast_primary_get(vswp->mh, primary_addr); if (ether_cmp((void *)primary_addr, (void*)macaddr) == 0) { mac_flags |= MAC_UNICAST_PRIMARY; } /* * If the interface has a specific 'pvid', then * register with that vlan-id, otherwise register * with VLAN_ID_NONE. */ if (vswp->pvid != vswp->default_vlan_id) { vid = vswp->pvid; } if (!(vswp->smode & VSW_LAYER2_PROMISC)) { mac_flags |= MAC_UNICAST_HW; } if (vswp->addr_set == B_FALSE) { vswp->muh = NULL; rv = mac_unicast_add(vswp->mch, macaddr, mac_flags, &vswp->muh, vid, &diag); if (rv != 0) { cmn_err(CE_WARN, "vsw%d: Failed to program" "macaddr,vid(%s, %d) err=%d", vswp->instance, ether_sprintf((void *)macaddr), vid, rv); return (rv); } vswp->addr_set = B_TRUE; D2(vswp, "%s:programmed macaddr(%s) vid(%d) into device %s", __func__, ether_sprintf((void *)macaddr), vid, vswp->physname); } vsw_mac_add_vlans(vswp, vswp->mch, macaddr, mac_flags, vswp->vids, vswp->nvids); vsw_maccl_set_bandwidth(vswp, NULL, VSW_LOCALDEV, vswp->bandwidth); mac_rx_set(vswp->mch, vsw_if_rx_cb, (void *)vswp); D1(vswp, "%s: exit", __func__); return (rv); }
/* * Add a new multicast entry. * * Search hash table based on address. If match found then * update associated val (which is chain of ports), otherwise * create new key/val (addr/port) pair and insert into table. */ int vsw_add_mcst(vsw_t *vswp, uint8_t devtype, uint64_t addr, void *arg) { int dup = 0; int rv = 0; mfdb_ent_t *ment = NULL; mfdb_ent_t *tmp_ent = NULL; mfdb_ent_t *new_ent = NULL; void *tgt = NULL; if (devtype == VSW_VNETPORT) { /* * Being invoked from a vnet. */ ASSERT(arg != NULL); tgt = arg; D2(NULL, "%s: port %d : address 0x%llx", __func__, ((vsw_port_t *)arg)->p_instance, addr); } else { /* * We are being invoked via the m_multicst mac entry * point. */ D2(NULL, "%s: address 0x%llx", __func__, addr); tgt = (void *)vswp; } WRITE_ENTER(&vswp->mfdbrw); if (mod_hash_find(vswp->mfdb, (mod_hash_key_t)addr, (mod_hash_val_t *)&ment) != 0) { /* address not currently in table */ ment = kmem_alloc(sizeof (mfdb_ent_t), KM_SLEEP); ment->d_addr = (void *)tgt; ment->d_type = devtype; ment->nextp = NULL; if (mod_hash_insert(vswp->mfdb, (mod_hash_key_t)addr, (mod_hash_val_t)ment) != 0) { DERR(vswp, "%s: hash table insertion failed", __func__); kmem_free(ment, sizeof (mfdb_ent_t)); rv = 1; } else { D2(vswp, "%s: added initial entry for 0x%llx to " "table", __func__, addr); } } else { /* * Address in table. Check to see if specified port * is already associated with the address. If not add * it now. */ tmp_ent = ment; while (tmp_ent != NULL) { if (tmp_ent->d_addr == (void *)tgt) { if (devtype == VSW_VNETPORT) { DERR(vswp, "%s: duplicate port entry " "found for portid %ld and key " "0x%llx", __func__, ((vsw_port_t *)arg)->p_instance, addr); } else { DERR(vswp, "%s: duplicate entry found" "for key 0x%llx", __func__, addr); } rv = 1; dup = 1; break; } tmp_ent = tmp_ent->nextp; } /* * Port not on list so add it to end now. */ if (0 == dup) { D2(vswp, "%s: added entry for 0x%llx to table", __func__, addr); new_ent = kmem_alloc(sizeof (mfdb_ent_t), KM_SLEEP); new_ent->d_addr = (void *)tgt; new_ent->d_type = devtype; new_ent->nextp = NULL; tmp_ent = ment; while (tmp_ent->nextp != NULL) tmp_ent = tmp_ent->nextp; tmp_ent->nextp = new_ent; } } RW_EXIT(&vswp->mfdbrw); return (rv); }
int jffs2_do_readpage_nolock (struct inode *inode, struct page *pg) { struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); struct jffs2_node_frag *frag = f->fraglist; __u32 offset = pg->index << PAGE_CACHE_SHIFT; __u32 end = offset + PAGE_CACHE_SIZE; unsigned char *pg_buf; int ret; D1(printk(KERN_DEBUG "jffs2_do_readpage_nolock(): ino #%lu, page at offset 0x%x\n", inode->i_ino, offset)); if (!PageLocked(pg)) PAGE_BUG(pg); while(frag && frag->ofs + frag->size <= offset) { // D1(printk(KERN_DEBUG "skipping frag %d-%d; before the region we care about\n", frag->ofs, frag->ofs + frag->size)); frag = frag->next; } pg_buf = kmap(pg); /* XXX FIXME: Where a single physical node actually shows up in two frags, we read it twice. Don't do that. */ /* Now we're pointing at the first frag which overlaps our page */ while(offset < end) { D2(printk(KERN_DEBUG "jffs2_readpage: offset %d, end %d\n", offset, end)); if (!frag || frag->ofs > offset) { __u32 holesize = end - offset; if (frag) { D1(printk(KERN_NOTICE "Eep. Hole in ino %ld fraglist. frag->ofs = 0x%08x, offset = 0x%08x\n", inode->i_ino, frag->ofs, offset)); holesize = min(holesize, frag->ofs - offset); D1(jffs2_print_frag_list(f)); } D1(printk(KERN_DEBUG "Filling non-frag hole from %d-%d\n", offset, offset+holesize)); memset(pg_buf, 0, holesize); pg_buf += holesize; offset += holesize; continue; } else if (frag->ofs < offset && (offset & (PAGE_CACHE_SIZE-1)) != 0) { D1(printk(KERN_NOTICE "Eep. Overlap in ino #%ld fraglist. frag->ofs = 0x%08x, offset = 0x%08x\n", inode->i_ino, frag->ofs, offset)); D1(jffs2_print_frag_list(f)); memset(pg_buf, 0, end - offset); ClearPageUptodate(pg); SetPageError(pg); kunmap(pg); return -EIO; } else if (!frag->node) { __u32 holeend = min(end, frag->ofs + frag->size); D1(printk(KERN_DEBUG "Filling frag hole from %d-%d (frag 0x%x 0x%x)\n", offset, holeend, frag->ofs, frag->ofs + frag->size)); memset(pg_buf, 0, holeend - offset); pg_buf += holeend - offset; offset = holeend; frag = frag->next; continue; } else { __u32 readlen; __u32 fragofs; /* offset within the frag to start reading */ fragofs = offset - frag->ofs; readlen = min(frag->size - fragofs, end - offset); D1(printk(KERN_DEBUG "Reading %d-%d from node at 0x%x\n", frag->ofs+fragofs, fragofs+frag->ofs+readlen, frag->node->raw->flash_offset & ~3)); ret = jffs2_read_dnode(c, frag->node, pg_buf, fragofs + frag->ofs - frag->node->ofs, readlen); D2(printk(KERN_DEBUG "node read done\n")); if (ret) { D1(printk(KERN_DEBUG"jffs2_readpage error %d\n",ret)); memset(pg_buf, 0, readlen); ClearPageUptodate(pg); SetPageError(pg); kunmap(pg); return ret; } pg_buf += readlen; offset += readlen; frag = frag->next; D2(printk(KERN_DEBUG "node read was OK. Looping\n")); } } D2(printk(KERN_DEBUG "readpage finishing\n")); SetPageUptodate(pg); ClearPageError(pg); flush_dcache_page(pg); kunmap(pg); D1(printk(KERN_DEBUG "readpage finished\n")); return 0; }
/* * Switch the given ethernet frame when operating in layer 2 mode. * * vswp: pointer to the vsw instance * mp: pointer to chain of ethernet frame(s) to be switched * caller: identifies the source of this frame as: * 1. VSW_VNETPORT - a vsw port (connected to a vnet). * 2. VSW_PHYSDEV - the physical ethernet device * 3. VSW_LOCALDEV - vsw configured as a virtual interface * arg: argument provided by the caller. * 1. for VNETPORT - pointer to the corresponding vsw_port_t. * 2. for PHYSDEV - NULL * 3. for LOCALDEV - pointer to to this vsw_t(self) */ void vsw_switch_l2_frame(vsw_t *vswp, mblk_t *mp, int caller, vsw_port_t *arg, mac_resource_handle_t mrh) { struct ether_header *ehp; mblk_t *bp, *ret_m; vsw_fdbe_t *fp; D1(vswp, "%s: enter (caller %d)", __func__, caller); /* * PERF: rather than breaking up the chain here, scan it * to find all mblks heading to same destination and then * pass that sub-chain to the lower transmit functions. */ /* process the chain of packets */ bp = mp; while (bp) { ehp = (struct ether_header *)bp->b_rptr; mp = vsw_get_same_dest_list(ehp, &bp); ASSERT(mp != NULL); D2(vswp, "%s: mblk data buffer %lld : actual data size %lld", __func__, MBLKSIZE(mp), MBLKL(mp)); if (ether_cmp(&ehp->ether_dhost, &vswp->if_addr) == 0) { /* * If destination is VSW_LOCALDEV (vsw as an eth * interface) and if the device is up & running, * send the packet up the stack on this host. * If the virtual interface is down, drop the packet. */ if (caller != VSW_LOCALDEV) { vsw_mac_rx(vswp, mrh, mp, VSW_MACRX_FREEMSG); } else { freemsgchain(mp); } continue; } /* * Find fdb entry for the destination * and hold a reference to it. */ fp = vsw_fdbe_find(vswp, &ehp->ether_dhost); if (fp != NULL) { /* * If plumbed and in promisc mode then copy msg * and send up the stack. */ vsw_mac_rx(vswp, mrh, mp, VSW_MACRX_PROMISC | VSW_MACRX_COPYMSG); /* * If the destination is in FDB, the packet * should be forwarded to the correponding * vsw_port (connected to a vnet device - * VSW_VNETPORT) */ (void) vsw_portsend(fp->portp, mp); /* Release the reference on the fdb entry */ VSW_FDBE_REFRELE(fp); } else { /* * Destination not in FDB. * * If the destination is broadcast or * multicast forward the packet to all * (VNETPORTs, PHYSDEV, LOCALDEV), * except the caller. */ if (IS_BROADCAST(ehp)) { D2(vswp, "%s: BROADCAST pkt", __func__); (void) vsw_forward_all(vswp, mp, caller, arg); } else if (IS_MULTICAST(ehp)) { D2(vswp, "%s: MULTICAST pkt", __func__); (void) vsw_forward_grp(vswp, mp, caller, arg); } else { /* * If the destination is unicast, and came * from either a logical network device or * the switch itself when it is plumbed, then * send it out on the physical device and also * up the stack if the logical interface is * in promiscious mode. * * NOTE: The assumption here is that if we * cannot find the destination in our fdb, its * a unicast address, and came from either a * vnet or down the stack (when plumbed) it * must be destinded for an ethernet device * outside our ldoms. */ if (caller == VSW_VNETPORT) { /* promisc check copy etc */ vsw_mac_rx(vswp, mrh, mp, VSW_MACRX_PROMISC | VSW_MACRX_COPYMSG); if ((ret_m = vsw_tx_msg(vswp, mp, caller, arg)) != NULL) { DERR(vswp, "%s: drop mblks to " "phys dev", __func__); freemsgchain(ret_m); } } else if (caller == VSW_PHYSDEV) { /* * Pkt seen because card in promisc * mode. Send up stack if plumbed in * promisc mode, else drop it. */ vsw_mac_rx(vswp, mrh, mp, VSW_MACRX_PROMISC | VSW_MACRX_FREEMSG); } else if (caller == VSW_LOCALDEV) { /* * Pkt came down the stack, send out * over physical device. */ if ((ret_m = vsw_tx_msg(vswp, mp, caller, NULL)) != NULL) { DERR(vswp, "%s: drop mblks to " "phys dev", __func__); freemsgchain(ret_m); } } } } } D1(vswp, "%s: exit\n", __func__); }
int jffs2_commit_write (struct file *filp, struct page *pg, unsigned start, unsigned end) { /* Actually commit the write from the page cache page we're looking at. * For now, we write the full page out each time. It sucks, but it's simple */ struct inode *inode = pg->mapping->host; struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); __u32 newsize = max_t(__u32, filp->f_dentry->d_inode->i_size, (pg->index << PAGE_CACHE_SHIFT) + end); __u32 file_ofs = (pg->index << PAGE_CACHE_SHIFT); __u32 writelen = min((__u32)PAGE_CACHE_SIZE, newsize - file_ofs); struct jffs2_raw_inode *ri; int ret = 0; ssize_t writtenlen = 0; D1(printk(KERN_DEBUG "jffs2_commit_write(): ino #%lu, page at 0x%lx, range %d-%d, flags %lx\n", inode->i_ino, pg->index << PAGE_CACHE_SHIFT, start, end, pg->flags)); if (!start && end == PAGE_CACHE_SIZE) { /* We need to avoid deadlock with page_cache_read() in jffs2_garbage_collect_pass(). So we have to mark the page up to date, to prevent page_cache_read() from trying to re-lock it. */ SetPageUptodate(pg); } ri = jffs2_alloc_raw_inode(); if (!ri) return -ENOMEM; while(writelen) { struct jffs2_full_dnode *fn; unsigned char *comprbuf = NULL; unsigned char comprtype = JFFS2_COMPR_NONE; __u32 phys_ofs, alloclen; __u32 datalen, cdatalen; D2(printk(KERN_DEBUG "jffs2_commit_write() loop: 0x%x to write to 0x%x\n", writelen, file_ofs)); ret = jffs2_reserve_space(c, sizeof(*ri) + JFFS2_MIN_DATA_LEN, &phys_ofs, &alloclen, ALLOC_NORMAL); if (ret) { SetPageError(pg); D1(printk(KERN_DEBUG "jffs2_reserve_space returned %d\n", ret)); break; } down(&f->sem); datalen = writelen; cdatalen = min(alloclen - sizeof(*ri), writelen); comprbuf = kmalloc(cdatalen, GFP_KERNEL); if (comprbuf) { comprtype = jffs2_compress(page_address(pg)+ (file_ofs & (PAGE_CACHE_SIZE-1)), comprbuf, &datalen, &cdatalen); } if (comprtype == JFFS2_COMPR_NONE) { /* Either compression failed, or the allocation of comprbuf failed */ if (comprbuf) kfree(comprbuf); comprbuf = page_address(pg) + (file_ofs & (PAGE_CACHE_SIZE -1)); datalen = cdatalen; } /* Now comprbuf points to the data to be written, be it compressed or not. comprtype holds the compression type, and comprtype == JFFS2_COMPR_NONE means that the comprbuf doesn't need to be kfree()d. */ ri->magic = JFFS2_MAGIC_BITMASK; ri->nodetype = JFFS2_NODETYPE_INODE; ri->totlen = sizeof(*ri) + cdatalen; ri->hdr_crc = crc32(0, ri, sizeof(struct jffs2_unknown_node)-4); ri->ino = inode->i_ino; ri->version = ++f->highest_version; ri->mode = inode->i_mode; ri->uid = inode->i_uid; ri->gid = inode->i_gid; ri->isize = max((__u32)inode->i_size, file_ofs + datalen); ri->atime = ri->ctime = ri->mtime = CURRENT_TIME; ri->offset = file_ofs; ri->csize = cdatalen; ri->dsize = datalen; ri->compr = comprtype; ri->node_crc = crc32(0, ri, sizeof(*ri)-8); ri->data_crc = crc32(0, comprbuf, cdatalen); fn = jffs2_write_dnode(inode, ri, comprbuf, cdatalen, phys_ofs, NULL); jffs2_complete_reservation(c); if (comprtype != JFFS2_COMPR_NONE) kfree(comprbuf); if (IS_ERR(fn)) { ret = PTR_ERR(fn); up(&f->sem); SetPageError(pg); break; } ret = jffs2_add_full_dnode_to_inode(c, f, fn); if (f->metadata) { jffs2_mark_node_obsolete(c, f->metadata->raw); jffs2_free_full_dnode(f->metadata); f->metadata = NULL; } up(&f->sem); if (ret) { /* Eep */ D1(printk(KERN_DEBUG "Eep. add_full_dnode_to_inode() failed in commit_write, returned %d\n", ret)); jffs2_mark_node_obsolete(c, fn->raw); jffs2_free_full_dnode(fn); SetPageError(pg); break; } inode->i_size = ri->isize; inode->i_blocks = (inode->i_size + 511) >> 9; inode->i_ctime = inode->i_mtime = ri->ctime; if (!datalen) { printk(KERN_WARNING "Eep. We didn't actually write any bloody data\n"); ret = -EIO; SetPageError(pg); break; } D1(printk(KERN_DEBUG "increasing writtenlen by %d\n", datalen)); writtenlen += datalen; file_ofs += datalen; writelen -= datalen; } jffs2_free_raw_inode(ri); if (writtenlen < end) { /* generic_file_write has written more to the page cache than we've actually written to the medium. Mark the page !Uptodate so that it gets reread */ D1(printk(KERN_DEBUG "jffs2_commit_write(): Not all bytes written. Marking page !uptodate\n")); SetPageError(pg); ClearPageUptodate(pg); } if (writtenlen <= start) { /* We didn't even get to the start of the affected part */ ret = ret?ret:-ENOSPC; D1(printk(KERN_DEBUG "jffs2_commit_write(): Only %x bytes written to page. start (%x) not reached, returning %d\n", writtenlen, start, ret)); } writtenlen = min(end-start, writtenlen-start); D1(printk(KERN_DEBUG "jffs2_commit_write() returning %d. nrpages is %ld\n",writtenlen?writtenlen:ret, inode->i_mapping->nrpages)); return writtenlen?writtenlen:ret; }
/* * Forward the ethernet frame to all ports (VNETPORTs, PHYSDEV, LOCALDEV), * except the caller (port on which frame arrived). */ static int vsw_forward_all(vsw_t *vswp, mblk_t *mp, int caller, vsw_port_t *arg) { vsw_port_list_t *plist = &vswp->plist; vsw_port_t *portp; mblk_t *nmp = NULL; mblk_t *ret_m = NULL; int skip_port = 0; D1(vswp, "vsw_forward_all: enter\n"); /* * Broadcast message from inside ldoms so send to outside * world if in either of layer 2 modes. */ if ((vswp->smode & VSW_LAYER2) && ((caller == VSW_LOCALDEV) || (caller == VSW_VNETPORT))) { nmp = vsw_dupmsgchain(mp); if (nmp) { if ((ret_m = vsw_tx_msg(vswp, nmp, caller, arg)) != NULL) { DERR(vswp, "%s: dropping pkt(s) " "consisting of %ld bytes of data for" " physical device", __func__, MBLKL(ret_m)); freemsgchain(ret_m); } } } if (caller == VSW_VNETPORT) skip_port = 1; /* * Broadcast message from other vnet (layer 2 or 3) or outside * world (layer 2 only), send up stack if plumbed. */ if ((caller == VSW_PHYSDEV) || (caller == VSW_VNETPORT)) { vsw_mac_rx(vswp, NULL, mp, VSW_MACRX_COPYMSG); } /* send it to all VNETPORTs */ READ_ENTER(&plist->lockrw); for (portp = plist->head; portp != NULL; portp = portp->p_next) { D2(vswp, "vsw_forward_all: port %d", portp->p_instance); /* * Caution ! - don't reorder these two checks as arg * will be NULL if the caller is PHYSDEV. skip_port is * only set if caller is VNETPORT. */ if ((skip_port) && (portp == arg)) { continue; } else { nmp = vsw_dupmsgchain(mp); if (nmp) { /* * The plist->lockrw is protecting the * portp from getting destroyed here. * So, no ref_cnt is incremented here. */ (void) vsw_portsend(portp, nmp); } else { DERR(vswp, "vsw_forward_all: nmp NULL"); } } } RW_EXIT(&plist->lockrw); freemsgchain(mp); D1(vswp, "vsw_forward_all: exit\n"); return (0); }
/* In version 1.4 this function takes 27 - 50 us */ void start_one_shot_timer(struct fast_timer *t, fast_timer_function_type *function, unsigned long data, unsigned long delay_us, const char *name) { unsigned long flags; struct fast_timer *tmp; D1(printk("sft %s %d us\n", name, delay_us)); local_irq_save(flags); do_gettimeofday_fast(&t->tv_set); tmp = fast_timer_list; #ifdef FAST_TIMER_SANITY_CHECKS /* Check so this is not in the list already... */ while (tmp != NULL) { if (tmp == t) { printk(KERN_WARNING "timer name: %s data: " "0x%08lX already in list!\n", name, data); sanity_failed++; goto done; } else tmp = tmp->next; } tmp = fast_timer_list; #endif t->delay_us = delay_us; t->function = function; t->data = data; t->name = name; t->tv_expires.tv_usec = t->tv_set.tv_usec + delay_us % 1000000; t->tv_expires.tv_jiff = t->tv_set.tv_jiff + delay_us / 1000000 / HZ; if (t->tv_expires.tv_usec > 1000000) { t->tv_expires.tv_usec -= 1000000; t->tv_expires.tv_jiff += HZ; } #ifdef FAST_TIMER_LOG timer_added_log[fast_timers_added % NUM_TIMER_STATS] = *t; #endif fast_timers_added++; /* Check if this should timeout before anything else */ if (tmp == NULL || fasttime_cmp(&t->tv_expires, &tmp->tv_expires) < 0) { /* Put first in list and modify the timer value */ t->prev = NULL; t->next = fast_timer_list; if (fast_timer_list) { fast_timer_list->prev = t; } fast_timer_list = t; #ifdef FAST_TIMER_LOG timer_started_log[fast_timers_started % NUM_TIMER_STATS] = *t; #endif start_timer1(delay_us); } else { /* Put in correct place in list */ while (tmp->next && fasttime_cmp(&t->tv_expires, &tmp->next->tv_expires) > 0) { tmp = tmp->next; } /* Insert t after tmp */ t->prev = tmp; t->next = tmp->next; if (tmp->next) { tmp->next->prev = t; } tmp->next = t; } D2(printk("start_one_shot_timer: %d us done\n", delay_us)); done: local_irq_restore(flags); } /* start_one_shot_timer */
static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, unsigned char *buf, uint32_t buf_size) { struct jffs2_unknown_node *node; struct jffs2_unknown_node crcnode; uint32_t ofs, prevofs; uint32_t hdr_crc, buf_ofs, buf_len; int err; int noise = 0; #ifdef CONFIG_JFFS2_FS_WRITEBUFFER int cleanmarkerfound = 0; #endif ofs = jeb->offset; prevofs = jeb->offset - 1; D1(printk(KERN_DEBUG "jffs2_scan_eraseblock(): Scanning block at 0x%x\n", ofs)); #ifdef CONFIG_JFFS2_FS_WRITEBUFFER if (jffs2_cleanmarker_oob(c)) { int ret = jffs2_check_nand_cleanmarker(c, jeb); D2(printk(KERN_NOTICE "jffs_check_nand_cleanmarker returned %d\n",ret)); /* Even if it's not found, we still scan to see if the block is empty. We use this information to decide whether to erase it or not. */ switch (ret) { case 0: cleanmarkerfound = 1; break; case 1: break; case 2: return BLK_STATE_BADBLOCK; case 3: return BLK_STATE_ALLDIRTY; /* Block has failed to erase min. once */ default: return ret; } } #endif buf_ofs = jeb->offset; if (!buf_size) { buf_len = c->sector_size; } else { buf_len = EMPTY_SCAN_SIZE(c->sector_size); err = jffs2_fill_scan_buf(c, buf, buf_ofs, buf_len); if (err) return err; } /* We temporarily use 'ofs' as a pointer into the buffer/jeb */ ofs = 0; /* Scan only 4KiB of 0xFF before declaring it's empty */ while(ofs < EMPTY_SCAN_SIZE(c->sector_size) && *(uint32_t *)(&buf[ofs]) == 0xFFFFFFFF) ofs += 4; if (ofs == EMPTY_SCAN_SIZE(c->sector_size)) { #ifdef CONFIG_JFFS2_FS_WRITEBUFFER if (jffs2_cleanmarker_oob(c)) { /* scan oob, take care of cleanmarker */ int ret = jffs2_check_oob_empty(c, jeb, cleanmarkerfound); D2(printk(KERN_NOTICE "jffs2_check_oob_empty returned %d\n",ret)); switch (ret) { case 0: return cleanmarkerfound ? BLK_STATE_CLEANMARKER : BLK_STATE_ALLFF; case 1: return BLK_STATE_ALLDIRTY; default: return ret; } } #endif D1(printk(KERN_DEBUG "Block at 0x%08x is empty (erased)\n", jeb->offset)); if (c->cleanmarker_size == 0) return BLK_STATE_CLEANMARKER; /* don't bother with re-erase */ else return BLK_STATE_ALLFF; /* OK to erase if all blocks are like this */ } if (ofs) { D1(printk(KERN_DEBUG "Free space at %08x ends at %08x\n", jeb->offset, jeb->offset + ofs)); DIRTY_SPACE(ofs); } /* Now ofs is a complete physical flash offset as it always was... */ ofs += jeb->offset; noise = 10; scan_more: while(ofs < jeb->offset + c->sector_size) { D1(ACCT_PARANOIA_CHECK(jeb)); cond_resched(); if (ofs & 3) { printk(KERN_WARNING "Eep. ofs 0x%08x not word-aligned!\n", ofs); ofs = PAD(ofs); continue; } if (ofs == prevofs) { printk(KERN_WARNING "ofs 0x%08x has already been seen. Skipping\n", ofs); DIRTY_SPACE(4); ofs += 4; continue; } prevofs = ofs; if (jeb->offset + c->sector_size < ofs + sizeof(*node)) { D1(printk(KERN_DEBUG "Fewer than %zd bytes left to end of block. (%x+%x<%x+%zx) Not reading\n", sizeof(struct jffs2_unknown_node), jeb->offset, c->sector_size, ofs, sizeof(*node))); DIRTY_SPACE((jeb->offset + c->sector_size)-ofs); break; } if (buf_ofs + buf_len < ofs + sizeof(*node)) { buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs); D1(printk(KERN_DEBUG "Fewer than %zd bytes (node header) left to end of buf. Reading 0x%x at 0x%08x\n", sizeof(struct jffs2_unknown_node), buf_len, ofs)); err = jffs2_fill_scan_buf(c, buf, ofs, buf_len); if (err) return err; buf_ofs = ofs; } node = (struct jffs2_unknown_node *)&buf[ofs-buf_ofs]; if (*(uint32_t *)(&buf[ofs-buf_ofs]) == 0xffffffff) { uint32_t inbuf_ofs; uint32_t empty_start; empty_start = ofs; ofs += 4; D1(printk(KERN_DEBUG "Found empty flash at 0x%08x\n", ofs)); more_empty: inbuf_ofs = ofs - buf_ofs; while (inbuf_ofs < buf_len) { if (*(uint32_t *)(&buf[inbuf_ofs]) != 0xffffffff) { printk(KERN_WARNING "Empty flash at 0x%08x ends at 0x%08x\n", empty_start, ofs); DIRTY_SPACE(ofs-empty_start); goto scan_more; } inbuf_ofs+=4; ofs += 4; } /* Ran off end. */ D1(printk(KERN_DEBUG "Empty flash to end of buffer at 0x%08x\n", ofs)); /* If we're only checking the beginning of a block with a cleanmarker, bail now */ if (buf_ofs == jeb->offset && jeb->used_size == PAD(c->cleanmarker_size) && c->cleanmarker_size && !jeb->dirty_size && !jeb->first_node->next_phys) { D1(printk(KERN_DEBUG "%d bytes at start of block seems clean... assuming all clean\n", EMPTY_SCAN_SIZE(c->sector_size))); return BLK_STATE_CLEANMARKER; } /* See how much more there is to read in this eraseblock... */ buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs); if (!buf_len) { /* No more to read. Break out of main loop without marking this range of empty space as dirty (because it's not) */ D1(printk(KERN_DEBUG "Empty flash at %08x runs to end of block. Treating as free_space\n", empty_start)); break; } D1(printk(KERN_DEBUG "Reading another 0x%x at 0x%08x\n", buf_len, ofs)); err = jffs2_fill_scan_buf(c, buf, ofs, buf_len); if (err) return err; buf_ofs = ofs; goto more_empty; } if (ofs == jeb->offset && je16_to_cpu(node->magic) == KSAMTIB_CIGAM_2SFFJ) { printk(KERN_WARNING "Magic bitmask is backwards at offset 0x%08x. Wrong endian filesystem?\n", ofs); DIRTY_SPACE(4); ofs += 4; continue; } if (je16_to_cpu(node->magic) == JFFS2_DIRTY_BITMASK) { D1(printk(KERN_DEBUG "Dirty bitmask at 0x%08x\n", ofs)); DIRTY_SPACE(4); ofs += 4; continue; } if (je16_to_cpu(node->magic) == JFFS2_OLD_MAGIC_BITMASK) { printk(KERN_WARNING "Old JFFS2 bitmask found at 0x%08x\n", ofs); printk(KERN_WARNING "You cannot use older JFFS2 filesystems with newer kernels\n"); DIRTY_SPACE(4); ofs += 4; continue; } if (je16_to_cpu(node->magic) != JFFS2_MAGIC_BITMASK) { /* OK. We're out of possibilities. Whinge and move on */ noisy_printk(&noise, "jffs2_scan_eraseblock(): Magic bitmask 0x%04x not found at 0x%08x: 0x%04x instead\n", JFFS2_MAGIC_BITMASK, ofs, je16_to_cpu(node->magic)); DIRTY_SPACE(4); ofs += 4; continue; } /* We seem to have a node of sorts. Check the CRC */ crcnode.magic = node->magic; crcnode.nodetype = cpu_to_je16( je16_to_cpu(node->nodetype) | JFFS2_NODE_ACCURATE); crcnode.totlen = node->totlen; hdr_crc = crc32(0, &crcnode, sizeof(crcnode)-4); if (hdr_crc != je32_to_cpu(node->hdr_crc)) { noisy_printk(&noise, "jffs2_scan_eraseblock(): Node at 0x%08x {0x%04x, 0x%04x, 0x%08x) has invalid CRC 0x%08x (calculated 0x%08x)\n", ofs, je16_to_cpu(node->magic), je16_to_cpu(node->nodetype), je32_to_cpu(node->totlen), je32_to_cpu(node->hdr_crc), hdr_crc); DIRTY_SPACE(4); ofs += 4; continue; } if (ofs + je32_to_cpu(node->totlen) > jeb->offset + c->sector_size) { /* Eep. Node goes over the end of the erase block. */ printk(KERN_WARNING "Node at 0x%08x with length 0x%08x would run over the end of the erase block\n", ofs, je32_to_cpu(node->totlen)); printk(KERN_WARNING "Perhaps the file system was created with the wrong erase size?\n"); DIRTY_SPACE(4); ofs += 4; continue; } if (!(je16_to_cpu(node->nodetype) & JFFS2_NODE_ACCURATE)) { /* Wheee. This is an obsoleted node */ D2(printk(KERN_DEBUG "Node at 0x%08x is obsolete. Skipping\n", ofs)); DIRTY_SPACE(PAD(je32_to_cpu(node->totlen))); ofs += PAD(je32_to_cpu(node->totlen)); continue; } switch(je16_to_cpu(node->nodetype)) { case JFFS2_NODETYPE_INODE: if (buf_ofs + buf_len < ofs + sizeof(struct jffs2_raw_inode)) { buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs); D1(printk(KERN_DEBUG "Fewer than %zd bytes (inode node) left to end of buf. Reading 0x%x at 0x%08x\n", sizeof(struct jffs2_raw_inode), buf_len, ofs)); err = jffs2_fill_scan_buf(c, buf, ofs, buf_len); if (err) return err; buf_ofs = ofs; node = (void *)buf; } err = jffs2_scan_inode_node(c, jeb, (void *)node, ofs); if (err) return err; ofs += PAD(je32_to_cpu(node->totlen)); break; case JFFS2_NODETYPE_DIRENT: if (buf_ofs + buf_len < ofs + je32_to_cpu(node->totlen)) { buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs); D1(printk(KERN_DEBUG "Fewer than %d bytes (dirent node) left to end of buf. Reading 0x%x at 0x%08x\n", je32_to_cpu(node->totlen), buf_len, ofs)); err = jffs2_fill_scan_buf(c, buf, ofs, buf_len); if (err) return err; buf_ofs = ofs; node = (void *)buf; } err = jffs2_scan_dirent_node(c, jeb, (void *)node, ofs); if (err) return err; ofs += PAD(je32_to_cpu(node->totlen)); break; case JFFS2_NODETYPE_CLEANMARKER: D1(printk(KERN_DEBUG "CLEANMARKER node found at 0x%08x\n", ofs)); if (je32_to_cpu(node->totlen) != c->cleanmarker_size) { printk(KERN_NOTICE "CLEANMARKER node found at 0x%08x has totlen 0x%x != normal 0x%x\n", ofs, je32_to_cpu(node->totlen), c->cleanmarker_size); DIRTY_SPACE(PAD(sizeof(struct jffs2_unknown_node))); ofs += PAD(sizeof(struct jffs2_unknown_node)); } else if (jeb->first_node) { printk(KERN_NOTICE "CLEANMARKER node found at 0x%08x, not first node in block (0x%08x)\n", ofs, jeb->offset); DIRTY_SPACE(PAD(sizeof(struct jffs2_unknown_node))); ofs += PAD(sizeof(struct jffs2_unknown_node)); } else { struct jffs2_raw_node_ref *marker_ref = jffs2_alloc_raw_node_ref(); if (!marker_ref) { printk(KERN_NOTICE "Failed to allocate node ref for clean marker\n"); return -ENOMEM; } marker_ref->next_in_ino = NULL; marker_ref->next_phys = NULL; marker_ref->flash_offset = ofs | REF_NORMAL; marker_ref->__totlen = c->cleanmarker_size; jeb->first_node = jeb->last_node = marker_ref; USED_SPACE(PAD(c->cleanmarker_size)); ofs += PAD(c->cleanmarker_size); } break; case JFFS2_NODETYPE_PADDING: DIRTY_SPACE(PAD(je32_to_cpu(node->totlen))); ofs += PAD(je32_to_cpu(node->totlen)); break; default: switch (je16_to_cpu(node->nodetype) & JFFS2_COMPAT_MASK) { case JFFS2_FEATURE_ROCOMPAT: printk(KERN_NOTICE "Read-only compatible feature node (0x%04x) found at offset 0x%08x\n", je16_to_cpu(node->nodetype), ofs); c->flags |= JFFS2_SB_FLAG_RO; if (!(jffs2_is_readonly(c))) return -EROFS; DIRTY_SPACE(PAD(je32_to_cpu(node->totlen))); ofs += PAD(je32_to_cpu(node->totlen)); break; case JFFS2_FEATURE_INCOMPAT: printk(KERN_NOTICE "Incompatible feature node (0x%04x) found at offset 0x%08x\n", je16_to_cpu(node->nodetype), ofs); return -EINVAL; case JFFS2_FEATURE_RWCOMPAT_DELETE: D1(printk(KERN_NOTICE "Unknown but compatible feature node (0x%04x) found at offset 0x%08x\n", je16_to_cpu(node->nodetype), ofs)); DIRTY_SPACE(PAD(je32_to_cpu(node->totlen))); ofs += PAD(je32_to_cpu(node->totlen)); break; case JFFS2_FEATURE_RWCOMPAT_COPY: D1(printk(KERN_NOTICE "Unknown but compatible feature node (0x%04x) found at offset 0x%08x\n", je16_to_cpu(node->nodetype), ofs)); USED_SPACE(PAD(je32_to_cpu(node->totlen))); ofs += PAD(je32_to_cpu(node->totlen)); break; } } } D1(printk(KERN_DEBUG "Block at 0x%08x: free 0x%08x, dirty 0x%08x, unchecked 0x%08x, used 0x%08x\n", jeb->offset, jeb->free_size, jeb->dirty_size, jeb->unchecked_size, jeb->used_size)); /* mark_node_obsolete can add to wasted !! */ if (jeb->wasted_size) { jeb->dirty_size += jeb->wasted_size; c->dirty_size += jeb->wasted_size; c->wasted_size -= jeb->wasted_size; jeb->wasted_size = 0; } if ((jeb->used_size + jeb->unchecked_size) == PAD(c->cleanmarker_size) && !jeb->dirty_size && (!jeb->first_node || !jeb->first_node->next_phys) ) return BLK_STATE_CLEANMARKER; /* move blocks with max 4 byte dirty space to cleanlist */ else if (!ISDIRTY(c->sector_size - (jeb->used_size + jeb->unchecked_size))) { c->dirty_size -= jeb->dirty_size; c->wasted_size += jeb->dirty_size; jeb->wasted_size += jeb->dirty_size; jeb->dirty_size = 0; return BLK_STATE_CLEAN; } else if (jeb->used_size || jeb->unchecked_size) return BLK_STATE_PARTDIRTY; else return BLK_STATE_ALLDIRTY; }
int main(int argc, char *argv[]) { int i; // Initialize POOMA and output stream, using Tester class Pooma::initialize(argc, argv); Pooma::Tester tester(argc, argv); tester.out() << argv[0]; tester.out() << ": DynamicArray <--> Array assignment." << std::endl; tester.out() << "-------------------------------------------" << std::endl; // Create some Interval objects to create and index into Array's with tester.out() << "Creating Interval<1> objects ..." << std::endl; Interval<1> D1(3); Interval<1> D2(4); tester.out() << "D1 = " << D1 << std::endl; tester.out() << "D2 = " << D2 << std::endl; // Create simple single-patch dynamic arrays. tester.out() << "Creating DynamicArray objects ..." << std::endl; DynamicArray<int> a(D1); // Create simple Brick-based regular arrays. tester.out() << "Creating regular Array objects ..." << std::endl; Array<1,long> b(D2); // Initialize dynamic array with scalar. a = 3; tester.out() << "Initialized DynamicArray a to the value 3." << std::endl; tester.out() << "a = " << a << std::endl; tester.check("Initially DynamicArray", sum(a) == (a.domain().size() * 3)); // Initialize the regular array with scalars. // Block since we're starting scalar code. Pooma::blockAndEvaluate(); tester.out() << "Initializing regular Array objects ..." << std::endl; for (i=0; i < b.domain().size(); ++i) { b(i) = i + 11; } tester.out() << "b = " << b << std::endl; // Resize a to the same size as b, and do operations. int oldsum = sum(a); tester.out() << "Resizing a to domain " << b.domain() << std::endl; a.create(1); a.sync(); a(a.domain().size() - 1) = 1000; tester.out() << "a = " << a << std::endl; tester.check("Resize a sum", sum(a) == (oldsum + 1000)); int suma = sum(a); long sumb = sum(b); tester.out() << "Trying a += b:" << std::endl; a += b; tester.out() << "a = " << a << std::endl; tester.out() << "b = " << b << std::endl; tester.check("a += b", sum(a) == (suma + sumb)); tester.out() << "Trying b = a:" << std::endl; b = a; tester.out() << "a = " << a << std::endl; tester.out() << "b = " << b << std::endl; tester.check("b = a", sum(a) == sum(b)); tester.out() << "Trying a = (b + b):" << std::endl; a = (b + b); tester.out() << "a = " << a << std::endl; tester.out() << "b = " << b << std::endl; tester.check("a = (b + b)", sum(a) == (sum(b) + sum(b))); tester.out() << "Trying a = (a + a) - b" << std::endl; suma = sum(a); a = (a + a) - b; tester.out() << "a = " << a << std::endl; tester.out() << "b = " << b << std::endl; tester.check("a = (a + a) - b", sum(a) == (2*suma - sum(b))); tester.out() << "Trying b = (a * b) + (b - a)" << std::endl; sumb = sum((a * b) + (b - a)); b = (a * b) + (b - a); tester.out() << "a = " << a << std::endl; tester.out() << "b = " << b << std::endl; tester.check("b = (a * b) + (b - a)", sum(b) == sumb); // Return resulting error code and exit; Tester will shut down POOMA. tester.out() << "-------------------------------------------" << std::endl; int retval = tester.results("DynamicArray <--> Array expressions"); Pooma::finalize(); return retval; }
inline void internal::Trr2kNNTT ( UpperOrLower uplo, Orientation orientationOfC, Orientation orientationOfD, T alpha, const DistMatrix<T,MC,MR>& A, const DistMatrix<T,MC,MR>& B, const DistMatrix<T,MC,MR>& C, const DistMatrix<T,MC,MR>& D, T beta, DistMatrix<T,MC,MR>& E ) { #ifndef RELEASE PushCallStack("internal::Trr2kNNTT"); if( E.Height() != E.Width() || A.Width() != C.Height() || A.Height() != E.Height() || C.Width() != E.Height() || B.Width() != E.Width() || D.Height() != E.Width() || A.Width() != B.Height() || C.Height() != D.Width() ) throw std::logic_error("Nonconformal Trr2kNNTT"); #endif const Grid& g = E.Grid(); DistMatrix<T,MC,MR> AL(g), AR(g), A0(g), A1(g), A2(g); DistMatrix<T,MC,MR> BT(g), B0(g), BB(g), B1(g), B2(g); DistMatrix<T,MC,MR> CT(g), C0(g), CB(g), C1(g), C2(g); DistMatrix<T,MC,MR> DL(g), DR(g), D0(g), D1(g), D2(g); DistMatrix<T,MC, STAR> A1_MC_STAR(g); DistMatrix<T,MR, STAR> B1Trans_MR_STAR(g); DistMatrix<T,STAR,MC > C1_STAR_MC(g); DistMatrix<T,VR, STAR> D1_VR_STAR(g); DistMatrix<T,STAR,MR > D1AdjOrTrans_STAR_MR(g); LockedPartitionRight( A, AL, AR, 0 ); LockedPartitionDown ( B, BT, BB, 0 ); LockedPartitionDown ( C, CT, CB, 0 ); LockedPartitionRight( D, DL, DR, 0 ); while( AL.Width() < A.Width() ) { LockedRepartitionRight ( AL, /**/ AR, A0, /**/ A1, A2 ); LockedRepartitionDown ( BT, B0, /**/ /**/ B1, BB, B2 ); LockedRepartitionDown ( CT, C0, /**/ /**/ C1, CB, C2 ); LockedRepartitionRight ( DL, /**/ DR, D0, /**/ D1, D2 ); A1_MC_STAR.AlignWith( E ); B1Trans_MR_STAR.AlignWith( E ); C1_STAR_MC.AlignWith( E ); D1_VR_STAR.AlignWith( E ); D1AdjOrTrans_STAR_MR.AlignWith( E ); //--------------------------------------------------------------------// A1_MC_STAR = A1; C1_STAR_MC = C1; B1Trans_MR_STAR.TransposeFrom( B1 ); D1_VR_STAR = D1; if( orientationOfD == ADJOINT ) D1AdjOrTrans_STAR_MR.AdjointFrom( D1_VR_STAR ); else D1AdjOrTrans_STAR_MR.TransposeFrom( D1_VR_STAR ); internal::LocalTrr2k ( uplo, TRANSPOSE, orientationOfC, alpha, A1_MC_STAR, B1Trans_MR_STAR, C1_STAR_MC, D1AdjOrTrans_STAR_MR, beta, E ); //--------------------------------------------------------------------// D1AdjOrTrans_STAR_MR.FreeAlignments(); D1_VR_STAR.FreeAlignments(); C1_STAR_MC.FreeAlignments(); B1Trans_MR_STAR.FreeAlignments(); A1_MC_STAR.FreeAlignments(); SlideLockedPartitionRight ( DL, /**/ DR, D0, D1, /**/ D2 ); SlideLockedPartitionDown ( CT, C0, C1, /**/ /**/ CB, C2 ); SlideLockedPartitionDown ( BT, B0, B1, /**/ /**/ BB, B2 ); SlideLockedPartitionRight ( AL, /**/ AR, A0, A1, /**/ A2 ); } #ifndef RELEASE PopCallStack(); #endif }
/**Funzione che modifica l'input del generatore andando a leggere tutto il file, e * scrivendo solo il tempo di decadimento massimo dell'iterazione i-esima. * Parametri: * - file_in_grafo: file di input del generatore. * - tempo_fisso: valore booleano che indica se il tempo di decadimento di ogni proteina è fisso a MDT oopure variabile tra 1 e MDT. * - new_t: nuovo MDT da impostare. */ bool modifica_input_generatore(const char *file_in_grafo, bool tempo_fisso, int new_t){ FILE *pfile; char c; //booleano che indica se leggere e memorizzare o meno il carattere letto bool leggi; //intero che indica quale occorrenze bisogna ancora leggere (le occorenze sono 6) int occorrenze=0; int i,iaus,aus1,aus2; float faus; int offset; pfile=fopen(file_in_grafo,"r+"); if(pfile==NULL){ printf("errore apertura in lettura file!!! error is %d\n",errno); return false;} leggi=false; while(fscanf(pfile,"%c",&c)!=EOF){ //se è un ':' allora si aspetta di leggere un numero if(c==':'){ leggi=true; D2(printf("leggi si\n")); } //può leggere if(leggi==true){ switch(occorrenze){ case 0: fscanf(pfile,"%d",&iaus); break; case 1: fscanf(pfile,"%d",&iaus); break; case 2: fscanf(pfile,"%d %d",&aus1,&aus2); break; case 3: //deve leggere le probabilità delle kin //alloca i float, ne alloca kinmax-kinmin+1 (min e max già letti) for(i=0;i<aus2-aus1+1;i++) fscanf(pfile,"%f ",&faus); break; case 4: fscanf(pfile,"%d",&iaus); break; case 5: //caso di interesse fscanf(pfile,"%d ",&iaus); fscanf(pfile,"%d",&iaus); offset=(iaus>=10)?2:1; offset=(iaus>=100)?3:offset; offset=(iaus>=1000)?4:offset; //se il tempo di dec delle proteine è fisso if(tempo_fisso){ fseek(pfile, -(2*offset+1), SEEK_CUR); fprintf(pfile,"%d %d ",new_t,new_t); } //se deve prendere con prob uniforme tra 1 ... MDT else{ fseek(pfile, -offset, SEEK_CUR); fprintf(pfile,"%d ",new_t); } if((iaus<10 && new_t>=10) || (iaus<100 && new_t>=100) || (iaus<1000 && new_t>=1000)) fprintf(pfile,"\n"); break; case 6: break; default:printf("errore! numero occorrenze errato in mod gen\n"); } occorrenze++; leggi=false; } } if(fclose(pfile)!=0){ printf("errore in chiusura file!!! error is %d\n",errno); return false;} return true; }
//======================================================================= //function : MergeEdges //purpose : auxilary //======================================================================= static Standard_Boolean MergeEdges(const TopTools_SequenceOfShape& SeqEdges, const TopoDS_Face& aFace, const Standard_Real Tol, TopoDS_Edge& anEdge) { // make chain for union BRep_Builder B; ShapeAnalysis_Edge sae; TopoDS_Edge FirstE = TopoDS::Edge(SeqEdges.Value(1)); TopoDS_Edge LastE = FirstE; TopoDS_Vertex VF = sae.FirstVertex(FirstE); TopoDS_Vertex VL = sae.LastVertex(LastE); TopTools_SequenceOfShape aChain; aChain.Append(FirstE); TColStd_MapOfInteger IndUsedEdges; IndUsedEdges.Add(1); Standard_Integer j; for(j=2; j<=SeqEdges.Length(); j++) { for(Standard_Integer k=2; k<=SeqEdges.Length(); k++) { if(IndUsedEdges.Contains(k)) continue; TopoDS_Edge edge = TopoDS::Edge(SeqEdges.Value(k)); TopoDS_Vertex VF2 = sae.FirstVertex(edge); TopoDS_Vertex VL2 = sae.LastVertex(edge); if(sae.FirstVertex(edge).IsSame(VL)) { aChain.Append(edge); LastE = edge; VL = sae.LastVertex(LastE); IndUsedEdges.Add(k); } else if(sae.LastVertex(edge).IsSame(VF)) { aChain.Prepend(edge); FirstE = edge; VF = sae.FirstVertex(FirstE); IndUsedEdges.Add(k); } } } if(aChain.Length()<SeqEdges.Length()) { MESSAGE ("can not create correct chain..."); return Standard_False; } // union edges in chain // first step: union lines and circles TopLoc_Location Loc; Standard_Real fp1,lp1,fp2,lp2; for(j=1; j<aChain.Length(); j++) { TopoDS_Edge edge1 = TopoDS::Edge(aChain.Value(j)); Handle(Geom_Curve) c3d1 = BRep_Tool::Curve(edge1,Loc,fp1,lp1); if(c3d1.IsNull()) break; while(c3d1->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) { Handle(Geom_TrimmedCurve) tc = Handle(Geom_TrimmedCurve)::DownCast(c3d1); c3d1 = tc->BasisCurve(); } TopoDS_Edge edge2 = TopoDS::Edge(aChain.Value(j+1)); Handle(Geom_Curve) c3d2 = BRep_Tool::Curve(edge2,Loc,fp2,lp2); if(c3d2.IsNull()) break; while(c3d2->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) { Handle(Geom_TrimmedCurve) tc = Handle(Geom_TrimmedCurve)::DownCast(c3d2); c3d2 = tc->BasisCurve(); } if( c3d1->IsKind(STANDARD_TYPE(Geom_Line)) && c3d2->IsKind(STANDARD_TYPE(Geom_Line)) ) { // union lines Handle(Geom_Line) L1 = Handle(Geom_Line)::DownCast(c3d1); Handle(Geom_Line) L2 = Handle(Geom_Line)::DownCast(c3d2); gp_Dir Dir1 = L1->Position().Direction(); gp_Dir Dir2 = L2->Position().Direction(); //if(!Dir1.IsEqual(Dir2,Precision::Angular())) { //if(!Dir1.IsParallel(Dir2,Precision::Angular())) { if(!Dir1.IsParallel(Dir2,Tol)) { continue; } // can union lines => create new edge TopoDS_Vertex V1 = sae.FirstVertex(edge1); gp_Pnt PV1 = BRep_Tool::Pnt(V1); TopoDS_Vertex V2 = sae.LastVertex(edge2); gp_Pnt PV2 = BRep_Tool::Pnt(V2); gp_Vec Vec(PV1,PV2); Handle(Geom_Line) L = new Geom_Line(gp_Ax1(PV1,Vec)); Standard_Real dist = PV1.Distance(PV2); Handle(Geom_TrimmedCurve) tc = new Geom_TrimmedCurve(L,0.0,dist); TopoDS_Edge E; B.MakeEdge (E,tc,Precision::Confusion()); B.Add (E,V1); B.Add (E,V2); B.UpdateVertex(V1, 0., E, 0.); B.UpdateVertex(V2, dist, E, 0.); //ShapeFix_Edge sfe; //sfe.FixAddPCurve(E,aFace,Standard_False); //sfe.FixSameParameter(E); aChain.Remove(j); aChain.SetValue(j,E); j--; } if( c3d1->IsKind(STANDARD_TYPE(Geom_Circle)) && c3d2->IsKind(STANDARD_TYPE(Geom_Circle)) ) { // union circles Handle(Geom_Circle) C1 = Handle(Geom_Circle)::DownCast(c3d1); Handle(Geom_Circle) C2 = Handle(Geom_Circle)::DownCast(c3d2); gp_Pnt P01 = C1->Location(); gp_Pnt P02 = C2->Location(); if (P01.Distance(P02) > Precision::Confusion()) continue; // can union circles => create new edge TopoDS_Vertex V1 = sae.FirstVertex(edge1); gp_Pnt PV1 = BRep_Tool::Pnt(V1); TopoDS_Vertex V2 = sae.LastVertex(edge2); gp_Pnt PV2 = BRep_Tool::Pnt(V2); TopoDS_Vertex VM = sae.LastVertex(edge1); gp_Pnt PVM = BRep_Tool::Pnt(VM); GC_MakeCircle MC (PV1,PVM,PV2); Handle(Geom_Circle) C = MC.Value(); TopoDS_Edge E; if (!MC.IsDone() || C.IsNull()) { // jfa for Mantis issue 0020228 if (PV1.Distance(PV2) > Precision::Confusion()) continue; // closed chain C = C1; B.MakeEdge (E,C,Precision::Confusion()); B.Add(E,V1); B.Add(E,V2); } else { gp_Pnt P0 = C->Location(); gp_Dir D1(gp_Vec(P0,PV1)); gp_Dir D2(gp_Vec(P0,PV2)); Standard_Real fpar = C->XAxis().Direction().Angle(D1); if(fabs(fpar)>Precision::Confusion()) { // check orientation gp_Dir ND = C->XAxis().Direction().Crossed(D1); if(ND.IsOpposite(C->Axis().Direction(),Precision::Confusion())) { fpar = -fpar; } } Standard_Real lpar = C->XAxis().Direction().Angle(D2); if(fabs(lpar)>Precision::Confusion()) { // check orientation gp_Dir ND = C->XAxis().Direction().Crossed(D2); if(ND.IsOpposite(C->Axis().Direction(),Precision::Confusion())) { lpar = -lpar; } } if(lpar<fpar) lpar += 2*M_PI; Handle(Geom_TrimmedCurve) tc = new Geom_TrimmedCurve(C,fpar,lpar); B.MakeEdge (E,tc,Precision::Confusion()); B.Add(E,V1); B.Add(E,V2); B.UpdateVertex(V1, fpar, E, 0.); B.UpdateVertex(V2, lpar, E, 0.); } aChain.Remove(j); aChain.SetValue(j,E); j--; } } if (j < aChain.Length()) { MESSAGE ("null curve3d in edge..."); return Standard_False; } if (aChain.Length() > 1) { // second step: union edges with various curves // skl for bug 0020052 from Mantis: perform such unions // only if curves are bspline or bezier bool NeedUnion = true; for(j=1; j<=aChain.Length(); j++) { TopoDS_Edge edge = TopoDS::Edge(aChain.Value(j)); Handle(Geom_Curve) c3d = BRep_Tool::Curve(edge,Loc,fp1,lp1); if(c3d.IsNull()) continue; while(c3d->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) { Handle(Geom_TrimmedCurve) tc = Handle(Geom_TrimmedCurve)::DownCast(c3d); c3d = tc->BasisCurve(); } if( ( c3d->IsKind(STANDARD_TYPE(Geom_BSplineCurve)) || c3d->IsKind(STANDARD_TYPE(Geom_BezierCurve)) ) ) continue; NeedUnion = false; break; } if(NeedUnion) { MESSAGE ("can not make analitical union => make approximation"); TopoDS_Wire W; B.MakeWire(W); for(j=1; j<=aChain.Length(); j++) { TopoDS_Edge edge = TopoDS::Edge(aChain.Value(j)); B.Add(W,edge); } Handle(BRepAdaptor_HCompCurve) Adapt = new BRepAdaptor_HCompCurve(W); Approx_Curve3d Conv(Adapt,Tol,GeomAbs_C1,9,1000); Handle(Geom_BSplineCurve) bc = Conv.Curve(); TopoDS_Edge E; B.MakeEdge (E,bc,Precision::Confusion()); B.Add (E,VF); B.Add (E,VL); aChain.SetValue(1,E); } else { MESSAGE ("can not make approximation for such types of curves"); return Standard_False; } } anEdge = TopoDS::Edge(aChain.Value(1)); return Standard_True; }
/* =============================================================== */ int32_t l3dsphere(struct xvimage * k, index_t x0, index_t y0, index_t z0, double r) /* =============================================================== */ /* Draws into the Khalimsky volume \b k, the discretized sphere of center \b x0, \b y0, \b z0 and of radius \b r. */ #undef F_NAME #define F_NAME "l3dsphere" { index_t rs, cs, ps, ds, N; uint8_t * K; index_t x, y, z; // coordinates in the continuous plane index_t xmin, ymin, zmin, xmax, ymax, zmax; index_t xx, yy, zz, x00, y00, z00; // coord. in the khalimsky space double t, t_, r2 = r*r; index_t tab[27]; int32_t i, n; rs = rowsize(k); cs = colsize(k); ds = depth(k); ps = rs * cs; N = ps * ds; K = UCHARDATA(k); x00 = x0 * 2; y00 = y0 * 2; z00 = z0 * 2; zmin = ymin = xmin = -((index_t)r+1); zmax = ymax = xmax = (index_t)r+1; #define D2(x,y,z) (double)((x)*(x)+(y)*(y)+(z)*(z)) for (z = zmin; z <= zmax; z++) for (y = ymin; y <= ymax; y++) { zz = z * 2 + z00; yy = y * 2 + y00; for (x = xmin; x < 0 ; x++) { xx = x * 2 + x00; t_ = D2(x,y,z); t = D2((x+1),y,z); if (t_ == r2) { if ((zz >= 0) && (zz < ds) && (yy >= 0) && (yy < cs) && (xx >= 0) && (xx < rs)) K[zz*ps + yy*rs + xx] = NDG_SINGL3D; } if ((t_ > r2) && (t < r2)) { if ((zz >= 0) && (zz < ds) && (yy >= 0) && (yy < cs) && (xx+1 >= 0) && (xx+1 < rs)) K[zz*ps + yy*rs + xx+1] = NDG_INTER3DX; Betacarre3d(rs, cs, ds, xx+1, yy, zz, tab, &n); for (i = 0; i < n; i++) K[tab[i]] = NDG_MAX; } t_ = t; } // for x for (x = 0; x < xmax ; x++) { xx = x * 2 + x00; t_ = D2(x,y,z); t = D2((x+1),y,z); if (t_ == r2) { if ((zz >= 0) && (zz < ds) && (yy >= 0) && (yy < cs) && (xx >= 0) && (xx < rs)) K[zz*ps + yy*rs + xx] = NDG_SINGL3D; } if ((t_ < r2) && (t > r2)) { if ((zz >= 0) && (zz < ds) && (yy >= 0) && (yy < cs) && (xx+1 >= 0) && (xx+1 < rs)) K[zz*ps + yy*rs + xx+1] = NDG_INTER3DX; Betacarre3d(rs, cs, ds, xx+1, yy, zz, tab, &n); for (i = 0; i < n; i++) K[tab[i]] = NDG_MAX; } t_ = t; } // for x if (t == r2) { xx = xmax * 2 + x00; if ((zz >= 0) && (zz < ds) && (yy >= 0) && (yy < cs) && (xx >= 0) && (xx < rs)) K[zz*ps + yy*rs + xx] = NDG_SINGL3D; } } // for y, z for (y = ymin; y <= ymax; y++) for (x = xmin; x <= xmax; x++) { xx = x * 2 + x00; yy = y * 2 + y00; for (z = zmin; z < 0 ; z++) { zz = z * 2 + z00; t_ = D2(x,y,z); t = D2(x,y,(z+1)); if (t_ == r2) { if ((zz >= 0) && (zz < ds) && (yy >= 0) && (yy < cs) && (xx >= 0) && (xx < rs)) K[zz*ps + yy*rs + xx] = NDG_SINGL3D; } if ((t_ > r2) && (t < r2)) { if ((zz+1 >= 0) && (zz+1 < ds) && (yy >= 0) && (yy < cs) && (xx >= 0) && (xx < rs)) K[(zz+1)*ps + yy*rs + xx] = NDG_INTER3DZ; Betacarre3d(rs, cs, ds, xx, yy, zz+1, tab, &n); for (i = 0; i < n; i++) K[tab[i]] = NDG_MAX; } t_ = t; } // for z for (z = 0; z < zmax ; z++) { zz = z * 2 + z00; t_ = D2(x,y,z); t = D2(x,y,(z+1)); if (t_ == r2) { if ((zz >= 0) && (zz < ds) && (yy >= 0) && (yy < cs) && (xx >= 0) && (xx < rs)) K[zz*ps + yy*rs + xx] = NDG_SINGL3D; } if ((t_ < r2) && (t > r2)) { if ((zz+1 >= 0) && (zz+1 < ds) && (yy >= 0) && (yy < cs) && (xx >= 0) && (xx < rs)) K[(zz+1)*ps + yy*rs + xx] = NDG_INTER3DZ; Betacarre3d(rs, cs, ds, xx, yy, zz+1, tab, &n); for (i = 0; i < n; i++) K[tab[i]] = NDG_MAX; } t_ = t; } // for z if (t == r2) { zz = zmax * 2 + z00; if ((zz >= 0) && (zz < ds) && (yy >= 0) && (yy < cs) && (xx >= 0) && (xx < rs)) K[zz*ps + yy*rs + xx] = NDG_SINGL3D; } } // for y, x for (z = zmin; z <= zmax; z++) for (x = xmin; x <= xmax; x++) { zz = z * 2 + z00; xx = x * 2 + x00; for (y = ymin; y < 0 ; y++) { yy = y * 2 + y00; t_ = D2(x,y,z); t = D2(x,(y+1),z); if (t_ == r2) { if ((zz >= 0) && (zz < ds) && (yy >= 0) && (yy < cs) && (xx >= 0) && (xx < rs)) K[zz*ps + yy*rs + xx] = NDG_SINGL3D; } if ((t_ > r2) && (t < r2)) { if ((zz >= 0) && (zz < ds) && (yy+1 >= 0) && (yy+1 < cs) && (xx >= 0) && (xx < rs)) K[zz*ps + (yy+1)*rs + xx] = NDG_INTER3DY; Betacarre3d(rs, cs, ds, xx, yy+1, zz, tab, &n); for (i = 0; i < n; i++) K[tab[i]] = NDG_MAX; } t_ = t; } // for y for (y = 0; y < ymax ; y++) { yy = y * 2 + y00; t_ = D2(x,y,z); t = D2(x,(y+1),z); if (t_ == r2) { if ((zz >= 0) && (zz < ds) && (yy >= 0) && (yy < cs) && (xx >= 0) && (xx < rs)) K[zz*ps + yy*rs + xx] = NDG_SINGL3D; } if ((t_ < r2) && (t > r2)) { if ((zz >= 0) && (zz < ds) && (yy+1 >= 0) && (yy+1 < cs) && (xx >= 0) && (xx < rs)) K[zz*ps + (yy+1)*rs + xx] = NDG_INTER3DY; Betacarre3d(rs, cs, ds, xx, yy+1, zz, tab, &n); for (i = 0; i < n; i++) K[tab[i]] = NDG_MAX; } t_ = t; } // for y if (t == r2) { yy = ymax * 2 + y00; if ((zz >= 0) && (zz < ds) && (yy >= 0) && (yy < cs) && (xx >= 0) && (xx < rs)) K[zz*ps + yy*rs + xx] = NDG_SINGL3D; } } // for x, z return 1; } /* l3dsphere() */
void RAUX::STLFile :: Load ( uint32_t * Status, uint32_t Flags ) { if ( TriangleList != NULL ) return; static_assert ( std::numeric_limits <float> :: is_iec559, "RAUX STL decoding requires IEEE-754 encoding for single precision floating point types." ); uint32_t SubStatus; if ( ! FileInstance.Exists () ) { * Status = kStatus_Failure_NonExistantFile; return; } FileInstance.Open ( & SubStatus ); if ( SubStatus != File :: kStatus_Success ) { * Status = kStatus_Failure_Load; return; } TriangleCount = 0; FileInstance.Read ( & TriangleCount, 4, 80, & SubStatus ); if ( SubStatus != File :: kStatus_Success ) { * Status = kStatus_Failure_Load; return; } #ifndef RAUX_LITTLE_ENDIAN_DEFINITE TriangleCount = LittleToHostEndian32 ( TriangleCount ); #endif TriangleList = new Triangle [ TriangleCount ]; for ( uint32_t I = 0; I < TriangleCount; I ++ ) { char Buffer [ 14 ]; FileInstance.Read ( reinterpret_cast <void *> ( Buffer ), 50, 84 + 50 * I, & SubStatus ); TriangleList [ I ].Normal.X = * reinterpret_cast <float *> ( & Buffer [ 0 ] ); TriangleList [ I ].Normal.Y = * reinterpret_cast <float *> ( & Buffer [ 4 ] ); TriangleList [ I ].Normal.Z = * reinterpret_cast <float *> ( & Buffer [ 8 ] ); TriangleList [ I ].P1.X = * reinterpret_cast <float *> ( & Buffer [ 12 ] ); TriangleList [ I ].P1.Y = * reinterpret_cast <float *> ( & Buffer [ 16 ] ); TriangleList [ I ].P1.Z = * reinterpret_cast <float *> ( & Buffer [ 20 ] ); TriangleList [ I ].P2.X = * reinterpret_cast <float *> ( & Buffer [ 24 ] ); TriangleList [ I ].P2.Y = * reinterpret_cast <float *> ( & Buffer [ 28 ] ); TriangleList [ I ].P2.Z = * reinterpret_cast <float *> ( & Buffer [ 32 ] ); TriangleList [ I ].P3.X = * reinterpret_cast <float *> ( & Buffer [ 36 ] ); TriangleList [ I ].P3.Y = * reinterpret_cast <float *> ( & Buffer [ 40 ] ); TriangleList [ I ].P3.Z = * reinterpret_cast <float *> ( & Buffer [ 44 ] ); }; if ( SubStatus != File :: kStatus_Success ) { delete TriangleList; TriangleCount = 0; * Status = kStatus_Failure_Load; return; } Vec3 MaxPositions ( 0.0f, 0.0f, 0.0f ); Vec3 MinPositions ( FLT_MAX, FLT_MAX, FLT_MAX ); for ( uint32_t I = 0; I < TriangleCount; I ++ ) { #ifndef RAUX_LITTLE_ENDIAN_DEFINITE TriangleList [ I ].Normal.X = LittleToHostEndianFloat ( TriangleList [ I ].Normal.X ); TriangleList [ I ].Normal.Y = LittleToHostEndianFloat ( TriangleList [ I ].Normal.Y ); TriangleList [ I ].Normal.Z = LittleToHostEndianFloat ( TriangleList [ I ].Normal.Z ); TriangleList [ I ].P1.X = LittleToHostEndianFloat ( TriangleList [ I ].P1.X ); TriangleList [ I ].P1.Y = LittleToHostEndianFloat ( TriangleList [ I ].P1.Y ); TriangleList [ I ].P1.Z = LittleToHostEndianFloat ( TriangleList [ I ].P1.Z ); TriangleList [ I ].P2.X = LittleToHostEndianFloat ( TriangleList [ I ].P2.X ); TriangleList [ I ].P2.Y = LittleToHostEndianFloat ( TriangleList [ I ].P2.Y ); TriangleList [ I ].P2.Z = LittleToHostEndianFloat ( TriangleList [ I ].P2.Z ); TriangleList [ I ].P3.X = LittleToHostEndianFloat ( TriangleList [ I ].P3.X ); TriangleList [ I ].P3.Y = LittleToHostEndianFloat ( TriangleList [ I ].P3.Y ); TriangleList [ I ].P3.Z = LittleToHostEndianFloat ( TriangleList [ I ].P3.Z ); #endif if ( ( ( Flags & kFlags_ReplaceNormalsForced ) != 0 ) || ( ( ( Flags & kFlags_ReplaceNormalsConditional ) != 0 ) && ( ( TriangleList [ I ].Normal.X == TriangleList [ I ].Normal.Y ) && ( TriangleList [ I ].Normal.Y == TriangleList [ I ].Normal.Z ) && ( TriangleList [ I ].Normal.Z == 0.0f ) ) ) ) { Vec3 D1 ( STLFILE_VEC3_NOINIT ); Vec3 D2 ( STLFILE_VEC3_NOINIT ); STLFILE_VEC3_SUBTRACT ( D1, TriangleList [ I ].P2, TriangleList [ I ].P1 ); STLFILE_VEC3_SUBTRACT ( D2, TriangleList [ I ].P3, TriangleList [ I ].P2 ); if ( ( Flags & kFlags_ForwardFace_CounterClockwise ) == 0 ) STLFILE_VEC3_CROSS ( TriangleList [ I ].Normal, D1, D2 ); else STLFILE_VEC3_CROSS ( TriangleList [ I ].Normal, D2, D1 ); STLFILE_VEC3_NORMALIZE ( TriangleList [ I ].Normal ); } } if ( ( ( Flags & kFlags_CenterPositions ) != 0 ) || ( ( Flags & kFlags_NormalizePositions ) != 0 ) ) { for ( uint32_t I = 0; I < TriangleCount; I ++ ) { if ( MaxPositions.X < TriangleList [ I ].P1.X ) MaxPositions.X = TriangleList [ I ].P1.X; if ( MaxPositions.Y < TriangleList [ I ].P1.Y ) MaxPositions.Y = TriangleList [ I ].P1.Y; if ( MaxPositions.Z < TriangleList [ I ].P1.Z ) MaxPositions.Z = TriangleList [ I ].P1.Z; if ( MaxPositions.X < TriangleList [ I ].P2.X ) MaxPositions.X = TriangleList [ I ].P2.X; if ( MaxPositions.Y < TriangleList [ I ].P2.Y ) MaxPositions.Y = TriangleList [ I ].P2.Y; if ( MaxPositions.Z < TriangleList [ I ].P2.Z ) MaxPositions.Z = TriangleList [ I ].P2.Z; if ( MaxPositions.X < TriangleList [ I ].P3.X ) MaxPositions.X = TriangleList [ I ].P3.X; if ( MaxPositions.Y < TriangleList [ I ].P3.Y ) MaxPositions.Y = TriangleList [ I ].P3.Y; if ( MaxPositions.Z < TriangleList [ I ].P3.Z ) MaxPositions.Z = TriangleList [ I ].P3.Z; if ( MinPositions.X > TriangleList [ I ].P1.X ) MinPositions.X = TriangleList [ I ].P1.X; if ( MinPositions.Y > TriangleList [ I ].P1.Y ) MinPositions.Y = TriangleList [ I ].P1.Y; if ( MinPositions.Z > TriangleList [ I ].P1.Z ) MinPositions.Z = TriangleList [ I ].P1.Z; if ( MinPositions.X > TriangleList [ I ].P2.X ) MinPositions.X = TriangleList [ I ].P2.X; if ( MinPositions.Y > TriangleList [ I ].P2.Y ) MinPositions.Y = TriangleList [ I ].P2.Y; if ( MinPositions.Z > TriangleList [ I ].P2.Z ) MinPositions.Z = TriangleList [ I ].P2.Z; if ( MinPositions.X > TriangleList [ I ].P3.X ) MinPositions.X = TriangleList [ I ].P3.X; if ( MinPositions.Y > TriangleList [ I ].P3.Y ) MinPositions.Y = TriangleList [ I ].P3.Y; if ( MinPositions.Z > TriangleList [ I ].P3.Z ) MinPositions.Z = TriangleList [ I ].P3.Z; } } Vec3 LimitRange ( 0.0f, 0.0f, 0.0f ); STLFILE_VEC3_SUBTRACT ( LimitRange, MaxPositions, MinPositions ); LimitRange.X = fabs ( LimitRange.X ); LimitRange.Y = fabs ( LimitRange.Y ); LimitRange.Z = fabs ( LimitRange.Z ); float RangeMax = fmax ( LimitRange.Z, fmax ( LimitRange.X, LimitRange.Y ) ); Vec3 Origin ( 0.0f, 0.0f, 0.0f ); Vec3 OffsetToOrigin ( STLFILE_VEC3_NOINIT ); STLFILE_VEC3_SUBTRACT ( OffsetToOrigin, Origin, MinPositions ); for ( uint32_t I = 0; I < TriangleCount; I ++ ) { STLFILE_VEC3_ADD ( TriangleList [ I ].P1, OffsetToOrigin ); STLFILE_VEC3_ADD ( TriangleList [ I ].P2, OffsetToOrigin ); STLFILE_VEC3_ADD ( TriangleList [ I ].P3, OffsetToOrigin ); } float ScaleMultiplier = 1.0f; if ( ( Flags & kFlags_CenterPositions ) != 0 ) ScaleMultiplier = 2.0f; if ( ( Flags & kFlags_NormalizePositions ) != 0 ) ScaleMultiplier /= RangeMax; if ( ScaleMultiplier != 1.0f ) { for ( uint32_t I = 0; I < TriangleCount; I ++ ) { STLFILE_VEC3_MULTIPLYSCALAR ( TriangleList [ I ].P1, ScaleMultiplier ); STLFILE_VEC3_MULTIPLYSCALAR ( TriangleList [ I ].P2, ScaleMultiplier ); STLFILE_VEC3_MULTIPLYSCALAR ( TriangleList [ I ].P3, ScaleMultiplier ); } } if ( ( Flags & kFlags_CenterPositions ) != 0 ) { Vec3 PositionOffset ( - 1.0f, - 1.0f, - 1.0f ); if ( ( Flags & kFlags_NormalizePositions ) == 0 ) STLFILE_VEC3_MULTIPLYSCALAR ( PositionOffset, RangeMax ); for ( uint32_t I = 0; I < TriangleCount; I ++ ) { STLFILE_VEC3_ADD ( TriangleList [ I ].P1, PositionOffset ); STLFILE_VEC3_ADD ( TriangleList [ I ].P2, PositionOffset ); STLFILE_VEC3_ADD ( TriangleList [ I ].P3, PositionOffset ); } } }
inline void Trr2kNTNT ( UpperOrLower uplo, Orientation orientationOfB, Orientation orientationOfD, T alpha, const DistMatrix<T,MC,MR>& A, const DistMatrix<T,MC,MR>& B, const DistMatrix<T,MC,MR>& C, const DistMatrix<T,MC,MR>& D, T beta, DistMatrix<T,MC,MR>& E ) { #ifndef RELEASE PushCallStack("internal::Trr2kNTNT"); if( E.Height() != E.Width() || A.Width() != C.Width() || A.Height() != E.Height() || C.Height() != E.Height() || B.Height() != E.Width() || D.Height() != E.Width() || A.Width() != B.Width() || C.Width() != D.Width() ) throw std::logic_error("Nonconformal Trr2kNTNT"); #endif const Grid& g = E.Grid(); DistMatrix<T,MC,MR> AL(g), AR(g), A0(g), A1(g), A2(g); DistMatrix<T,MC,MR> BL(g), BR(g), B0(g), B1(g), B2(g); DistMatrix<T,MC,MR> CL(g), CR(g), C0(g), C1(g), C2(g); DistMatrix<T,MC,MR> DL(g), DR(g), D0(g), D1(g), D2(g); DistMatrix<T,MC, STAR> A1_MC_STAR(g); DistMatrix<T,VR, STAR> B1_VR_STAR(g); DistMatrix<T,STAR,MR > B1AdjOrTrans_STAR_MR(g); DistMatrix<T,MC, STAR> C1_MC_STAR(g); DistMatrix<T,VR, STAR> D1_VR_STAR(g); DistMatrix<T,STAR,MR > D1AdjOrTrans_STAR_MR(g); A1_MC_STAR.AlignWith( E ); B1_VR_STAR.AlignWith( E ); B1AdjOrTrans_STAR_MR.AlignWith( E ); C1_MC_STAR.AlignWith( E ); D1_VR_STAR.AlignWith( E ); D1AdjOrTrans_STAR_MR.AlignWith( E ); LockedPartitionRight( A, AL, AR, 0 ); LockedPartitionRight( B, BL, BR, 0 ); LockedPartitionRight( C, CL, CR, 0 ); LockedPartitionRight( D, DL, DR, 0 ); while( AL.Width() < A.Width() ) { LockedRepartitionRight ( AL, /**/ AR, A0, /**/ A1, A2 ); LockedRepartitionRight ( BL, /**/ BR, B0, /**/ B1, B2 ); LockedRepartitionRight ( CL, /**/ CR, C0, /**/ C1, C2 ); LockedRepartitionRight ( CL, /**/ CR, C0, /**/ C1, C2 ); //--------------------------------------------------------------------// A1_MC_STAR = A1; C1_MC_STAR = C1; B1_VR_STAR = B1; D1_VR_STAR = D1; if( orientationOfB == ADJOINT ) B1AdjOrTrans_STAR_MR.AdjointFrom( B1_VR_STAR ); else B1AdjOrTrans_STAR_MR.TransposeFrom( B1_VR_STAR ); if( orientationOfD == ADJOINT ) D1AdjOrTrans_STAR_MR.AdjointFrom( D1_VR_STAR ); else D1AdjOrTrans_STAR_MR.TransposeFrom( D1_VR_STAR ); LocalTrr2k ( uplo, alpha, A1_MC_STAR, B1AdjOrTrans_STAR_MR, C1_MC_STAR, D1AdjOrTrans_STAR_MR, beta, E ); //--------------------------------------------------------------------// SlideLockedPartitionRight ( DL, /**/ DR, D0, D1, /**/ D2 ); SlideLockedPartitionRight ( CL, /**/ CR, C0, C1, /**/ C2 ); SlideLockedPartitionRight ( BL, /**/ BR, B0, B1, /**/ B2 ); SlideLockedPartitionRight ( AL, /**/ AR, A0, A1, /**/ A2 ); } #ifndef RELEASE PopCallStack(); #endif }