Пример #1
0
/* 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);
}
Пример #2
0
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);
}
Пример #3
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);
   }
Пример #5
0
/*
 * 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__);
}
Пример #6
0
/*
 * 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);
}
Пример #7
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);
}
Пример #8
0
/*
 * 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);
}
Пример #9
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);
        }
Пример #11
0
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 );
    }
}
Пример #12
0
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);
}
Пример #13
0
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;
}
Пример #14
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);
}
Пример #15
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);
}
Пример #16
0
/*
 * 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);
}
Пример #17
0
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;
}
Пример #18
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__);
}
Пример #19
0
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;
}
Пример #20
0
/*
 * 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);
}
Пример #21
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 */
Пример #22
0
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;
}
Пример #24
0
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
}
Пример #25
0
/**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;
}
Пример #26
0
//=======================================================================
//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;
}
Пример #27
0
/* =============================================================== */
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() */
Пример #28
0
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 );
			
		}
		
	}
	
}
Пример #29
0
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
}