Beispiel #1
0
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];
}
Beispiel #2
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;
}
Beispiel #3
0
/* 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);
}
Beispiel #4
0
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;
}
Beispiel #5
0
/* 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;
}
Beispiel #6
0
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);
}
Beispiel #7
0
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);
    }
  }
}
Beispiel #8
0
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);
}
Beispiel #9
0
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
}
Beispiel #11
0
/*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
}
Beispiel #13
0
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;
}
Beispiel #14
0
/* 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;
}
Beispiel #15
0
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];
}
Beispiel #16
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;
}
Beispiel #17
0
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];
}
Beispiel #18
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];
}
Beispiel #19
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;
}
Beispiel #21
0
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;
}
Beispiel #22
0
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);
  }
}