static tree_node_t make_nary_tree(tree_node_t *nodes, gasnet_node_t num_nodes, int radix) { gasnet_node_t num_children=0; int i,j; if(num_nodes > 1) { tree_node_t *children; for(j=0; j<radix; j++){ int start,end; start = (j==0 ? 1 : MIN(num_nodes, j*(MYCEIL(num_nodes, radix)))); end = MIN(num_nodes, (j+1)*MYCEIL(num_nodes, radix)); if(start == end) continue; num_children++; } if(num_children > 0) { children = (tree_node_t*) gasneti_malloc(num_children*sizeof(tree_node_t)); for(j=0, i=num_children-1; j<radix; j++) { int start,end; start = (j==0 ? 1 : MIN(num_nodes, j*(MYCEIL(num_nodes, radix)))); end = MIN(num_nodes, (j+1)*MYCEIL(num_nodes, radix)); if(start == end) continue; children[i] = make_nary_tree(nodes+start, end-start, radix); i--; } nodes[0]->children_reversed=1; preappend_children(nodes[0], children, num_children); gasneti_free(children); } } return nodes[0]; }
static gasnete_coll_tree_type_t make_tree_type_str_helper(char *tree_name) { gasnete_coll_tree_type_t ret = gasnete_coll_get_tree_type(); char **inner_split; int num_splits; int i; char inner_delim[]=","; num_splits = split_string(&inner_split, tree_name,inner_delim); if(strcmp(inner_split[0], "NARY_TREE")==0) { ret->tree_class = GASNETE_COLL_NARY_TREE; } else if(strcmp(inner_split[0], "KNOMIAL_TREE")==0) { ret->tree_class = GASNETE_COLL_KNOMIAL_TREE; } else if(strcmp(inner_split[0], "RECURSIVE_TREE")==0) { ret->tree_class = GASNETE_COLL_RECURSIVE_TREE; } else if(strcmp(inner_split[0], "FORK_TREE")==0) { ret->tree_class = GASNETE_COLL_FORK_TREE; }else if(strcmp(inner_split[0], "FLAT_TREE")==0) { ret->tree_class = GASNETE_COLL_FLAT_TREE; } else { gasneti_fatalerror("Unknown Tree Type: %s\n", tree_name); } ret->params = gasneti_malloc(sizeof(int)*num_splits-1); ret->num_params = num_splits-1; for(i=0; i<ret->num_params; i++) { ret->params[i] = atoi(inner_split[i+1]); } gasneti_free(inner_split); return ret; }
/* Naive (poorly scaling) "reference" implementation via gasnetc_bootstrapExchange() */ static void gasnetc_bootstrapSNodeBroadcast(void *src, size_t len, void *dest, int rootnode) { void *tmp = gasneti_malloc(len * gasneti_nodes); gasneti_assert(NULL != src); gasnetc_bootstrapExchange(src, len, tmp); memcpy(dest, (void*)((uintptr_t)tmp + (len * rootnode)), len); gasneti_free(tmp); }
static tree_node_t make_hiearchical_tree_helper(gasnete_coll_tree_type_t tree_type, int level, int final_level, tree_node_t *allnodes, int num_nodes, int *node_counts) { tree_node_t rootnode; tree_node_t *temp; gasneti_assert(tree_type !=NULL); if(level == final_level) { switch (tree_type->tree_class) { case GASNETE_COLL_NARY_TREE: rootnode = make_nary_tree(allnodes, num_nodes, tree_type->params[0]); break; case GASNETE_COLL_FLAT_TREE: rootnode = make_flat_tree(allnodes, num_nodes); break; case GASNETE_COLL_KNOMIAL_TREE: rootnode = make_knomial_tree(allnodes, num_nodes, tree_type->params[0]); break; case GASNETE_COLL_RECURSIVE_TREE: rootnode = make_recursive_tree(allnodes, num_nodes, tree_type->params[0]); break; case GASNETE_COLL_FORK_TREE: rootnode = make_fork_tree(allnodes, num_nodes, tree_type->params, tree_type->num_params); break; default: gasneti_fatalerror("unknown tree type"); } } else { int i,j=0,num_processed=0; int level_nodes = MYCEIL(num_nodes, node_counts[0]); temp = gasneti_malloc(sizeof(tree_node_t) * level_nodes); for(i=0; i<level_nodes-1; i++) { temp[j]=make_hiearchical_tree_helper(tree_type->subtree, level+1, final_level, allnodes+i*node_counts[0], node_counts[0], node_counts+1); j++; num_processed += node_counts[0]; } temp[j]=make_hiearchical_tree_helper(tree_type->subtree, level+1, final_level, allnodes+i*node_counts[0], num_nodes - num_processed, node_counts+1); j++; switch (tree_type->tree_class) { case GASNETE_COLL_NARY_TREE: rootnode = make_nary_tree(temp, j, tree_type->params[0]); break; case GASNETE_COLL_FLAT_TREE: rootnode = make_flat_tree(temp,j); break; case GASNETE_COLL_KNOMIAL_TREE: rootnode = make_knomial_tree(temp, j, tree_type->params[0]); break; case GASNETE_COLL_RECURSIVE_TREE: rootnode = make_recursive_tree(temp, j, tree_type->params[0]); break; case GASNETE_COLL_FORK_TREE: rootnode = make_fork_tree(temp, j, tree_type->params, tree_type->num_params); break; default: gasneti_fatalerror("unknown tree type"); } gasneti_free(temp); } return rootnode; }
/* Prepare the checkpoint directory, optionally choosing it as well. * * If the 'dir' argument is non-NULL, it is used as the checkpoint directory and * is also the return value. Otherwise the default directory name is chosen (as * described below) and its name (in malloced memory) is returned. * * Regardles of whether the directory name is caller-provided or default, the * directory is prepared as follows: * + The directory and all parents are created if they did not already exist. * + A 'metadata' file is created, storing info useful at restart time. * * Default checkpoint directory names are of the form * [jobdir]/[sequence] * where * [jobdir] is one of the following (the first w/o an undefined variable): * 1. ${GASNET_CHECKPOINT_JOBDIR} * 2. ${GASNET_CHECKPOINT_BASEDIR}/[guid_hi].[guid_lo] * 3. ${HOME}/gasnet-checkpoint/[guid_hi].[guid_lo] * and * [sequence] is a decimal integer (increased on each call). * * NOT thread-safe (but neither is checkpoint initiation). */ extern const char *gasneti_checkpoint_dir(const char *dir) { char *filename; if (!dir) { size_t len = strlen(gasneti_checkpoint_jobdir) + 12; /* 12 = "/0123456789\0" */ char *tmp = gasneti_malloc(len); snprintf(tmp, len, "%s/%d", gasneti_checkpoint_jobdir, gasneti_checkpoint_sequence++); dir = tmp; } /* Make a copy of 'dir' which we can write to as needed */ filename = gasneti_malloc(10 + strlen(dir)); /* 10 = "/metadata\0" */ strcpy(filename, dir); { /* The following implements "mkdir -p" (and needs to write to filename) */ char *p = filename; int rc; do { p = strchr(p+1, '/'); if (p) { *p = '\0'; } rc = mkdir(filename, S_IRWXU); if ((rc < 0) && (errno != EEXIST)) { gasneti_fatalerror("Failed to mkdir('%s') %d:%s\n", filename, errno, strerror(errno)); /* BLCR-TODO: error recovery */ } if (p) { *p = '/'; } } while (p); } /* Create metadata file. * Since every process tries, we get one copy per filesystem. */ strcat(filename, "/metadata"); { /* Want O_EXCL, but not available directly via fopen() */ int fd = open(filename, O_CREAT|O_EXCL|O_WRONLY, S_IRUSR); if (fd >= 0) { FILE *md = fdopen(fd, "w"); if (md) { /* BLCR-TODO: error detection or silent failure for fwrite() or fclose()? */ fprintf(md, "argv0:\t%s\n", gasneti_exename); fprintf(md, "nproc:\t%d\n", gasneti_nodes); fprintf(md, "guid:\t%08x.%08x\n", GASNETI_HIWORD(gasneti_checkpoint_guid), GASNETI_LOWORD(gasneti_checkpoint_guid)); fprintf(md, "time:\t%lu\n", (unsigned long)time(NULL)); fclose(md); } else { gasneti_fatalerror("Failed to fdopen file '%s' %d:%s\n", filename, errno, strerror(errno)); } } else if (errno != EEXIST) { gasneti_fatalerror("Failed to create file '%s' %d:%s\n", filename, errno, strerror(errno)); } } gasneti_free(filename); return dir; }
void gasnetc_free_send_req(void * p_sreq) { gasnet_mxm_send_req_t * sreq = (gasnet_mxm_send_req_t *) p_sreq; gasneti_assert(sreq && "bad sreq to free"); #if GASNET_DEBUG /* clear object's data before freeing it - might catch use after free */ memset(sreq, 0, sizeof(gasnet_mxm_send_req_t)); #endif gasneti_free(sreq); }
extern void gasneti_checkpoint_init(gasneti_bootstrapBroadcastfn_t bcast_fn) { /* Initialize the GUID if the conduit has not already set a non-zero value */ if (!gasneti_checkpoint_guid) { if (! gasneti_mynode) { gasneti_checkpoint_guid = gasneti_checkpoint_mkguid(); } bcast_fn(&gasneti_checkpoint_guid, sizeof(uint64_t), &gasneti_checkpoint_guid, 0); } /* Enforce use of absolute paths */ { char *val; if (NULL != (val = gasneti_getenv("GASNET_CHECKPOINT_JOBDIR"))) { if ('/' != val[0]) { gasneti_fatalerror("Environment variable GASNET_CHECKPOINT_JOBDIR='%s' is not an absolute path", val); } else { gasneti_checkpoint_jobdir = val; } } else { char *dir; size_t len; if (NULL != (val = gasneti_getenv("GASNET_CHECKPOINT_BASEDIR"))) { if ('/' != val[0]) { gasneti_fatalerror("Environment variable GASNET_CHECKPOINT_BASEDIR='%s' is not an absolute path", val); } else { dir = val; } } else { if (NULL != (val = gasneti_getenv("HOME"))) { if ('/' != val[0]) { gasneti_fatalerror("Environment variable HOME='%s' is not an absolute path", val); } else { const char *rest = "/gasnet-checkpoint"; len = strlen(val) + strlen(rest) + 1; dir = gasneti_malloc(len); strcpy(dir, val); strcat(dir, rest); } } else { gasneti_fatalerror("Environment variable HOME is not set"); } } len = strlen(dir) + 19; /* 19 = 16 digits, '/' , '.' and '\0' */ gasneti_checkpoint_jobdir = gasneti_malloc(len); gasneti_leak(gasneti_checkpoint_jobdir); snprintf(gasneti_checkpoint_jobdir, len, "%s/%08x.%08x", dir, GASNETI_HIWORD(gasneti_checkpoint_guid), GASNETI_LOWORD(gasneti_checkpoint_guid)); if (dir != val) gasneti_free(dir); } } }
static void fh_hash_destroy(fh_hash_t *hash) { #ifdef FH_HASH_STATS fprintf(stderr, "elements: %d, collisions: %d, avg=%2.5f%%\n", hash->fh_used, hash->fh_collisions, (float) hash->fh_collisions*100/hash->fh_used); { int i, hits; for (i = 0; i < hash->fh_entries; i++) { hits = hash->fh_col_table[i]; if (hits) { /*printf("%d\t%d\n", i, hits);*/ } } } gasneti_free(hash->fh_col_table); #endif gasneti_free(hash->fh_table); gasneti_free(hash); }
void myxml_destroyTree(myxml_node_t *node) { int i,j; if(node==NULL) return; for(i=0; i<node->num_children; i++) { myxml_destroyTree(node->children[i]); } gasneti_free(node->children); for(j=0; j<node->num_attributes; j++) { gasneti_free(node->attribute_list[j].attribute_name); gasneti_free(node->attribute_list[j].attribute_value); } gasneti_free(node->attribute_list); if(node->tag) gasneti_free(node->tag); if(node->value) gasneti_free(node->value); gasneti_free(node); return; }
void gasneti_bootstrapExchange_mpi(void *src, size_t len, void *dest) { const int inplace = ((uint8_t *)src == (uint8_t *)dest + len * gasnetc_mpi_rank); int err; if (inplace) { #if GASNETC_MPI_ALLGATHER_IN_PLACE src = MPI_IN_PLACE; #else src = memcpy(gasneti_malloc(len), src, len); #endif } err = MPI_Allgather(src, len, MPI_BYTE, dest, len, MPI_BYTE, gasnetc_mpi_comm); gasneti_assert(err == MPI_SUCCESS); #if !GASNETC_MPI_ALLGATHER_IN_PLACE if (inplace) gasneti_free(src); #endif }
/*preappend a list of children*/ static tree_node_t preappend_children(tree_node_t main_node, tree_node_t *child_nodes, int num_nodes) { if(num_nodes > 0) { if(main_node->num_children == 0) { main_node->children = gasneti_malloc(num_nodes * sizeof(tree_node_t)); GASNETE_FAST_UNALIGNED_MEMCPY_CHECK(main_node->children, child_nodes, sizeof(tree_node_t)*num_nodes); } else { tree_node_t *new_children = gasneti_malloc(sizeof(tree_node_t)* (main_node->num_children+num_nodes)); GASNETE_FAST_UNALIGNED_MEMCPY_CHECK(new_children, child_nodes, num_nodes*sizeof(tree_node_t)); GASNETE_FAST_UNALIGNED_MEMCPY_CHECK(new_children+num_nodes, main_node->children, main_node->num_children*(sizeof(tree_node_t))); gasneti_free(main_node->children); main_node->children = new_children; } main_node->num_children = main_node->num_children+num_nodes; } return main_node; }
void gasneti_bootstrapAlltoall_mpi(void *src, size_t len, void *dest) { const int inplace = (src == dest); int err; if (inplace) { #if GASNETC_MPI_ALLTOALL_IN_PLACE src = MPI_IN_PLACE; #else const size_t total_len = len * gasnetc_mpi_size; src = memcpy(gasneti_malloc(total_len), src, total_len); #endif } err = MPI_Alltoall(src, len, MPI_BYTE, dest, len, MPI_BYTE, gasnetc_mpi_comm); gasneti_assert(err == MPI_SUCCESS); #if !GASNETC_MPI_ALLTOALL_IN_PLACE if (inplace) gasneti_free(src); #endif }
gasnete_coll_tree_type_t gasnete_coll_make_tree_type_str(char *tree_name_str) { char outter_delim[]=":"; char inner_delim[]=","; char **outer_split; gasnete_coll_tree_type_t ret; /*first split the tree string on the ":"*/ int num_levels = split_string(&outer_split, tree_name_str, outter_delim); if(num_levels > 1) { char **inner_split; int num_splits, num_params; int i; gasnete_coll_tree_type_t temp; ret = gasnete_coll_get_tree_type(); num_splits = split_string(&inner_split, outer_split[0],inner_delim); num_params = num_splits-1;/*first split is the tree name*/ gasneti_assert(strcmp(inner_split[0], "HIERARCHICAL_TREE")==0); ret->tree_class = GASNETE_COLL_HIERARCHICAL_TREE; if(num_params != num_levels-1){ gasneti_fatalerror("badly formed hierarchical tree expect HIEARCHICAL_TREE,<numlevels>,<in level1>,<in level2>,..,<in level n-1>:TREE1,PARAMS1:TREE2,PARAMS2:(etc)\n"); } /*NOT DONE*/ ret->params = gasneti_malloc(sizeof(int)*(num_params)); ret->num_params = num_params; for(i=0; i<num_params; i++) { ret->params[i] = atoi(inner_split[i+1]); } temp = ret; for(i=1; i<num_levels; i++) { temp->subtree = make_tree_type_str_helper(outer_split[i]); temp = temp->subtree; } } else { ret = make_tree_type_str_helper(tree_name_str); } gasneti_free(outer_split); return ret; }
/* Create the caller's context file */ extern int gasneti_checkpoint_create(const char *dir) { const int flags = O_WRONLY|O_APPEND|O_CREAT|O_EXCL|O_LARGEFILE|O_TRUNC; const int mode = S_IRUSR; char *filename; size_t len; int fd; gasneti_assert(NULL != dir); len = strlen(dir) + 19; /* 19 = "/context.123456789\0" */ filename = gasneti_malloc(len); snprintf(filename, len, "%s/context.%d", dir, gasneti_mynode); fd = open(filename, flags, mode); gasneti_free(filename); if (fd < 0) { /* BLCR-TODO: error checking/recovery */ gasneti_fatalerror("Failed to create '%s' errno=%d(%s)\n", filename, errno, strerror(errno)); } return fd; }
static tree_node_t make_knomial_tree(tree_node_t *nodes, int num_nodes, int radix) { int i; int num_children=0; gasneti_assert(radix>1); if(num_nodes > 1) { int r; int stride = 1; int num_proc = 1; tree_node_t *children; while(num_proc < num_nodes) { for(r=stride; r<stride*radix; r+=stride) { num_proc += MIN(stride, num_nodes - num_proc); num_children++; if(num_proc == num_nodes) break; } stride*=radix; } children = (tree_node_t*) gasneti_malloc(num_children*sizeof(tree_node_t)); num_proc = 1; i=1; stride = 1; while(num_proc<num_nodes) { for(r=stride; r<stride*radix; r+=stride) { gasneti_assert(i<=num_children); children[num_children-i] = make_knomial_tree(nodes+r,MIN(stride, num_nodes - num_proc), radix); num_proc += MIN(stride, num_nodes - num_proc); if(num_proc == num_nodes) break; i++; } stride*=radix; } nodes[0]->children_reversed=1; preappend_children(nodes[0], children, num_children); gasneti_free(children); } return nodes[0]; }
static tree_node_t *allocate_nodes(tree_node_t **curr_nodes, gasnet_team_handle_t team, int rootrank) { gasnet_node_t i; int new_allocation=0; if(!(*curr_nodes)) { *curr_nodes = (tree_node_t*) gasneti_malloc(sizeof(tree_node_t)*team->total_ranks); new_allocation=1; } for(i=0; i<team->total_ranks; i++) { if(new_allocation) { (*curr_nodes)[i] = (struct tree_node_t_*) gasneti_calloc(1,sizeof(struct tree_node_t_)); } else { gasneti_free((*curr_nodes)[i]->children); (*curr_nodes)[i]->children = NULL; (*curr_nodes)[i]->num_children = 0; (*curr_nodes)[i]->children_reversed = 0; } (*curr_nodes)[i]->id = (i+rootrank)%team->total_ranks; (*curr_nodes)[i]->parent = NULL; } return *curr_nodes; }
static tree_node_t make_recursive_tree(tree_node_t *nodes, gasnet_node_t num_nodes, int radix) { gasnet_node_t i,j; int num_children=0; if(num_nodes > 1) { tree_node_t *children; gasneti_assert(radix > 1); for(i=1; i<num_nodes; i*=radix) { num_children++; } children = (tree_node_t*) gasneti_malloc(num_children*sizeof(tree_node_t)); /*reverse the order of hte children as specified by the binomial tree construction*/ for(i=1,j=num_children-1; i<num_nodes; i*=radix,j--) { children[j] = make_recursive_tree(nodes+i, (MIN(num_nodes, (i*radix)) - i), radix); } nodes[0]->children_reversed=1; preappend_children(nodes[0], children, num_children); gasneti_free(children); } return nodes[0]; }
/*need to worry about corner cases*/ static tree_node_t make_fork_tree(tree_node_t *nodes, int num_nodes, int *dims, int ndims) { int i; int stride; tree_node_t *temp_nodes; gasneti_assert(ndims > 0); gasneti_assert(multarr(dims, ndims)==num_nodes); if(ndims > 1) { temp_nodes = gasneti_malloc(sizeof(tree_node_t)*dims[0]); stride = multarr(dims+1,ndims-1); for(i=dims[0]-1; i>=0; i--) { temp_nodes[i] = make_fork_tree(nodes+stride*i, stride, dims+1, ndims-1); } make_chain_tree(temp_nodes, dims[0]); gasneti_free(temp_nodes); } else { make_chain_tree(nodes, dims[0]); } nodes[0]->children_reversed=1; return nodes[0]; }
void gasnetc_free_recv_req(gasnet_mxm_recv_req_t *p_rreq) { gasneti_munmap(p_rreq->mxm_rreq.base.data.buffer.ptr, p_rreq->mxm_rreq.base.data.buffer.length); gasneti_free(p_rreq); }
/* ##################################################################### */ void gasnete_fh_callback_put(struct gm_port *p, void *context, gm_status_t status) { #ifndef GASNET_SEGMENT_FAST GASNET_BEGIN_FUNCTION(); /* thread cache for *_IN_UNKNOWN */ #endif gasnete_eop_t *pop = (gasnete_eop_t *) context; #if defined(GASNET_DEBUG) || defined(GASNETI_STATS_OR_TRACE) gasnet_node_t node = pop->node; gasneti_tick_t starttime = GASNETI_TICKS_NOW_IFENABLED(C); #endif const firehose_request_t *fhreqs[2]; int numreqs = 1; gasneti_mutex_assertlocked(&gasnetc_lock_gm); gasneti_assert(pop != NULL); gasneti_assert(node != gasneti_mynode && node < gasneti_nodes); if_pf (status != GM_SUCCESS) gasnetc_callback_error(status, NULL); gasnetc_token_lo_release(); GASNETI_TRACE_PRINTF(C, ("Firehose decrement remote refcount for (%p,%d) on node %d (op=%p,%p,%d)\n", (void *) pop->dest, pop->len, (unsigned) node, (void *) pop, (void *)pop->req_remote.addr, (int)pop->req_remote.len)); fhreqs[0] = &(pop->req_remote); /* Puts use an ambuffer, while bulk puts send from a pinned location */ if (OPMISC(pop) == OPMISC_AMBUF) { gasnetc_bufdesc_t *bufd; bufd = (gasnetc_bufdesc_t *) GASNETC_BUFDESC_PTR(pop->src); GASNETC_ASSERT_BUFDESC_PTR(bufd, pop->src); gasnetc_callback_ambuffer(p, (void *) bufd, status); } else { fhreqs[1] = pop->req_local; numreqs++; #ifdef GASNET_SEGMENT_FAST /* Only release locally for "fast" segment */ firehose_release(fhreqs+1, 1); #endif } #ifndef GASNET_SEGMENT_FAST GASNETE_GM_SET_IN_UNKNOWN(); firehose_release(fhreqs, numreqs); GASNETE_GM_UNSET_IN_UNKNOWN(); #endif GASNETE_FIREHOSE_TRACE_PUTGET(pop, PUT); /* If this was associated to an iop, increment put completed count */ if (pop->iop != NULL) { gasneti_weakatomic_increment(&(pop->iop->completed_put_cnt),0/*Rel?*/); gasneti_free(pop); /* free a "dummy" eop */ } else { gasnete_op_markdone((gasnete_op_t *)pop, 0); } GASNETI_TRACE_EVENT_TIME(C, FIREHOSE_MOVE_LOCAL, GASNETI_TICKS_NOW_IFENABLED(C)-starttime); return; }
gasnete_coll_local_tree_geom_t *gasnete_coll_local_tree_geom_fetch(gasnete_coll_tree_type_t type, gasnet_node_t root, gasnete_coll_team_t team) { gasnete_coll_tree_geom_t *geom_cache_head = team->tree_geom_cache_head; gasnete_coll_local_tree_geom_t *ret; gasnete_coll_tree_geom_t *curr_geom; /*lock here so that only one multiple threads don't try to build it*/ gasneti_mutex_lock(&team->tree_geom_cache_lock); curr_geom = gasnete_coll_tree_geom_fetch_helper(type, team); if(curr_geom == NULL) { int i; #if 0 if(gasneti_mynode ==0) fprintf(stderr, "%d> new tree: %d type %d fanout\n",gasneti_mynode, type.tree_class, type.prams[0]); #endif /* allocate new geometry */ curr_geom = (gasnete_coll_tree_geom_t *) gasneti_malloc(sizeof(gasnete_coll_tree_geom_t)); curr_geom->local_views = (gasnete_coll_local_tree_geom_t**) gasneti_malloc(sizeof(gasnete_coll_local_tree_geom_t*)*team->total_ranks); for(i=0; i<team->total_ranks; i++) { curr_geom->local_views[i] = NULL; } curr_geom->tree_type = type; #if 0 /* Not using the ref_count for now */ gasneti_weakatomic_set(&(curr_geom->ref_count), 0, 0); #endif /* curr_geom->root = root; */ /* link it into the cache*/ if(geom_cache_head == NULL) { /*cache is empty*/ curr_geom->prev = NULL; curr_geom->next = NULL; team->tree_geom_cache_head = curr_geom; team->tree_geom_cache_tail = curr_geom; } else { curr_geom->prev = NULL; /* new head */ curr_geom->next = team->tree_geom_cache_head; team->tree_geom_cache_head->prev = curr_geom; team->tree_geom_cache_head = curr_geom; } curr_geom->local_views[root] = gasnete_coll_tree_geom_create_local(type, root, team, curr_geom); ret = curr_geom->local_views[root]; /* create local view for the root that we request */ } else { /* if it is already allocated for root go ahead and return it ... this should be the fast path*/ if(curr_geom->local_views[root] == NULL) { curr_geom->local_views[root] = gasnete_coll_tree_geom_create_local(type, root, team, curr_geom); } ret = curr_geom->local_views[root]; } #ifdef GASNETC_HAVE_AMRDMA /*at the time of this writing no conduits support this yet*/ if(team->myrank != ret->root) { int count = GASNETE_COLL_TREE_GEOM_CHILD_COUNT(ret); gasnet_node_t *tmp = gasneti_calloc(1+count, sizeof(gasnet_node_t)); memcpy(tmp, GASNETE_COLL_TREE_GEOM_CHILDREN(ret), count*sizeof(gasnet_node_t)); tmp[count] = GASNETE_COLL_TREE_GEOM_PARENT(ret); gasnetc_amrdma_init(1+count, tmp); gasneti_free(tmp); } else { gasnetc_amrdma_init(GASNETE_COLL_TREE_GEOM_CHILD_COUNT(ret), GASNETE_COLL_TREE_GEOM_CHILDREN(ret)); } #endif #if 0 /* Not using the reference counts for now */ gasneti_weakatomic_increment(&(curr_geom->ref_count), 0); gasneti_weakatomic_increment(&(ret->ref_count), 0); /* fprintf(stderr, "[%u] gasnete_coll_local_tree_geom_fetch: curr_geom->ref_count %u, ret->ref_count %u \n", gasnet_mynode(), gasneti_weakatomic_read(&(curr_geom->ref_count), 0), gasneti_weakatomic_read(&(ret->ref_count), 0)); */ #endif gasneti_mutex_unlock(&team->tree_geom_cache_lock); return ret; }
void gasnete_coll_free_tree_type(gasnete_coll_tree_type_t in){ gasneti_free(in->params); if(in!=NULL) { gasneti_lifo_push(&gasnete_coll_tree_type_free_list, in); } }