/* find key/data */ unsigned int mmtree64_find(void *x, int rootid, int64_t key, int *data) { unsigned int id = 0; if(x && rootid > 0) { mmtree64_mutex_lock(x, rootid); if(MMT(x)->map && MMT(x)->state && rootid < MMTREE64_ROOT_MAX && MMT(x)->state->roots[rootid].status > 0) { //fprintf(stdout, "%s::%d rootid:%d key:%d data:%d total:%d\n", __FILE__, __LINE__, rootid, key, *data, MMT(x)->state->total); id = MMT(x)->state->roots[rootid].rootid; while(id > 0 && id < MMT(x)->state->total) { if(key == MMT(x)->map[id].key) { if(data) *data = MMT(x)->map[id].data; break; } else if(key > MMT(x)->map[id].key) { id = MMT(x)->map[id].right; } else { id = MMT(x)->map[id].left; } } } //fprintf(stdout, "%s::%d rootid:%d key:%d data:%d\n", __FILE__, __LINE__, rootid, key, *data); mmtree64_mutex_unlock(x, rootid); } return id; }
/* insert new node */ unsigned int mmtree64_insert(void *x, int rootid, int64_t key, int data, int *old) { unsigned int id = 0, nodeid = 0, rid = 0, lid = 0, uid = 0, pid = 0, gpid = 0, ppid = 0, *prootid = NULL; MTNODE64 *node = NULL; if(x && rootid > 0) { mmtree64_mutex_lock(x, rootid); if(MMT(x)->state && MMT(x)->map && rootid < MMTREE64_ROOT_MAX && MMT(x)->state->roots[rootid].status > 0) { nodeid = MMT(x)->state->roots[rootid].rootid; while(nodeid > 0 && nodeid < MMT(x)->state->total) { node = &(MMT(x)->map[nodeid]); if(key == node->key) { id = nodeid; if(old) *old = node->data; node->data = data; goto end; } else if(key > node->key) { if(node->right == 0) break; nodeid = node->right; } else { if(node->left == 0) break; nodeid = node->left; } } //new node if(id == 0) id = mmtree64_new_node(x, rootid, nodeid, key, data); } if((nodeid = id) > 0) { if(MMT(x)->state->roots[rootid].rootid > 0) { prootid = &(MMT(x)->state->roots[rootid].rootid); MMT(x)->map[nodeid].color = MMT_COLOR_RED; MMT_INSERT_COLOR(x, prootid, nodeid, lid, rid, uid, pid, gpid, ppid); } else { MMT(x)->state->roots[rootid].rootid = nodeid; } } end: mmtree64_mutex_unlock(x, rootid); } return id; }
/* get tree->min key/data */ unsigned int mmtree64_min(void *x, int rootid, int64_t *key, int *data) { unsigned int id = 0; if(x && rootid > 0) { mmtree64_mutex_lock(x, rootid); if(MMT(x)->map && MMT(x)->state && rootid < MMTREE64_ROOT_MAX && MMT(x)->state->roots[rootid].status > 0) { id = MMT(x)->state->roots[rootid].rootid; while(MMT(x)->map[id].left > 0) { id = MMT(x)->map[id].left; } if(id > 0 && MMT(x)->state->total) { if(key) *key = MMT(x)->map[id].key; if(data) *data = MMT(x)->map[id].data; } } mmtree64_mutex_unlock(x, rootid); } return id; }
/* try insert node */ unsigned int mmtree64_try_insert(void *x, int rootid, int64_t key, int data, int *old) { unsigned int id = 0, nodeid = 0, rid = 0, lid = 0, uid = 0, pid = 0, gpid = 0, ppid = 0, *prootid = NULL; MTNODE64 *node = NULL; if(x && rootid > 0) { mmtree64_mutex_lock(x, rootid); if(MMT(x)->state && MMT(x)->map && rootid < MMTREE64_ROOT_MAX && MMT(x)->state->roots[rootid].status > 0) { nodeid = MMT(x)->state->roots[rootid].rootid; while(nodeid > 0 && nodeid < MMT(x)->state->total) { node = &(MMT(x)->map[nodeid]); if(key == node->key) { id = nodeid; if(old) *old = node->data; //fprintf(stdout, "%s::%d id:%d key:%lld old[%lld]->data:%d\n", __FILE__, __LINE__, nodeid, (long long)key, (long long)node->key, node->data); goto end; } else if(key > node->key) { if(node->right == 0) break; nodeid = node->right; } else { if(node->left == 0) break; nodeid = node->left; } } } if(id == 0) id = mmtree64_new_node(x, rootid, nodeid, key, data); if((nodeid = id) > 0) { if(MMT(x)->state->roots[rootid].rootid > 0) { prootid = &(MMT(x)->state->roots[rootid].rootid); MMT(x)->map[nodeid].color = MMT_COLOR_RED; MMT_INSERT_COLOR(x, prootid, nodeid, lid, rid, uid, pid, gpid, ppid); } else { MMT(x)->state->roots[rootid].rootid = nodeid; } } end: mmtree64_mutex_unlock(x, rootid); } return id; }
/* get tree->max key/data */ unsigned int mmtree64_max(void *x, int rootid, int64_t *key, int *data) { unsigned int id = 0, tmp = 0; if(x && rootid > 0) { mmtree64_mutex_lock(x, rootid); if(MMT(x)->map && MMT(x)->state && rootid < MMTREE64_ROOT_MAX && MMT(x)->state->roots[rootid].status > 0) { tmp = MMT(x)->state->roots[rootid].rootid; do { id = tmp; }while(id > 0 && (tmp = MMT(x)->map[id].right) > 0); if(id > 0 && MMT(x)->state->total) { if(key) *key = MMT(x)->map[id].key; if(data) *data = MMT(x)->map[id].data; } } mmtree64_mutex_unlock(x, rootid); } return id; }
void mmtree64_view_tree(void *x, int rootid, FILE *fp) { if(x && rootid > 0) { mmtree64_mutex_lock(x, rootid); if(MMT(x)->map && MMT(x)->state && rootid < MMTREE64_ROOT_MAX) { fprintf(stdout, "%s::%d rootid:%d\n", __FILE__, __LINE__, MMT(x)->state->roots[rootid].rootid); mmtree64_view_tnode(x, MMT(x)->state->roots[rootid].rootid, fp); } mmtree64_mutex_unlock(x, rootid); } return ; }
/* remove tree */ void mmtree64_remove_tree(void *x, int rootid) { if(x && rootid > 0 && rootid < MMTREE64_ROOT_MAX) { mmtree64_mutex_lock(x, rootid); mmtree64_remove_tnode(x, MMT(x)->state->roots[rootid].rootid); MMT(x)->state->roots[rootid].rootid = 0; MMT(x)->state->roots[rootid].status = 0; //fprintf(stdout, "%s::%d rootid:%d start:%p state:%p map:%p current:%d left:%d total:%d qleft:%d qfirst:%d qlast:%d\n", __FILE__, __LINE__, rootid, MMT(x)->start, MMT(x)->state, MMT(x)->map, MMT(x)->state->current, MMT(x)->state->left, MMT(x)->state->total, MMT(x)->state->qleft, MMT(x)->state->qfirst, MMT(x)->state->qlast); mmtree64_mutex_unlock(x, rootid); } return ; }
/* total */ unsigned int mmtree64_total(void *x, int rootid) { unsigned int total = 0; if(x && rootid > 0) { MUTEX_LOCK(MMT(x)->mutex); if(MMT(x)->state && MMT(x)->map && rootid < MMTREE64_ROOT_MAX) { total = MMT(x)->state->roots[rootid].total; } MUTEX_UNLOCK(MMT(x)->mutex); } return total; }
/* view node */ void mmtree64_view_tnode(void *x, unsigned int tnodeid, FILE *fp) { if(x) { if(MMT(x)->map[tnodeid].left > 0 && MMT(x)->map[tnodeid].left < MMT(x)->state->total) { mmtree64_view_tnode(x, MMT(x)->map[tnodeid].left, fp); } fprintf(fp, "[%d:%lld:%d]\n", tnodeid, (long long)MMT(x)->map[tnodeid].key, MMT(x)->map[tnodeid].data); if(MMT(x)->map[tnodeid].right > 0 && MMT(x)->map[tnodeid].right < MMT(x)->state->total) { mmtree64_view_tnode(x, MMT(x)->map[tnodeid].right, fp); } } return ; }
void mmtree64_mutex_unlock(void *x, int id) { if(x) { #ifdef HAVE_PTHREAD pthread_mutex_unlock(&(MMT(x)->mutexs[id%MMTREE64_MUTEX_MAX])); #endif } return ; }
//close mmtree void mmtree64_close(void *x) { int i = 0; if(x) { //fprintf(stdout, "%s::%d start:%p state:%p map:%p current:%d left:%d total:%d qleft:%d qfirst:%d qlast:%d sizeof(MTSTATE64):%d\n", __FILE__, __LINE__, MMT(x)->start, MMT(x)->state, MMT(x)->map, MMT(x)->state->current, MMT(x)->state->left, MMT(x)->state->total, MMT(x)->state->qleft, MMT(x)->state->qfirst, MMT(x)->state->qlast, sizeof(MTSTATE64)); MMT_MUNMAP(x); MUTEX_DESTROY(MMT(x)->mutex); #ifdef HAVE_PTHREAD for(i = 0; i < MMTREE64_MUTEX_MAX; i++) { pthread_mutex_destroy(&(MMT(x)->mutexs[i])); } #endif if(MMT(x)->fd) close(MMT(x)->fd); free(x); } return ; }
/* remove node */ void mmtree64_remove_tnode(void *x, unsigned int tnodeid) { if(x) { if(MMT(x)->map[tnodeid].left > 0 && MMT(x)->map[tnodeid].left < MMT(x)->state->total) { mmtree64_remove_tnode(x, MMT(x)->map[tnodeid].left); } if(MMT(x)->map[tnodeid].right > 0 && MMT(x)->map[tnodeid].right < MMT(x)->state->total) { mmtree64_remove_tnode(x, MMT(x)->map[tnodeid].right); } mmtree64_qleft(x, tnodeid); } return ; }
/* init mmtree */ void *mmtree64_init(char *file) { int i = 0; void *x = NULL; struct stat st = {0}; if((x = (MMTREE64 *)calloc(1, sizeof(MMTREE64)))) { if((MMT(x)->fd = open(file, O_CREAT|O_RDWR, 0644)) > 0 && fstat(MMT(x)->fd, &st) == 0) { MUTEX_INIT(MMT(x)->mutex); MMT(x)->end = st.st_size; MMT(x)->size = (off_t)sizeof(MTSTATE64) + (off_t)sizeof(MTNODE64) * (off_t)MMTREE64_NODES_MAX; //mmap MMT_MMAP(x); //init truncate if(st.st_size == 0) { MMT(x)->end = (off_t)sizeof(MTSTATE64); MMT_INCRE(x); } /* initialize mutexs */ #ifdef HAVE_PTHREAD for(i = 0; i < MMTREE64_MUTEX_MAX; i++) { pthread_mutex_init(&(MMT(x)->mutexs[i]), NULL); } #endif } else { if(MMT(x)->fd > 0) close(MMT(x)->fd); free(x); x = NULL; } } return x; }
/* set data */ int mmtree64_set_data(void *x, unsigned int tnodeid, int data) { int old = -1; if(x && tnodeid > 0) { MUTEX_LOCK(MMT(x)->mutex); if(MMT(x)->map && MMT(x)->state && tnodeid < MMT(x)->state->total) { old = MMT(x)->map[tnodeid].data; MMT(x)->map[tnodeid].data = data; } MUTEX_UNLOCK(MMT(x)->mutex); } return old; }
int CG(double* Phi, double* X, double* K, int numProcs, int myID) { double* R = new double[TOT]; double* P = new double[TOT]; double* Ap = new double[TOT]; double* temBuf = new double[TOT]; int n = 0; MPI_Setzero(X, numProcs, myID); MPI_Assign(Phi, R, numProcs, myID); MPI_Assign(R, P, numProcs, myID); double rnrn = MPI_Dot(R, R, numProcs, myID); while((rnrn>Accuracy) && (n<N_iter)) { MMT(P, Ap, K, numProcs, myID); double a = rnrn/MPI_Dot(P, Ap, numProcs, myID); MPI_Multiply(P, a, temBuf, numProcs, myID); MPI_Add(X, temBuf, X, numProcs, myID); MPI_Multiply(Ap, a, temBuf, numProcs, myID); MPI_Subtract(R, temBuf, R, numProcs, myID); double b = MPI_Dot(R, R, numProcs, myID)/rnrn; MPI_Multiply(P, b, temBuf, numProcs, myID); MPI_Add(R, temBuf, P, numProcs, myID); rnrn = MPI_Dot(R, R, numProcs, myID); n++; } if(myID == ROOT) { ofstream file_log("evolution.log", ios_base::app); file_log<<n<<endl; file_log.close(); } delete [] R; delete [] P; delete [] Ap; delete [] temBuf; if(n == N_iter) { return 0; } else { return 1; } }
/* insert new root */ int mmtree64_new_tree(void *x) { int id = 0, i = 0; if(x) { MUTEX_LOCK(MMT(x)->mutex); if(MMT(x)->state->nroots == 0) MMT(x)->state->nroots = 1; if(MMT(x)->state && MMT(x)->state->nroots < MMTREE64_ROOT_MAX) { for(i = 1; i < MMTREE64_ROOT_MAX; i++) { if(MMT(x)->state->roots[i].status == 0) { MMT(x)->state->roots[i].status = 1; MMT(x)->state->nroots++; id = i; break; } } } MUTEX_UNLOCK(MMT(x)->mutex); } return id; }
/* get node key/data */ unsigned int mmtree64_get(void *x, unsigned int tnodeid, int64_t *key, int *data) { unsigned int id = 0; if(x && tnodeid > 0) { MUTEX_LOCK(MMT(x)->mutex); if(MMT(x)->map && MMT(x)->state && tnodeid < MMT(x)->state->total) { if(key) *key = MMT(x)->map[tnodeid].key; if(data) *data = MMT(x)->map[tnodeid].data; id = tnodeid; } MUTEX_UNLOCK(MMT(x)->mutex); } return id; }
/* remove node */ void mmtree64_remove(void *x, int rootid, unsigned int tnodeid, int64_t *key, int *data) { unsigned int id = 0, pid = 0, parent = 0, child = 0, rid = 0, lid = 0, uid = 0, ppid = 0, color = 0, *prootid = NULL; if(x && rootid > 0 && tnodeid > 0) { mmtree64_mutex_lock(x, rootid); if(MMT(x)->map && MMT(x)->state && tnodeid < MMT(x)->state->total) { if(key) *key = MMT(x)->map[tnodeid].key; if(data) *data = MMT(x)->map[tnodeid].data; id = tnodeid; if(MMT(x)->map[tnodeid].left == 0) { child = MMT(x)->map[tnodeid].right; } else if(MMT(x)->map[tnodeid].right == 0) { child = MMT(x)->map[tnodeid].left; } else { id = MMT(x)->map[tnodeid].right; while(MMT(x)->map[id].left > 0) id = MMT(x)->map[id].left; parent = MMT(x)->map[id].parent; color = MMT(x)->map[id].color; if((child = MMT(x)->map[id].right) > 0) MMT(x)->map[child].parent = parent; if((pid = parent) > 0) { if(MMT(x)->map[pid].left == id) MMT(x)->map[pid].left = child; else MMT(x)->map[pid].right = child; } else { MMT(x)->state->roots[rootid].rootid = child; } if(MMT(x)->map[id].parent == tnodeid) parent = id; MMT(x)->map[id].color = MMT(x)->map[tnodeid].color; MMT(x)->map[id].parent = MMT(x)->map[tnodeid].parent; MMT(x)->map[id].left = MMT(x)->map[tnodeid].left; MMT(x)->map[id].right = MMT(x)->map[tnodeid].right; if((pid = MMT(x)->map[tnodeid].parent) > 0) { if(MMT(x)->map[pid].left == tnodeid) MMT(x)->map[pid].left = id; else MMT(x)->map[pid].right = id; } else { MMT(x)->state->roots[rootid].rootid = id; } lid = MMT(x)->map[tnodeid].left; MMT(x)->map[lid].parent = id; if((rid = MMT(x)->map[tnodeid].right) > 0) MMT(x)->map[rid].parent = id; goto color_remove; } parent = MMT(x)->map[tnodeid].parent; color = MMT(x)->map[tnodeid].color; if(child > 0) { MMT(x)->map[child].parent = parent; } if((pid = parent) > 0) { if(tnodeid == MMT(x)->map[pid].left) MMT(x)->map[pid].left = child; else MMT(x)->map[pid].right = child; } else { MMT(x)->state->roots[rootid].rootid = child; } //remove color set color_remove: MMT(x)->state->roots[rootid].total--; if(color == MMT_COLOR_BLACK) { //fprintf(stdout, "%s::%d node:%d parent:%d left:%d right:%d key:%d data:%d\n", __FILE__, __LINE__, tnodeid, MMT(x)->map[tnodeid].parent, MMT(x)->map[tnodeid].left, MMT(x)->map[tnodeid].right, MMT(x)->map[tnodeid].key, MMT(x)->map[tnodeid].data); prootid = &(MMT(x)->state->roots[rootid].rootid); MMT_REMOVE_COLOR(x, prootid, child, parent, lid, rid, uid, ppid); } //add to qleft mmtree64_qleft(x, tnodeid); //fprintf(stdout, "%s::%d %d start:%p state:%p map:%p current:%d left:%d total:%d qleft:%d qfirst:%d qlast:%d\n", __FILE__, __LINE__, id, MMT(x)->start, MMT(x)->state, MMT(x)->map, MMT(x)->state->current, MMT(x)->state->left, MMT(x)->state->total, MMT(x)->state->qleft, MMT(x)->state->qfirst, MMT(x)->state->qlast); } mmtree64_mutex_unlock(x, rootid); } return ; }
//add nodeid to qleft void mmtree64_qleft(void *x, int tnodeid) { int z = 0; if(x) { MUTEX_LOCK(MMT(x)->mutex); memset(&(MMT(x)->map[tnodeid]), 0, sizeof(MTNODE64)); if(MMT(x)->state->qleft == 0) { MMT(x)->state->qfirst = MMT(x)->state->qlast = tnodeid; } else { z = MMT(x)->state->qlast; MMT(x)->map[z].parent = tnodeid; MMT(x)->state->qlast = tnodeid; } MMT(x)->state->qleft++; MMT(x)->state->left++; MUTEX_UNLOCK(MMT(x)->mutex); } return ; }
//new node unsigned int mmtree64_new_node(void *x, int rootid, int nodeid, int64_t key, int data) { unsigned int id = 0; if(x) { MUTEX_LOCK(MMT(x)->mutex); //fprintf(stdout, "%s::%d %d start:%p state:%p map:%p current:%d left:%d total:%d qleft:%d qfirst:%d qlast:%d\n", __FILE__, __LINE__, id, MMT(x)->start, MMT(x)->state, MMT(x)->map, MMT(x)->state->current, MMT(x)->state->left, MMT(x)->state->total, MMT(x)->state->qleft, MMT(x)->state->qfirst, MMT(x)->state->qlast); if(MMT(x)->state->left == 0) { MMT_INCRE(x); } if(MMT(x)->state->qleft > 0) { id = MMT(x)->state->qfirst; MMT(x)->state->qfirst = MMT(x)->map[id].parent; MMT(x)->state->qleft--; } else { id = ++(MMT(x)->state->current); } //fprintf(stdout, "%s::%d %d start:%p state:%p map:%p current:%d left:%d total:%d qleft:%d qfirst:%d qlast:%d\n", __FILE__, __LINE__, id, MMT(x)->start, MMT(x)->state, MMT(x)->map, MMT(x)->state->current, MMT(x)->state->left, MMT(x)->state->total, MMT(x)->state->qleft, MMT(x)->state->qfirst, MMT(x)->state->qlast); MMT(x)->state->left--; //memset(&(MMT(x)->map[id]), 0, sizeof(MTNODE64)); MMT(x)->map[id].parent = nodeid; MMT(x)->map[id].key = key; MMT(x)->map[id].data = data; MMT_MIN_MAX(x, id, key); if(nodeid > 0) { if(key > MMT(x)->map[nodeid].key) MMT(x)->map[nodeid].right = id; else MMT(x)->map[nodeid].left = id; } MMT(x)->state->roots[rootid].total++; MUTEX_UNLOCK(MMT(x)->mutex); } return id; }
/* get prev node key/data */ unsigned int mmtree64_prev(void *x, int rootid, unsigned int tnodeid, int64_t *key, int *data) { unsigned int id = 0, parentid = 0; if(x && tnodeid > 0 && rootid > 0) { mmtree64_mutex_lock(x, rootid); if(MMT(x)->map && MMT(x)->state && tnodeid < MMT(x)->state->total) { id = tnodeid; if(MMT(x)->map[id].left > 0) { id = MMT(x)->map[id].left; while(MMT(x)->map[id].right > 0) { id = MMT(x)->map[id].right; } //fprintf(stdout, "%s::%d id:%d\n", __FILE__, __LINE__, id); } else { while(id > 0) { parentid = MMT(x)->map[id].parent; if(MMT(x)->map[id].key > MMT(x)->map[parentid].key) { id = parentid; goto end; } else { id = parentid; } } //fprintf(stdout, "%s::%d id:%d\n", __FILE__, __LINE__, id); } end: if(id > 0 && id < MMT(x)->state->total) { if(key)*key = MMT(x)->map[id].key; if(data)*data = MMT(x)->map[id].data; } //fprintf(stdout, "%s::%d rootid:%d tnodeid:%d id:%d\n",__FILE__, __LINE__, rootid, tnodeid, id); } mmtree64_mutex_unlock(x, rootid); } return id; }