示例#1
0
void stat_reset(void)
/* Reset the statusline pointer and clear old messages if expired. */
{
	if (stat_ktl > 0 && --stat_ktl == 0) {
		statusrow= STATUSROW;
		need_help= 1;
	}
	if (need_help && statusrow < (24-2)) {
		if (statusrow > STATUSROW) stat_start(0);
		stat_start(0);
		putstr(
"Type '+' or '-' to change, 'r' to read, '?' for more help, 'q' to exit");
	}
	statusrow= STATUSROW;
	need_help= 0;
}
示例#2
0
/*
 * Fetch a file
 */
static int
fetch(char *URL, const char *path)
{
	struct url *url;
	struct url_stat us;
	struct stat sb, nsb;
	struct xferstat xs;
	FILE *f, *of;
	size_t size, readcnt, wr;
	off_t count;
	char flags[8];
	const char *slash;
	char *tmppath;
	int r;
	unsigned timeout;
	char *ptr;

	f = of = NULL;
	tmppath = NULL;

	timeout = 0;
	*flags = 0;
	count = 0;

	/* set verbosity level */
	if (v_level > 1)
		strcat(flags, "v");
	if (v_level > 2)
		fetchDebug = 1;

	/* parse URL */
	if ((url = fetchParseURL(URL)) == NULL) {
		warnx("%s: parse error", URL);
		goto failure;
	}

	/* if no scheme was specified, take a guess */
	if (*url->scheme == 0) {
		if (*url->host == 0)
			strcpy(url->scheme, SCHEME_FILE);
		else if (strncasecmp(url->host, "ftp.", 4) == 0)
			strcpy(url->scheme, SCHEME_FTP);
		else if (strncasecmp(url->host, "www.", 4) == 0)
			strcpy(url->scheme, SCHEME_HTTP);
	}

	/* common flags */
	switch (family) {
	case PF_INET:
		strcat(flags, "4");
		break;
	case PF_INET6:
		strcat(flags, "6");
		break;
	}

	/* FTP specific flags */
	if (strcmp(url->scheme, SCHEME_FTP) == 0) {
		if (p_flag)
			strcat(flags, "p");
		if (d_flag)
			strcat(flags, "d");
		if (U_flag)
			strcat(flags, "l");
		timeout = T_secs ? T_secs : ftp_timeout;
	}

	/* HTTP specific flags */
	if (strcmp(url->scheme, SCHEME_HTTP) == 0 ||
	    strcmp(url->scheme, SCHEME_HTTPS) == 0) {
		if (d_flag)
			strcat(flags, "d");
		if (A_flag)
			strcat(flags, "A");
		timeout = T_secs ? T_secs : http_timeout;
		if (i_flag) {
			if (stat(i_filename, &sb)) {
				warn("%s: stat()", i_filename);
				goto failure;
			}
			url->ims_time = sb.st_mtime;
			strcat(flags, "i");
		}
	}

	/* set the protocol timeout. */
	fetchTimeout = timeout;

	/* just print size */
	if (s_flag) {
		if (timeout)
			alarm(timeout);
		r = fetchStat(url, &us, flags);
		if (timeout)
			alarm(0);
		if (sigalrm || sigint)
			goto signal;
		if (r == -1) {
			warnx("%s", fetchLastErrString);
			goto failure;
		}
		if (us.size == -1)
			printf("Unknown\n");
		else
			printf("%jd\n", (intmax_t)us.size);
		goto success;
	}

	/*
	 * If the -r flag was specified, we have to compare the local
	 * and remote files, so we should really do a fetchStat()
	 * first, but I know of at least one HTTP server that only
	 * sends the content size in response to GET requests, and
	 * leaves it out of replies to HEAD requests.  Also, in the
	 * (frequent) case that the local and remote files match but
	 * the local file is truncated, we have sufficient information
	 * before the compare to issue a correct request.  Therefore,
	 * we always issue a GET request as if we were sure the local
	 * file was a truncated copy of the remote file; we can drop
	 * the connection later if we change our minds.
	 */
	sb.st_size = -1;
	if (!o_stdout) {
		r = stat(path, &sb);
		if (r == 0 && r_flag && S_ISREG(sb.st_mode)) {
			url->offset = sb.st_size;
		} else if (r == -1 || !S_ISREG(sb.st_mode)) {
			/*
			 * Whatever value sb.st_size has now is either
			 * wrong (if stat(2) failed) or irrelevant (if the
			 * path does not refer to a regular file)
			 */
			sb.st_size = -1;
		}
		if (r == -1 && errno != ENOENT) {
			warnx("%s: stat()", path);
			goto failure;
		}
	}

	/* start the transfer */
	if (timeout)
		alarm(timeout);
	f = fetchXGet(url, &us, flags);
	if (timeout)
		alarm(0);
	if (sigalrm || sigint)
		goto signal;
	if (f == NULL) {
		warnx("%s: %s", URL, fetchLastErrString);
		if (i_flag && strcmp(url->scheme, SCHEME_HTTP) == 0
		    && fetchLastErrCode == FETCH_OK
		    && strcmp(fetchLastErrString, "Not Modified") == 0) {
			/* HTTP Not Modified Response, return OK. */
			r = 0;
			goto done;
		} else
			goto failure;
	}
	if (sigint)
		goto signal;

	/* check that size is as expected */
	if (S_size) {
		if (us.size == -1) {
			warnx("%s: size unknown", URL);
		} else if (us.size != S_size) {
			warnx("%s: size mismatch: expected %jd, actual %jd",
			    URL, (intmax_t)S_size, (intmax_t)us.size);
			goto failure;
		}
	}

	/* symlink instead of copy */
	if (l_flag && strcmp(url->scheme, "file") == 0 && !o_stdout) {
		if (symlink(url->doc, path) == -1) {
			warn("%s: symlink()", path);
			goto failure;
		}
		goto success;
	}

	if (us.size == -1 && !o_stdout && v_level > 0)
		warnx("%s: size of remote file is not known", URL);
	if (v_level > 1) {
		if (sb.st_size != -1)
			fprintf(stderr, "local size / mtime: %jd / %ld\n",
			    (intmax_t)sb.st_size, (long)sb.st_mtime);
		if (us.size != -1)
			fprintf(stderr, "remote size / mtime: %jd / %ld\n",
			    (intmax_t)us.size, (long)us.mtime);
	}

	/* open output file */
	if (o_stdout) {
		/* output to stdout */
		of = stdout;
	} else if (r_flag && sb.st_size != -1) {
		/* resume mode, local file exists */
		if (!F_flag && us.mtime && sb.st_mtime != us.mtime) {
			/* no match! have to refetch */
			fclose(f);
			/* if precious, warn the user and give up */
			if (R_flag) {
				warnx("%s: local modification time "
				    "does not match remote", path);
				goto failure_keep;
			}
		} else if (us.size != -1) {
			if (us.size == sb.st_size)
				/* nothing to do */
				goto success;
			if (sb.st_size > us.size) {
				/* local file too long! */
				warnx("%s: local file (%jd bytes) is longer "
				    "than remote file (%jd bytes)", path,
				    (intmax_t)sb.st_size, (intmax_t)us.size);
				goto failure;
			}
			/* we got it, open local file */
			if ((of = fopen(path, "a")) == NULL) {
				warn("%s: fopen()", path);
				goto failure;
			}
			/* check that it didn't move under our feet */
			if (fstat(fileno(of), &nsb) == -1) {
				/* can't happen! */
				warn("%s: fstat()", path);
				goto failure;
			}
			if (nsb.st_dev != sb.st_dev ||
			    nsb.st_ino != nsb.st_ino ||
			    nsb.st_size != sb.st_size) {
				warnx("%s: file has changed", URL);
				fclose(of);
				of = NULL;
				sb = nsb;
			}
		}
	} else if (m_flag && sb.st_size != -1) {
		/* mirror mode, local file exists */
		if (sb.st_size == us.size && sb.st_mtime == us.mtime)
			goto success;
	}

	if (of == NULL) {
		/*
		 * We don't yet have an output file; either this is a
		 * vanilla run with no special flags, or the local and
		 * remote files didn't match.
		 */

		if (url->offset > 0) {
			/*
			 * We tried to restart a transfer, but for
			 * some reason gave up - so we have to restart
			 * from scratch if we want the whole file
			 */
			url->offset = 0;
			if ((f = fetchXGet(url, &us, flags)) == NULL) {
				warnx("%s: %s", URL, fetchLastErrString);
				goto failure;
			}
			if (sigint)
				goto signal;
		}

		/* construct a temporary file name */
		if (sb.st_size != -1 && S_ISREG(sb.st_mode)) {
			if ((slash = strrchr(path, '/')) == NULL)
				slash = path;
			else
				++slash;
			asprintf(&tmppath, "%.*s.fetch.XXXXXX.%s",
			    (int)(slash - path), path, slash);
			if (tmppath != NULL) {
				if (mkstemps(tmppath, strlen(slash)+1) == -1) {
					warn("%s: mkstemps()", path);
					goto failure;
				}

				of = fopen(tmppath, "w");
				chown(tmppath, sb.st_uid, sb.st_gid);
				chmod(tmppath, sb.st_mode & ALLPERMS);
			}
		}

		if (of == NULL)
			if ((of = fopen(path, "w")) == NULL) {
				warn("%s: fopen()", path);
			goto failure;
		}
	}
	count = url->offset;

	/* start the counter */
	stat_start(&xs, path, us.size, count);

	sigalrm = siginfo = sigint = 0;

	/* suck in the data */
	signal(SIGINFO, sig_handler);
	while (!sigint) {
		if (us.size != -1 && us.size - count < B_size &&
		    us.size - count >= 0)
			size = us.size - count;
		else
			size = B_size;
		if (siginfo) {
			stat_end(&xs);
			siginfo = 0;
		}

		if (size == 0)
			break;

		if ((readcnt = fread(buf, 1, size, f)) < size) {
			if (ferror(f) && errno == EINTR && !sigint)
				clearerr(f);
			else if (readcnt == 0)
				break;
		}

		stat_update(&xs, count += readcnt);
		for (ptr = buf; readcnt > 0; ptr += wr, readcnt -= wr)
			if ((wr = fwrite(ptr, 1, readcnt, of)) < readcnt) {
				if (ferror(of) && errno == EINTR && !sigint)
					clearerr(of);
				else
					break;
			}
		if (readcnt != 0)
			break;
	}
	if (!sigalrm)
		sigalrm = ferror(f) && errno == ETIMEDOUT;
	signal(SIGINFO, SIG_DFL);

	stat_end(&xs);

	/*
	 * If the transfer timed out or was interrupted, we still want to
	 * set the mtime in case the file is not removed (-r or -R) and
	 * the user later restarts the transfer.
	 */
 signal:
	/* set mtime of local file */
	if (!n_flag && us.mtime && !o_stdout && of != NULL &&
	    (stat(path, &sb) != -1) && sb.st_mode & S_IFREG) {
		struct timeval tv[2];

		fflush(of);
		tv[0].tv_sec = (long)(us.atime ? us.atime : us.mtime);
		tv[1].tv_sec = (long)us.mtime;
		tv[0].tv_usec = tv[1].tv_usec = 0;
		if (utimes(tmppath ? tmppath : path, tv))
			warn("%s: utimes()", tmppath ? tmppath : path);
	}

	/* timed out or interrupted? */
	if (sigalrm)
		warnx("transfer timed out");
	if (sigint) {
		warnx("transfer interrupted");
		goto failure;
	}

	/* timeout / interrupt before connection completley established? */
	if (f == NULL)
		goto failure;

	if (!sigalrm) {
		/* check the status of our files */
		if (ferror(f))
			warn("%s", URL);
		if (ferror(of))
			warn("%s", path);
		if (ferror(f) || ferror(of))
			goto failure;
	}

	/* did the transfer complete normally? */
	if (us.size != -1 && count < us.size) {
		warnx("%s appears to be truncated: %jd/%jd bytes",
		    path, (intmax_t)count, (intmax_t)us.size);
		goto failure_keep;
	}

	/*
	 * If the transfer timed out and we didn't know how much to
	 * expect, assume the worst (i.e. we didn't get all of it)
	 */
	if (sigalrm && us.size == -1) {
		warnx("%s may be truncated", path);
		goto failure_keep;
	}

 success:
	r = 0;
	if (tmppath != NULL && rename(tmppath, path) == -1) {
		warn("%s: rename()", path);
		goto failure_keep;
	}
	goto done;
 failure:
	if (of && of != stdout && !R_flag && !r_flag)
		if (stat(path, &sb) != -1 && (sb.st_mode & S_IFREG))
			unlink(tmppath ? tmppath : path);
	if (R_flag && tmppath != NULL && sb.st_size == -1)
		rename(tmppath, path); /* ignore errors here */
 failure_keep:
	r = -1;
	goto done;
 done:
	if (f)
		fclose(f);
	if (of && of != stdout)
		fclose(of);
	if (url)
		fetchFreeURL(url);
	if (tmppath != NULL)
		free(tmppath);
	return (r);
}
示例#3
0
void* non_adaptive_fmm_periodic_ws2(GenericFmmThreadArg *arg)
{
    FmmvHandle *FMMV = arg->fh;
    int thread = arg->thread;    
    Box *box, *box1, *box2;
    int level;
    int i, j, k, jj;
    void (*GEN_M)(FmmvHandle *FMMV, Box *box) = FMMV->gen_M;
    void (*EVAL_L)(FmmvHandle *FMMV, Box *box) = FMMV->eval_L;
    void (*EVAL_DIRECT)(FmmvHandle *FMMV, Box *target, Box *source) = FMMV->eval_direct;
    void (*EVAL_DIRECT_periodic)(FmmvHandle *FMMV, Box *target, Box *source, _FLOAT_ dx, _FLOAT_ dy
	#if (FMM_DIM>=3)
    	, _FLOAT_ dz
	#endif
	) = FMMV->eval_direct_periodic;

    switch(thread) {
    case (FARFIELD_THREAD):
	stat_start(FMMV, STAT_FARFIELD);	
	break;
    case (NEARFIELD_THREAD):
	stat_start(FMMV, STAT_NEARFIELD);	
	break;
    default:	
	break;
    }	
		    
    if ((thread==STANDARD_THREAD)||(thread==FARFIELD_THREAD)) {
	/*** Upward Pass ***/
	/* Form multipole expansions at finest level */
	stat_start(FMMV, STAT_GEN_M);	
	for (box=FMMV->firstSourceBoxOfLevel[FMMV->maxLevel]; box!=0; box=box->nextSourceBox) {
		GEN_M(FMMV, box);
	}
	stat_stop(FMMV, STAT_GEN_M);	

	/* Form multipole expansions at coarser levels by merging */
	stat_start(FMMV, STAT_M2M);	
        init_M2M(FMMV, -1);
	for (level=FMMV->maxLevel-1; level>=0; level--) {/* note: now compute M up to level 0 */
		for (box=FMMV->firstSourceBoxOfLevel[level]; box!=0; box=box->nextSourceBox) {
                        init_M2M(FMMV, level);
			M2M(FMMV, box);
		}	
	}
        finish_M2M(FMMV);
	stat_stop(FMMV, STAT_M2M);	

	/*** Downward Pass ***/
	stat_start(FMMV, STAT_M2L);
        init_M2L(FMMV, -1);
	/******************************************************************/
	FMMV->firstSourceBoxOfLevel[0]->L = (_FLOAT_ *) FMMV_MALLOC(FMMV, FMM_SIZE_OF_L(FMMV->pL)*sizeof(_FLOAT_));

#ifdef USE_PTHREADS
	if (thread==FARFIELD_THREAD) {
		pthread_mutex_lock(&(FMMV->firstSourceBoxOfLevel[0]->mutex));
	}
#endif	
	
	periodic_lattice_M2L(FMMV, FMMV->firstSourceBoxOfLevel[0]->M, FMMV->firstSourceBoxOfLevel[0]->L);

#ifdef USE_PTHREADS
	if (thread==FARFIELD_THREAD) {
		pthread_mutex_unlock(&(FMMV->firstSourceBoxOfLevel[0]->mutex));
	}
#endif	
	FREE_M(FMMV, FMMV->firstSourceBoxOfLevel[0]->M);
	/******************************************************************/
	if (FMMV->reducedScheme) {
		/* we need an artificial parent for root */	
		Box parentOfRoot;
		box = FMMV->firstSourceBoxOfLevel[0];
		parentOfRoot.level = -1;
		box->whichChild=0;
		box->parent=&parentOfRoot;
		for (i=0; i<FMM_CHILDS_PER_BOX; i++) {
			parentOfRoot.child[i] = box;
		}	
		for (i=0; i<26; i++) {
			parentOfRoot.neighbor[i] = &parentOfRoot;
		}
		for (i=0; i<6; i++) {
			parentOfRoot.X[i] = 0;
			parentOfRoot.X2[i] = 0;
		}
                init_M2L(FMMV, 1);
		M2L_ws2_reduced(FMMV, &parentOfRoot);
		box = FMMV->firstSourceBoxOfLevel[0];
		for (i=0; i<FMM_CHILDS_PER_BOX; i++) {
			if (box->child[i]) {
				FREE_M(FMMV, box->child[i]->M);
			}	
		}
		
		for (level=2; level<=FMMV->maxLevel; level++) {
		/* Convert multipole to exponential expansions and shift exponential expansions */
                        init_M2L(FMMV, level);
			for (box=FMMV->firstSourceBoxOfLevel[level-2]; box!=0; box=box->nextSourceBox) {
				M2L_ws2_reduced(FMMV, box);
				for (i=0; i<FMM_CHILDS_PER_BOX; i++) {
					if (box->child[i]) {
						for (j=0; j<FMM_CHILDS_PER_BOX; j++) {
							if (box->child[i]->child[j]) {
								FREE_M(FMMV, box->child[i]->child[j]->M);
							}	
					}	}
				}
			}	
		}
	}	
	else {
		for (level=1; level<=FMMV->maxLevel; level++) {
		/* Convert multipole to exponential expansions and shift exponential expansions */
                        init_M2L(FMMV, level);
			for (box=FMMV->firstSourceBoxOfLevel[level-1]; box!=0; box=box->nextSourceBox) {
				M2L_ws2(FMMV, box);
				for (i=0; i<FMM_CHILDS_PER_BOX; i++) {
					if (box->child[i]) FREE_M(FMMV, box->child[i]->M);
				}
			}	
		}	
	}
        finish_M2L(FMMV);
	stat_stop(FMMV, STAT_M2L);

	/* Shift local expansions from each parent to each of its children */
	stat_start(FMMV, STAT_L2L);	
        init_L2L(FMMV, -1);
	for (level=1; level<=FMMV->maxLevel; level++) {
                init_L2L(FMMV, level-1);
		for (box=FMMV->firstTargetBoxOfLevel[level-1]; box!=0; box=box->nextTargetBox) {
			L2L(FMMV, box);
			FREE_L(FMMV, box->L);
		}	
	}	
        finish_L2L(FMMV);	
	stat_stop(FMMV, STAT_L2L);	
	
	/*** Evaluation of Potentials ***/
	stat_start(FMMV, STAT_EVAL_L);	
	if (thread==STANDARD_THREAD) {
		for (box=FMMV->firstTargetBoxOfLevel[FMMV->maxLevel]; box!=0; box=box->nextTargetBox) {
			/* Evaluate local expansions at finest level */
 			EVAL_L(FMMV, box);
			FREE_L(FMMV, box->L);
                }			
	} /* if (thread==STANDARD_THREAD) */
	#ifdef USE_PTHREADS
	else { /* if (thread==FARFIELD_THREAD) */
		for (box=FMMV->firstTargetBoxOfLevel[FMMV->maxLevel]; box!=0; box=box->nextTargetBox) {
			/* Evaluate local expansions at finest level */
			pthread_mutex_lock(&(box->mutex));
			pthread_mutex_lock(&(box->parent->mutex));
 			EVAL_L(FMMV, box);
			pthread_mutex_unlock(&(box->mutex));
			pthread_mutex_unlock(&(box->parent->mutex));
			FREE_L(FMMV, box->L);
		}	
	} /* if (thread==FARFIELD_THREAD) */
	#endif   
	stat_stop(FMMV, STAT_EVAL_L);	
   } /* if ((thread==STANDARD_THREAD)||(thread==FARFIELD_THREAD)) */

   if (thread==STANDARD_THREAD) {
	stat_start(FMMV, STAT_LIST1);	
	if (FMMV->maxLevel==0) {	
		int dx, dy;
		#if (FMM_DIM>=3)
	        int dz;
		#endif
		box=FMMV->firstTargetBoxOfLevel[0];
		EVAL_DIRECT(FMMV, box, box);
		for (dx=-2; dx<=+2; dx++) {
		for (dy=-2; dy<=+2; dy++) {
		#if (FMM_DIM>=3)
		for (dz=-2; dz<=+2; dz++) {
		#endif
			   if (!((dx==0)&&(dy==0)
				#if (FMM_DIM>=3)
				&&(dz==0)
				#endif
				)) {
				EVAL_DIRECT_periodic(FMMV, box, box, dx, dy
					#if (FMM_DIM>=3)
					, dz
					#endif
					);
			   }	
		#if (FMM_DIM>=3)
		}
		#endif
		}}
	}	
	else {
		for (box=FMMV->firstTargetBoxOfLevel[FMMV->maxLevel-1]; box!=0; box=box->nextTargetBox) {
			EVAL_DIRECT(FMMV, box, box);
		}
		for (box=FMMV->firstTargetBoxOfLevel[FMMV->maxLevel]; box!=0; box=box->nextTargetBox) {
			for (i=0; i<FMM_CHILDS_PER_BOX-1; i++) {
				box1 = box->parent->neighbor[k=theseParentNeighbors[box->whichChild][i]];
				if (isSource(box1)) { /*&& (box1->firstParticle < box->firstParticle) */
					jj=((box->parent->atBoundary) & (boundarysData[k]));
					EVAL_DIRECT_periodic(FMMV, box, box1, pS[jj].dx, pS[jj].dy
						#if (FMM_DIM>=3)
						, pS[jj].dz
						#endif
						);
				}	
			}
			for (i=0; i<N_OTHER_NEIGHBORS; i++) {
				box1 = box->parent->neighbor[k=otherParentNeighborsChilds[box->whichChild][i][0]];
				if (isSource(box1)) {
					jj=((box->parent->atBoundary) & (boundarysData[k]));
					for (j=2; j<otherParentNeighborsChilds[box->whichChild][i][1]+2; j++) {
						box2 = box1->child[otherParentNeighborsChilds[box->whichChild][i][j]];
						EVAL_DIRECT_periodic(FMMV, box, box2, pS[jj].dx, pS[jj].dy
						#if (FMM_DIM>=3)
						, pS[jj].dz
						#endif
						);
					}	
				}
			}
		}	
	}	
	stat_stop(FMMV, STAT_LIST1);	
   } /* if (thread==STANDARD_THREAD) */
   
#ifdef USE_PTHREADS
   if (thread==NEARFIELD_THREAD) {
	stat_start(FMMV, STAT_LIST1);	
	if (FMMV->maxLevel==0) {	
		int dx, dy;
		#if (FMM_DIM>=3)
		int dz;
		#endif
		box=FMMV->firstTargetBoxOfLevel[0];
		pthread_mutex_lock(&(box->mutex));
		EVAL_DIRECT(FMMV, box, box);
		for (dx=-2; dx<=+2; dx++) {
		for (dy=-2; dy<=+2; dy++) {
		#if (FMM_DIM>=3)
		for (dz=-2; dz<=+2; dz++) {
		#endif
			   if (!((dx==0)&&(dy==0)
				#if (FMM_DIM>=3)
				&&(dz==0)
				#endif
				)) {
				EVAL_DIRECT_periodic(FMMV, box, box, dx, dy
					#if (FMM_DIM>=3)
					, dz
					#endif
					);
			   }	
		#if (FMM_DIM>=3)
		}
		#endif
		}}    
		pthread_mutex_unlock(&(box->mutex));
	}
	else {
		for (box=FMMV->firstTargetBoxOfLevel[FMMV->maxLevel-1]; box!=0; box=box->nextTargetBox) {
			pthread_mutex_lock(&(box->mutex));
			EVAL_DIRECT(FMMV, box, box);
			pthread_mutex_unlock(&(box->mutex));
		}
		for (box=FMMV->firstTargetBoxOfLevel[FMMV->maxLevel]; box!=0; box=box->nextTargetBox) {
			pthread_mutex_lock(&(box->mutex));
			if (FMMV->targets) { /* no lock for source boxes */
			    for (i=0; i<FMM_CHILDS_PER_BOX-1; i++) {
				box1 = box->parent->neighbor[k=theseParentNeighbors[box->whichChild][i]];
				if (isSource(box1)) { /*&& (box1->firstParticle < box->firstParticle) */
					jj=((box->parent->atBoundary) & (boundarysData[k]));
					EVAL_DIRECT_periodic(FMMV, box, box1, pS[jj].dx, pS[jj].dy
						#if (FMM_DIM>=3)
						, pS[jj].dz
						#endif
						);
				}
			     }
			     for (i=0; i<N_OTHER_NEIGHBORS; i++) {
				box1 = box->parent->neighbor[k=otherParentNeighborsChilds[box->whichChild][i][0]];
				if (isSource(box1)) { /* && (box1->firstParticle < box->firstParticle)) { */
					jj=((box->parent->atBoundary) & (boundarysData[k]));
					for (j=2; j<otherParentNeighborsChilds[box->whichChild][i][1]+2; j++) {
						box2 = box1->child[otherParentNeighborsChilds[box->whichChild][i][j]];
						if(box2) {
							EVAL_DIRECT_periodic(FMMV, box, box2, pS[jj].dx, pS[jj].dy
								#if (FMM_DIM>=3)
								, pS[jj].dz
								#endif
								);
						}
					}	
				}
			    }
			}
			else {	
			    for (i=0; i<FMM_CHILDS_PER_BOX-1; i++) {
				box1 = box->parent->neighbor[k=theseParentNeighbors[box->whichChild][i]];
				if (isSource(box1)) { /*&& (box1->firstParticle < box->firstParticle) */
					jj=((box->parent->atBoundary) & (boundarysData[k]));
					pthread_mutex_lock(&(box1->mutex));
					EVAL_DIRECT_periodic(FMMV, box, box1, pS[jj].dx, pS[jj].dy
						#if (FMM_DIM>=3)
						, pS[jj].dz
						#endif
						);
					pthread_mutex_unlock(&(box1->mutex));
				}
			     }
			     for (i=0; i<N_OTHER_NEIGHBORS; i++) {
				box1 = box->parent->neighbor[k=otherParentNeighborsChilds[box->whichChild][i][0]];
				if (isSource(box1)) { /* && (box1->firstParticle < box->firstParticle)) { */
					jj=((box->parent->atBoundary) & (boundarysData[k]));
					for (j=2; j<otherParentNeighborsChilds[box->whichChild][i][1]+2; j++) {
						box2 = box1->child[otherParentNeighborsChilds[box->whichChild][i][j]];
						if(box2) {
							pthread_mutex_lock(&(box2->mutex));
							EVAL_DIRECT_periodic(FMMV, box, box2, pS[jj].dx, pS[jj].dy
								#if (FMM_DIM>=3)
								, pS[jj].dz
								#endif
								);
							pthread_mutex_unlock(&(box2->mutex));
						}
					}	
				}
			    }
			}	
			pthread_mutex_unlock(&(box->mutex));
		}	
	}	
	stat_stop(FMMV, STAT_LIST1);	
   } /* if (thread==NEARFIELD_THREAD) */
#endif	

   
   switch(thread) {
   case (FARFIELD_THREAD):
	stat_stop(FMMV, STAT_FARFIELD);	
	break;
   case (NEARFIELD_THREAD):
	stat_stop(FMMV, STAT_NEARFIELD);	
	break;
   default:	
	break;
   }	
   return 0;
}	
示例#4
0
void* non_adaptive_fmm_ws2(GenericFmmThreadArg *arg)
{
    FmmvHandle *FMMV = arg->fh;
    int thread = arg->thread;    
    Box *box, *box1, *box2;
    int level;
    int i, j;
    void (*GEN_M)(FmmvHandle *FMMV, Box *box) = FMMV->gen_M;
    void (*EVAL_L)(FmmvHandle *FMMV, Box *box) = FMMV->eval_L;
    void (*EVAL_DIRECT)(FmmvHandle *FMMV, Box *target, Box *source) = FMMV->eval_direct;

    switch(thread) {
    case (FARFIELD_THREAD):
	stat_start(FMMV, STAT_FARFIELD);	
	break;
    case (NEARFIELD_THREAD):
	stat_start(FMMV, STAT_NEARFIELD);	
	break;
    default:	
	break;
    }	
   
    if ((thread==STANDARD_THREAD)||(thread==FARFIELD_THREAD)) {
	/*** Upward Pass ***/
	/* Form multipole expansions at finest level */
	stat_start(FMMV, STAT_GEN_M);	
	if (FMMV->maxLevel>1) {
		for (box=FMMV->firstSourceBoxOfLevel[FMMV->maxLevel]; box!=0; box=box->nextSourceBox) {
			GEN_M(FMMV, box);
		}
	}
	stat_stop(FMMV, STAT_GEN_M);	

	/* Form multipole expansions at coarser levels by merging */
	stat_start(FMMV, STAT_M2M);
        init_M2M(FMMV, -1);	
	for (level=FMMV->maxLevel-1; level>=2; level--) {
                init_M2M(FMMV, level);
		for (box=FMMV->firstSourceBoxOfLevel[level]; box!=0; box=box->nextSourceBox) {
			M2M(FMMV, box);
		}	
	}
        finish_M2M(FMMV);
	stat_stop(FMMV, STAT_M2M);	

	/*** Downward Pass ***/
	stat_start(FMMV, STAT_M2L);
        init_M2L(FMMV, -1);
	if (FMMV->reducedScheme) {	
		for (level=2; level<=FMMV->maxLevel; level++) {
                init_M2L(FMMV, level);
		/* Convert multipole to exponential expansions and shift exponential expansions */
			for (box=FMMV->firstSourceBoxOfLevel[level-2]; box!=0; box=box->nextSourceBox) {
				M2L_ws2_reduced(FMMV, box);
				for (i=0; i<FMM_CHILDS_PER_BOX; i++) {
					if (box->child[i]) {
						for (j=0; j<FMM_CHILDS_PER_BOX; j++) {
							if (box->child[i]->child[j]) {
								FREE_M(FMMV, box->child[i]->child[j]->M);
							}
						}	
					}	
				}
			}	
		}
	}	
	else {
		for (level=2; level<=FMMV->maxLevel; level++) {
                init_M2L(FMMV, level);
		/* Convert multipole to exponential expansions and shift exponential expansions */
			for (box=FMMV->firstSourceBoxOfLevel[level-1]; box!=0; box=box->nextSourceBox) {
				M2L_ws2(FMMV, box);
				for (i=0; i<FMM_CHILDS_PER_BOX; i++) {
					if (box->child[i]) FREE_M(FMMV, box->child[i]->M);
				}
			}	
		}	
	}
        finish_M2L(FMMV);
	stat_stop(FMMV, STAT_M2L);	

	/* Shift local expansions from each parent to each of its children */
	stat_start(FMMV, STAT_L2L);
        init_L2L(FMMV, -1);
	for (level=2; level<=FMMV->maxLevel; level++) {
                init_L2L(FMMV, level-1);
		for (box=FMMV->firstTargetBoxOfLevel[level-1]; box!=0; box=box->nextTargetBox) {
			L2L(FMMV, box);
			FREE_L(FMMV, box->L);
		}	
	}
        finish_L2L(FMMV);
	stat_stop(FMMV, STAT_L2L);	
	
	/*** Evaluation of Potentials ***/
	stat_start(FMMV, STAT_EVAL_L);	
	if (thread==STANDARD_THREAD) {
		if (FMMV->maxLevel>1) {
			for (box=FMMV->firstTargetBoxOfLevel[FMMV->maxLevel]; box!=0; box=box->nextTargetBox) {
				/* Evaluate local expansions at finest level */
 				EVAL_L(FMMV, box);
				FREE_L(FMMV, box->L);
                	}			
		}
	} /* if (thread==STANDARD_THREAD) */
	#ifdef USE_PTHREADS
	else { /* if (thread==FARFIELD_THREAD) */
		if (FMMV->maxLevel>1) {
			for (box=FMMV->firstTargetBoxOfLevel[FMMV->maxLevel]; box!=0; box=box->nextTargetBox) {
				/* Evaluate local expansions at finest level */
				pthread_mutex_lock(&(box->parent->mutex));
				pthread_mutex_lock(&(box->mutex));
 				EVAL_L(FMMV, box);
				pthread_mutex_unlock(&(box->mutex));
				pthread_mutex_unlock(&(box->parent->mutex));
				FREE_L(FMMV, box->L);
			}	
		}	
	} /* if (thread==FARFIELD_THREAD) */
	#endif   
	stat_stop(FMMV, STAT_EVAL_L);	
   } /* if ((thread==STANDARD_THREAD)||(thread==FARFIELD_THREAD)) */

   if (thread==STANDARD_THREAD) {
	stat_start(FMMV, STAT_LIST1);	
	if (FMMV->maxLevel<=1) {	
		box=FMMV->firstTargetBoxOfLevel[0];
		EVAL_DIRECT(FMMV, box, box);
	}
	else {
		for (box=FMMV->firstTargetBoxOfLevel[FMMV->maxLevel-1]; box!=0; box=box->nextTargetBox) {
			EVAL_DIRECT(FMMV, box, box);
		}
		for (box=FMMV->firstTargetBoxOfLevel[FMMV->maxLevel]; box!=0; box=box->nextTargetBox) {
			for (i=0; i<FMM_CHILDS_PER_BOX-1; i++) {
				box1 = box->parent->neighbor[theseParentNeighbors[box->whichChild][i]];
				EVAL_DIRECT(FMMV, box, box1);
			}
			for (i=0; i<N_OTHER_NEIGHBORS; i++) {
				box1 = box->parent->neighbor[otherParentNeighborsChilds[box->whichChild][i][0]];
				if (isSource(box1)) {
					for (j=2; j<otherParentNeighborsChilds[box->whichChild][i][1]+2; j++) {
						box2 = box1->child[otherParentNeighborsChilds[box->whichChild][i][j]];
						EVAL_DIRECT(FMMV, box, box2);
					}	
				}
			}
		}	
	}	
	stat_stop(FMMV, STAT_LIST1);	
   } /* if (thread==STANDARD_THREAD) */

#ifdef USE_PTHREADS
   if (thread==NEARFIELD_THREAD) {
	stat_start(FMMV, STAT_LIST1);	
	if (FMMV->maxLevel<=1) {	
		box=FMMV->firstTargetBoxOfLevel[0];
		EVAL_DIRECT(FMMV, box, box);
	}
	else {
		for (box=FMMV->firstTargetBoxOfLevel[FMMV->maxLevel-1]; box!=0; box=box->nextTargetBox) {
			pthread_mutex_lock(&(box->mutex));
			EVAL_DIRECT(FMMV, box, box);
			pthread_mutex_unlock(&(box->mutex));
		}
		for (box=FMMV->firstTargetBoxOfLevel[FMMV->maxLevel]; box!=0; box=box->nextTargetBox) {
			pthread_mutex_lock(&(box->mutex));
			if (FMMV->targets) { /* no lock for source boxes */
			    for (i=0; i<FMM_CHILDS_PER_BOX-1; i++) {
				box1 = box->parent->neighbor[theseParentNeighbors[box->whichChild][i]];
				if (box1) {
					EVAL_DIRECT(FMMV, box, box1);
				}
			    }
			    for (i=0; i<N_OTHER_NEIGHBORS; i++) {
				box1 = box->parent->neighbor[otherParentNeighborsChilds[box->whichChild][i][0]];
				if (isSource(box1)) {
					for (j=2; j<otherParentNeighborsChilds[box->whichChild][i][1]+2; j++) {
						box2 = box1->child[otherParentNeighborsChilds[box->whichChild][i][j]];
						if (box2) {
							EVAL_DIRECT(FMMV, box, box2);
						}
					}	
				}
			    }	
			}
			else {	
			    for (i=0; i<FMM_CHILDS_PER_BOX-1; i++) {
				box1 = box->parent->neighbor[theseParentNeighbors[box->whichChild][i]];
				if (box1) {
					pthread_mutex_lock(&(box1->mutex));
					EVAL_DIRECT(FMMV, box, box1);
					pthread_mutex_unlock(&(box1->mutex));
				}
			    }
			    for (i=0; i<N_OTHER_NEIGHBORS; i++) {
				box1 = box->parent->neighbor[otherParentNeighborsChilds[box->whichChild][i][0]];
				if (isSource(box1)) {
					for (j=2; j<otherParentNeighborsChilds[box->whichChild][i][1]+2; j++) {
						box2 = box1->child[otherParentNeighborsChilds[box->whichChild][i][j]];
						if (box2) {
							pthread_mutex_lock(&(box2->mutex));
							EVAL_DIRECT(FMMV, box, box2);
							pthread_mutex_unlock(&(box2->mutex));
						}
					}	
				}
			    }	
			}
			pthread_mutex_unlock(&(box->mutex));
		}	
	}	
	stat_stop(FMMV, STAT_LIST1);	
   } /* if (thread==NEARFIELD_THREAD) */
#endif	
   
   switch(thread) {
   case (FARFIELD_THREAD):
	stat_stop(FMMV, STAT_FARFIELD);	
	break;
   case (NEARFIELD_THREAD):
	stat_stop(FMMV, STAT_NEARFIELD);	
	break;
   default:	
	break;
   }	
   return 0;
}
示例#5
0
/***** INITIALIZE ********************************************************/	
char* fmmv_initialize(FmmvHandle **fh, struct FmmvOptions *options, struct FmmvStatistics *statistics)	
{
	int err;
	struct FmmvOptions _options;
	FmmvHandle *FMMV = *fh;
	
	if (!options) {
		_options = fmmvGetDefaultOptions();
		options = &_options;
	}	
	FMMV->statistics.PAPIeventSet = options->PAPIeventSet;
	stat_init(FMMV);
	stat_start(FMMV, STAT_TOTAL);
	stat_start(FMMV, STAT_INITIALIZE);
	if (!FMMV) goto _err;

	/* TODO: check options */
	FMMV->beta = options->beta;
	FMMV->pM = options->pM;
	FMMV->pL = options->pL;
	FMMV->s_eps = options->s;
	FMMV->ws = options->ws;
	FMMV->splitThreshold = options->splitThreshold;
	FMMV->splitTargetThreshold = options->splitTargetThreshold;
	FMMV->maxLevel = options->levels;
	FMMV->directEvalThreshold = options->directEvalThreshold;
	FMMV->periodicBoundaryConditions = options->periodicBoundaryConditions;
	FMMV->extrinsicCorrection = options->extrinsicCorrection;
	FMMV->scale = (_FLOAT_) options->scale;
	FMMV->useHilbertOrder = options->useHilbertOrder;
	FMMV->directEvalAccuracy = options->directEvalAccuracy;
	FMMV->useFarfieldNearfieldThreads = options->useFarfieldNearfieldThreads;
	FMMV->reducedScheme = options->reducedScheme;

	FMMV->lambda = 0;
/* TODO: handle addtitional options */
/*
	if (options->x) { // TODO: no global variables!!!
		for (i=0; i<FMMV->s_eps; i++) {
			user_defined_x[i] = (_FLOAT_) options->x[i];
			user_defined_w[i] = (_FLOAT_) options->w[i];
			user_defined_M[i] = (_FLOAT_) options->M[i];
		}
		FMMV->lambda = user_defined_x;
		FMMV->w = user_defined_w;
		FMMV->M = user_defined_M;
	}	
*/

	/* TODO: search for best values: */
	if (FMMV->splitThreshold==-1) FMMV->splitThreshold = 200; /* TODO: find precision-, dipole_grad-, etc.- dependent better value */
	if (FMMV->splitTargetThreshold==-1) FMMV->splitTargetThreshold = 200; /* TODO: find precision-, dipole_grad-, etc.- dependent better value */
	if (FMMV->splitThreshold==0) FMMV->splitTargetThreshold = 0; /* non adaptive FMM! */

	#if (FMM_PRECISION==0)
	if (FMMV->maxLevel==-1) FMMV->maxLevel = 22;
	#elif (FMM_PRECISION==1)
	if (FMMV->maxLevel==-1) FMMV->maxLevel = 51;
	#endif
	if (FMMV->directEvalThreshold==-1) FMMV->directEvalThreshold = 200; /* TODO: find precision-, dipole_grad-, etc.- dependent better value */
	
	FMMV->allocatedMemory = 0;
	FMMV->maxAllocatedMemory = 0;

	FMMV->noOfDirectInteractions = 0;

	init_all(FMMV); 

	stat_start(FMMV, STAT_BUILD_TREE); 

	FMMV->perm = (int *) FMMV_MALLOC(FMMV, FMMV->NParticles*sizeof(int));
	if (FMMV->perm==0) goto _err;

	if (FMMV->targets) {
		FMMV->permTargets = (int *) FMMV_MALLOC(FMMV, FMMV->NTargets*sizeof(int));
		if (FMMV->permTargets==0) goto _err;
	
		err = buildTree_ST(FMMV);
		if (err) goto _err;
	}
	else {
		FMMV->permTargets = FMMV->perm;
		err = buildTree(FMMV);
		if (err) goto _err;
	}	
	stat_stop(FMMV, STAT_BUILD_TREE); 

	if (FMMV->targets) {
        	FMMV->maxTargetLevel = FMMV->maxLevel;
        	for (; FMMV->firstSourceBoxOfLevel[FMMV->maxLevel] == 0; FMMV->maxLevel--)
			;
        	for (; FMMV->firstTargetBoxOfLevel[FMMV->maxTargetLevel] == 0; FMMV->maxTargetLevel--)
                	;

		genTreeStatistics_ST(FMMV);
	}	
	else {
        	for (; FMMV->firstSourceBoxOfLevel[FMMV->maxLevel] == 0; FMMV->maxLevel--)
			;

		genTreeStatistics(FMMV);
		FMMV->statistics.noOfTargets = -1;
		FMMV->statistics.noOfTargetLevels = -1;
		FMMV->statistics.noOfTargetBoxes = -1;
		FMMV->statistics.noOfTargetLeafBoxes = -1;
		FMMV->statistics.averageNoOfTargetsPerLeafBox = -1;
	}	

	ida_allocate(FMMV);
	copy_particles(FMMV);

	stat_stop(FMMV, STAT_INITIALIZE);
	if (statistics) {
		*statistics = FMMV->statistics;
		statistics->maxAllocatedMemory = FMMV->maxAllocatedMemory;
		statistics->noOfDirectInteractions = FMMV->noOfDirectInteractions;
		statistics->PAPIeventSet = FMMV->statistics.PAPIeventSet;
	}

	*fh = (void*) FMMV;
	return 0;
_err:
	return errbuf;	
}	
示例#6
0
/***** EVALUATE ********************************************************/
char* fmmv_evaluate(FmmvHandle *FMMV, struct FmmvStatistics *statistics)
{
	GenericFmmThreadArg STANDARD_THREAD, FARFIELD_THREAD, NEARFIELD_THREAD;
#ifdef USE_PTHREADS
	pthread_t nearfield_thread;
#endif	
	int err;
	
	stat_start(FMMV, STAT_EVALUATE);

	FMMV->noOfStoredXin = 0;
	FMMV->maxNoOfStoredXin = 0;

	STANDARD_THREAD.fh = FMMV;
	FARFIELD_THREAD.fh = FMMV;
	NEARFIELD_THREAD.fh = FMMV;
	STANDARD_THREAD.thread = 0;
	FARFIELD_THREAD.thread = 1;
	NEARFIELD_THREAD.thread = 2;

	copy_charges(FMMV);
	zero_pot(FMMV);
	
	if (FMMV->useFarfieldNearfieldThreads) {
#ifdef USE_PTHREADS	
	   if (FMMV->useFarfieldNearfieldThreads<0) { /* test mode */
#endif	   
		if (FMMV->periodicBoundaryConditions) {
			if (FMMV->splitThreshold == 0) {
			    if (FMMV->ws == 1) {	
					non_adaptive_fmm_periodic(&FARFIELD_THREAD);
					non_adaptive_fmm_periodic(&NEARFIELD_THREAD);
			    }
			    else { /* FMMV->ws == 2 */
					non_adaptive_fmm_periodic_ws2(&FARFIELD_THREAD);
					non_adaptive_fmm_periodic_ws2(&NEARFIELD_THREAD);
			    }

			}
			else {
				assert(0);
				/* adaptive_fmm_periodic - not yet implemented... */
			}
		} 
		else {
			if (FMMV->splitThreshold == 0) {
			    if (FMMV->ws == 1) {	
					non_adaptive_fmm(&FARFIELD_THREAD);
					non_adaptive_fmm(&NEARFIELD_THREAD);
			    }
			    else { /* FMMV->ws == 2 */
					non_adaptive_fmm_ws2(&FARFIELD_THREAD);
					non_adaptive_fmm_ws2(&NEARFIELD_THREAD);
			    }
			}
			else {
			    if (FMMV->ws == 1) {	
				if (FMMV->targets) {
					adaptive_fmm_ST(&FARFIELD_THREAD);
					adaptive_fmm_ST(&NEARFIELD_THREAD);
				}
				else {
					adaptive_fmm(&FARFIELD_THREAD);
					adaptive_fmm(&NEARFIELD_THREAD);
				}
			    }
			    else { /* FMMV->ws == 2 */
				assert(0); 
				/*adaptive_fmm_ws2 not yet implemented */
			    }
			}
		}
#ifdef USE_PTHREADS	
	   }
	   else {
		if (FMMV->periodicBoundaryConditions) {
			if (FMMV->splitThreshold == 0) {
			    if (FMMV->ws == 1) {	
					/* TODO error handling ... */
					err =  pthread_create(&nearfield_thread, 0, 
							(void* (*)(void *))
							non_adaptive_fmm_periodic, (void*) &NEARFIELD_THREAD);
					non_adaptive_fmm_periodic(&FARFIELD_THREAD);
			    }
			    else { /* FMMV->ws == 2 */
					/* TODO error handling ... */
					err =  pthread_create(&nearfield_thread, 0, 
							(void* (*)(void *))
							non_adaptive_fmm_periodic_ws2, (void*) &NEARFIELD_THREAD);
					non_adaptive_fmm_periodic_ws2(&FARFIELD_THREAD);
			    }
			}
			else {
				assert(0);
				/* adaptive_fmm_periodic - not yet implemented... */
			}
		} 
		else {
			if (FMMV->splitThreshold == 0) {
			    if (FMMV->ws == 1) {	
					err =  pthread_create(&nearfield_thread, 0, 
							(void* (*)(void *))
							non_adaptive_fmm, (void*) &NEARFIELD_THREAD);
					non_adaptive_fmm(&FARFIELD_THREAD);
			    }
			    else { /* FMMV->ws == 2 */
					err =  pthread_create(&nearfield_thread, 0, 
							(void* (*)(void *))
							non_adaptive_fmm_ws2, (void*) &NEARFIELD_THREAD);
					non_adaptive_fmm_ws2(&FARFIELD_THREAD);
			    }
			}
			else {
			    if (FMMV->ws == 1) {	
				if (FMMV->targets) {
					err =  pthread_create(&nearfield_thread, 0, 
							(void* (*)(void *))
							adaptive_fmm_ST, (void*) &NEARFIELD_THREAD);
					adaptive_fmm_ST(&FARFIELD_THREAD);
				}
				else {
					err =  pthread_create(&nearfield_thread, 0, 
							(void* (*)(void *))
							adaptive_fmm, (void*) &NEARFIELD_THREAD);
					adaptive_fmm(&FARFIELD_THREAD);
				}
			    }
			    else { /* FMMV->ws == 2 */
				assert(0); 
				/* adaptive_fmm_ws2 not yet implemented */
			    }
			}
		}
		pthread_join(nearfield_thread, 0);
	    }	
#endif	   
	}
	else {
		if (FMMV->periodicBoundaryConditions) {
			if (FMMV->splitThreshold == 0) {
			    if (FMMV->ws == 1) {	
					non_adaptive_fmm_periodic(&STANDARD_THREAD);
			    }
			    else { /* FMMV->ws == 2 */
					non_adaptive_fmm_periodic_ws2(&STANDARD_THREAD);
			    }
			}
			else {
				assert(0);
				/* adaptive_fmm_periodic - not yet implemented... */
			}
		} 
		else {
			if (FMMV->splitThreshold == 0) {
			    if (FMMV->ws == 1) {	
					non_adaptive_fmm(&STANDARD_THREAD);
			    }
			    else { /* FMMV->ws == 2 */
					non_adaptive_fmm_ws2(&STANDARD_THREAD);
			    }
			}
			else {
			    if (FMMV->ws == 1) {	
				if (FMMV->targets) {
					adaptive_fmm_ST(&STANDARD_THREAD);
				}	
				else {	
					adaptive_fmm(&STANDARD_THREAD);
				}
			    }
			    else { /* FMMV->ws == 2 */
				assert(0); 
				/* adaptive_fmm_ws2 not yet implemented */
			    }
			}
		}
	}
	
	if (FMMV->periodicBoundaryConditions && FMMV->extrinsicCorrection) {
		FMMV->extrinsic_correction(FMMV);
	}

	backcopy_pot(FMMV);

	if (FMMV->targets==0) {
		FMMV->noOfDirectInteractions *= 2;
	}

	stat_stop(FMMV, STAT_EVALUATE);
	if (statistics) {
		*statistics = FMMV->statistics;
		statistics->maxNoOfStoredXin = FMMV->maxNoOfStoredXin;
		statistics->maxAllocatedMemory = FMMV->maxAllocatedMemory;
		statistics->noOfDirectInteractions = FMMV->noOfDirectInteractions;
		statistics->PAPIeventSet = FMMV->statistics.PAPIeventSet;
	}
	return 0;
/*  //TODO: error handling
_err:
	return errbuf;	
*/
	
}