Пример #1
0
/* fh_hash_create(keylen,entries)
 *
 * Allocates a table large enough to hold 'entries' entries of size 'keylen'.
 * Note that 'entries' must be a power of two.
 */
static
fh_hash_t *
fh_hash_create(size_t entries)
{
	fh_hash_t	*hash;

	if (!IS_POWER_OF_2(entries))
		gasneti_fatalerror("fh_hash_create requires a power of 2!");

	hash = (fh_hash_t *) gasneti_malloc(sizeof(fh_hash_t));
	if (hash == NULL)
		gasneti_fatalerror("Can't allocate memory for hash structure");
	memset(hash, 0, sizeof(fh_hash_t));

	hash->fh_table   = (void **) gasneti_calloc(entries, sizeof(void *));
	hash->fh_mask    = entries-1;
	hash->fh_entries = entries;
	#ifdef FH_HASH_STATS
		hash->fh_col_table = (int *) gasneti_malloc(entries * sizeof(int));
		/*printf("hash create: entries=%d, mask=%x\n", entries, entries-1);*/
		hash->fh_used = 0;
		hash->fh_collisions = 0;
	#endif
	
	return hash;
}
Пример #2
0
static int split_string(char ***split_strs, char *str, char *delim) {
  char *temp=NULL,*copy;
  int ret=0;
  size_t malloc_len = 8;
  static gasneti_mutex_t lock= GASNETI_MUTEX_INITIALIZER;

  copy = gasneti_malloc(sizeof(char)*(strlen(str)+1));
  
  /*since the strtok function is desructive we have to
    create a copy of the string first to preserve the orignal*/
  GASNETE_FAST_UNALIGNED_MEMCPY_CHECK(copy, str, sizeof(char)*(strlen(str)+1));
  gasneti_mutex_lock(&lock);
  *split_strs = (char **) gasneti_malloc(sizeof(char*) * malloc_len);
  temp = strtok(copy, delim);
  while(temp != NULL) {
    if(ret == malloc_len) {
      /*we've run out of space so grow the array by another factor*/
      malloc_len +=malloc_len;
      *split_strs = (char**) gasneti_realloc(*split_strs, sizeof(char*) * malloc_len);
      gasneti_fatalerror("more than 8 params not yet supported");

    }
    (*split_strs)[ret] = temp;
    
    ret++;
    temp=strtok(NULL, delim);
  }
  *split_strs = (char**) gasneti_realloc(*split_strs, sizeof(char*) * ret);
  gasneti_mutex_unlock(&lock);

  return ret;
}
Пример #3
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;
}
Пример #4
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);
    }
  }
}
Пример #5
0
static
gasnete_coll_dissem_info_t *gasnete_coll_build_dissemination(int r, gasnete_coll_team_t team) {
  gasnete_coll_dissem_info_t *ret;  
  int h,w,i,j,distance,x,numpeers,destproc;
  int num_out_peers, num_in_peers;
  ret = (gasnete_coll_dissem_info_t*) gasneti_malloc(sizeof(gasnete_coll_dissem_info_t));
  
  w = gasnete_coll_build_tree_mylogn(team->total_ranks, r);
  ret->dissemination_radix = r;
  ret->dissemination_phases = w;
  
  
  
  distance = 1;
  /* phase 2: communication in log_r(team->total_ranks) steps*/
  for(i=0; i<w; i++) {
    if(i==(w-1)) {
      /*h = ceil(team->total_ranks/DIST);*/
      h = team->total_ranks/distance;
      if(team->total_ranks % distance != 0) 
        h++;
    } else {
      h = r;
    }
    
    ret->exchange_order[i].n = h-1;
    ret->exchange_order[i].elem_list = (gasnet_node_t*) gasneti_malloc(sizeof(gasnet_node_t)*(h-1));
    for(j=1; j<h; j++) {
      ret->barrier_order[i].elem_list[j-1] = (team->myrank + j*distance) % team->total_ranks;
    }
    /*scale the distance by the radix*/
    distance *= r;
  }
  
  
  
  /*simulate the packing step and figure out what is the maxiumum number of blocks that come in across all the nodes*/
  ret->max_dissem_blocks =MAX(1,(team->total_ranks/ret->dissemination_radix));
  for(i=0; i<w; i++) {
    int curr_count = 0;
    for(j=0; j<team->total_ranks; j++) {
      if( ((j / gasnete_coll_build_tree_mypow(ret->dissemination_radix, i)) % ret->dissemination_radix) 
         == 1) curr_count++; 
    }
    ret->max_dissem_blocks=MAX(ret->max_dissem_blocks, curr_count);
  }
  
  return ret;
}
Пример #6
0
myxml_node_t *myxml_createNode_attr_list(myxml_node_t* parent, const char *tag, const char **attribute_list, const char **attribute_vals, int num_attributes, const char *value) {
  int i;
  myxml_node_t *ret=gasneti_calloc(1,sizeof(myxml_node_t));
  ret->parent = parent;
  ret->num_children = 0;
  ret->children = NULL;
  /*make sure that we aren't adding to a leaf or know that this is the root node*/
  if(parent==NULL) {
    ret->nodeclass = MYXML_ROOT_NODE;
  } else if(parent->nodeclass == MYXML_LEAF_NODE) {
    fprintf(stderr, "can't add a child to a leaf node!\n");
    exit(1);
  }

  if(tag==NULL) {
    fprintf(stderr, "tag can't be null!\n");
    exit(1);
  } else {
    STR_ALLOC_AND_COPY(ret->tag, tag); 
  } 
  
  /*this mustbe a leaf node since an explicit value was declared*/
  if(value) {
    STR_ALLOC_AND_COPY(ret->value, value); 
    ret->nodeclass = MYXML_LEAF_NODE;
  } else if(parent!=NULL)  {
    ret->nodeclass = MYXML_INTER_NODE;
  }
  
  ret->attribute_list = gasneti_malloc(sizeof(myxml_attribute_t)*num_attributes);
  
  for(i=0; i<num_attributes; i++) {
    STR_ALLOC_AND_COPY(ret->attribute_list[i].attribute_name, attribute_list[i]);
    STR_ALLOC_AND_COPY(ret->attribute_list[i].attribute_value, attribute_vals[i]);
  }
  
  /*add myself to my parents children list*/
  if(parent) {
    parent->num_children++;
    if(parent->children) {
      parent->children = gasneti_realloc(parent->children,parent->num_children*sizeof(myxml_node_t*));
    } else {
      parent->children = gasneti_malloc(parent->num_children*sizeof(myxml_node_t*));
    }
    parent->children[parent->num_children-1] = ret;
  }
  
  return ret;
}
Пример #7
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];
}
Пример #8
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;
}
Пример #9
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);
}
Пример #10
0
void gasnete_coll_set_dissemination_order(gasnete_coll_local_tree_geom_t *geom, int gasnete_coll_tree_mynode, int gasnete_coll_tree_nodes) {
  
  int i = gasnete_coll_tree_nodes;
  int j, k;
  int factor;
  int lognp;
  gasnet_node_t *proc_list;
  
  lognp = 0;
  i = gasnete_coll_tree_nodes;
  while(i > 1) {
    lognp ++;
    i = i/2;
  }
  
  proc_list = (gasnet_node_t*)gasneti_malloc(sizeof(gasnet_node_t)*lognp);
  
  k=0;
  factor = 2;
  for(i=0; i<lognp; i++) {
    j = (gasnete_coll_tree_mynode + (factor/2))%factor;
    j += (gasnete_coll_tree_mynode / factor) * factor;
    proc_list[i] = j;
    factor = factor * 2;
  }
  
  geom->dissem_order = proc_list;
  geom->dissem_count = lognp;
}
Пример #11
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;
}
Пример #12
0
gasnete_coll_tree_type_t gasnete_coll_get_tree_type(void) {
  gasnete_coll_tree_type_t ret;
  
  ret = gasneti_lifo_pop(&gasnete_coll_tree_type_free_list);
  if(!ret) {
    ret = (gasnete_coll_tree_type_t) gasneti_malloc(sizeof(struct gasnete_coll_tree_type_t_));
  }
  memset(ret, 0, sizeof(struct gasnete_coll_tree_type_t_));
  return ret;
}
Пример #13
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;
}
Пример #14
0
gasnet_mxm_send_req_t * gasnetc_alloc_send_req(void)
{
    gasnet_mxm_send_req_t * sreq = (gasnet_mxm_send_req_t *)
#if GASNET_DEBUG
                                   gasneti_calloc(1, sizeof(gasnet_mxm_send_req_t));
#else
                                   gasneti_malloc(sizeof(gasnet_mxm_send_req_t));
#endif
    gasneti_assert(sreq && "Out of memory");
    return sreq;
}
Пример #15
0
/*  allocate a new iop */
GASNETI_NEVER_INLINE(gasnete_iop_alloc,
static gasnete_iop_t *gasnete_iop_alloc(gasneti_threaddata_t * const thread)) {
    gasnete_iop_t *iop = (gasnete_iop_t *)gasneti_malloc(sizeof(gasnete_iop_t));
    gasneti_leak(iop);
    #if GASNET_DEBUG
      memset(iop, 0, sizeof(gasnete_iop_t)); /* set pad to known value */
    #endif
    SET_OPTYPE((gasnete_op_t *)iop, OPTYPE_IMPLICIT);
    iop->threadidx = thread->threadidx;
    iop->initiated_get_cnt = 0;
    iop->initiated_put_cnt = 0;
    gasnetc_atomic_set(&(iop->completed_get_cnt), 0, 0);
    gasnetc_atomic_set(&(iop->completed_put_cnt), 0, 0);
    return iop;
}
Пример #16
0
gasnete_coll_tree_type_t gasnete_coll_make_tree_type(int tree_class,  int *params, int num_params) {
  gasnete_coll_tree_type_t ret= gasnete_coll_get_tree_type();
  
  
#if GASNET_DEBUG
  if(tree_class >= GASNETE_COLL_NUM_TREE_CLASSES) {
    gasneti_fatalerror("Unknown Tree Class: %d\n", tree_class);
  }
#endif  
  ret->tree_class = (gasnete_coll_tree_class_t) tree_class;
  ret->params = (int*) gasneti_malloc(sizeof(int)*num_params);
  GASNETE_FAST_UNALIGNED_MEMCPY_CHECK(ret->params, params, num_params*sizeof(int));
  ret->num_params = num_params;
  
  return ret;
}
Пример #17
0
extern gasnet_mxm_recv_req_t * gasnetc_alloc_recv_req(void)
{
    gasnet_mxm_recv_req_t * r;
    size_t size = GASNETI_PAGE_ALIGNUP(gasneti_AMMaxMedium());
    void * buf; 

    r = gasneti_malloc(sizeof(*r));
    gasneti_assert(r && "Out of memory");

    buf = gasneti_mmap(size);
    gasneti_assert(buf && "Out of memory");

    r->mxm_rreq.base.data.buffer.ptr = buf;
    r->mxm_rreq.base.data.buffer.length = size;

    return r;
}
Пример #18
0
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
}
Пример #19
0
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
}
Пример #20
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;
}
Пример #21
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;
}
Пример #22
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];
}
Пример #23
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;
}
Пример #24
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];
}
Пример #25
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];
}
Пример #26
0
/* ------------------------------------------------------------------------------------ */
extern int gasnetc_attach(gasnet_handlerentry_t *table, int numentries,
                          uintptr_t segsize, uintptr_t minheapoffset) {
  void *segbase = NULL;
  int ret;
  
  GASNETI_TRACE_PRINTF(C,("gasnetc_attach(table (%i entries), segsize=%lu, minheapoffset=%lu)",
                          numentries, (unsigned long)segsize, (unsigned long)minheapoffset));

  if (!gasneti_init_done) 
    GASNETI_RETURN_ERRR(NOT_INIT, "GASNet attach called before init");
  if (gasneti_attach_done) 
    GASNETI_RETURN_ERRR(NOT_INIT, "GASNet already attached");

  /*  check argument sanity */
  #if GASNET_SEGMENT_FAST || GASNET_SEGMENT_LARGE
    if ((segsize % GASNET_PAGESIZE) != 0) 
      GASNETI_RETURN_ERRR(BAD_ARG, "segsize not page-aligned");
    if (segsize > gasneti_MaxLocalSegmentSize) 
      GASNETI_RETURN_ERRR(BAD_ARG, "segsize too large");
    if ((minheapoffset % GASNET_PAGESIZE) != 0) /* round up the minheapoffset to page sz */
      minheapoffset = ((minheapoffset / GASNET_PAGESIZE) + 1) * GASNET_PAGESIZE;
  #else
    segsize = 0;
    minheapoffset = 0;
  #endif

  segsize = gasneti_auxseg_preattach(segsize); /* adjust segsize for auxseg reqts */

  /* ------------------------------------------------------------------------------------ */
  /*  register handlers */
  { int i;
    for (i = 0; i < GASNETC_MAX_NUMHANDLERS; i++) 
      gasnetc_handler[i] = (gasneti_handler_fn_t)&gasneti_defaultAMHandler;
  }
  { /*  core API handlers */
    gasnet_handlerentry_t *ctable = (gasnet_handlerentry_t *)gasnetc_get_handlertable();
    int len = 0;
    int numreg = 0;
    gasneti_assert(ctable);
    while (ctable[len].fnptr) len++; /* calc len */
    if (gasnetc_reghandlers(ctable, len, 1, 63, 0, &numreg) != GASNET_OK)
      GASNETI_RETURN_ERRR(RESOURCE,"Error registering core API handlers");
    gasneti_assert(numreg == len);
  }

  { /*  extended API handlers */
    gasnet_handlerentry_t *etable = (gasnet_handlerentry_t *)gasnete_get_handlertable();
    int len = 0;
    int numreg = 0;
    gasneti_assert(etable);
    while (etable[len].fnptr) len++; /* calc len */
    if (gasnetc_reghandlers(etable, len, 64, 127, 0, &numreg) != GASNET_OK)
      GASNETI_RETURN_ERRR(RESOURCE,"Error registering extended API handlers");
    gasneti_assert(numreg == len);
  }

  if (table) { /*  client handlers */
    int numreg1 = 0;
    int numreg2 = 0;

    /*  first pass - assign all fixed-index handlers */
    if (gasnetc_reghandlers(table, numentries, 128, 255, 0, &numreg1) != GASNET_OK)
      GASNETI_RETURN_ERRR(RESOURCE,"Error registering fixed-index client handlers");

    /*  second pass - fill in dontcare-index handlers */
    if (gasnetc_reghandlers(table, numentries, 128, 255, 1, &numreg2) != GASNET_OK)
      GASNETI_RETURN_ERRR(RESOURCE,"Error registering fixed-index client handlers");

    gasneti_assert(numreg1 + numreg2 == numentries);
  }

  /* ------------------------------------------------------------------------------------ */
  /*  register fatal signal handlers */

  /* catch fatal signals and convert to SIGQUIT */
  gasneti_registerSignalHandlers(gasneti_defaultSignalHandler);

  #if HAVE_ON_EXIT
    on_exit(gasnetc_on_exit, NULL);
  #else
    atexit(gasnetc_atexit);
  #endif

  /* ------------------------------------------------------------------------------------ */
  /*  register segment  */

  gasneti_seginfo = (gasnet_seginfo_t *)gasneti_malloc(gasneti_nodes*sizeof(gasnet_seginfo_t));
  gasneti_leak(gasneti_seginfo);

  #if GASNET_SEGMENT_FAST || GASNET_SEGMENT_LARGE
    if (segsize == 0) segbase = NULL; /* no segment */
    else {
      gasneti_segmentAttach(segsize, minheapoffset, gasneti_seginfo, &gasnetc_bootstrapExchange);
      segbase = gasneti_seginfo[gasneti_mynode].addr;
      segsize = gasneti_seginfo[gasneti_mynode].size;
      gasneti_assert(((uintptr_t)segbase) % GASNET_PAGESIZE == 0);
      gasneti_assert(segsize % GASNET_PAGESIZE == 0);
    }
  #else
  { /* GASNET_SEGMENT_EVERYTHING */
    gasnet_node_t i;
    for (i=0; i<gasneti_nodes; i++) {
      gasneti_seginfo[i].addr = (void *)0;
      gasneti_seginfo[i].size = (uintptr_t)-1;
    }
    segbase = (void *)0;
    segsize = (uintptr_t)-1;
  }
  #endif
  ret = gasnetc_p4_attach(segbase, segsize);
  if (GASNET_OK != ret) {
      GASNETI_RETURN_ERRR(RESOURCE,"Error attaching Portals4 resources");
  }

  /* ------------------------------------------------------------------------------------ */
  /*  gather segment information */
  /* This was done by segmentAttach above */

  /* ------------------------------------------------------------------------------------ */
  /*  primary attach complete */
  gasneti_attach_done = 1;
  gasnetc_bootstrapBarrier();

  GASNETI_TRACE_PRINTF(C,("gasnetc_attach(): primary attach complete"));

  gasneti_assert(gasneti_seginfo[gasneti_mynode].addr == segbase &&
         gasneti_seginfo[gasneti_mynode].size == segsize);

  gasneti_auxseg_attach(); /* provide auxseg */

  gasnete_init(); /* init the extended API */

  gasneti_nodemapFini();

  /* ensure extended API is initialized across nodes */
  gasnetc_bootstrapBarrier();

  return GASNET_OK;
}
Пример #27
0
/* ------------------------------------------------------------------------------------ */
extern int gasnetc_attach(gasnet_handlerentry_t *table, int numentries,
                          uintptr_t segsize, uintptr_t minheapoffset) {
  int retval = GASNET_OK;
  void *segbase = NULL;
  
  GASNETI_TRACE_PRINTF(C,("gasnetc_attach(table (%i entries), segsize=%lu, minheapoffset=%lu)",
                          numentries, (unsigned long)segsize, (unsigned long)minheapoffset));
  AMLOCK();
    if (!gasneti_init_done) 
      INITERR(NOT_INIT, "GASNet attach called before init");
    if (gasneti_attach_done) 
      INITERR(NOT_INIT, "GASNet already attached");

    /* pause to make sure all nodes have called attach 
       if a node calls gasnet_exit() between init/attach, then this allows us
       to process the AMUDP_SPMD control messages required for job shutdown
     */
    gasnetc_bootstrapBarrier();

    /*  check argument sanity */
    #if GASNET_SEGMENT_FAST || GASNET_SEGMENT_LARGE
      if ((segsize % GASNET_PAGESIZE) != 0) 
        INITERR(BAD_ARG, "segsize not page-aligned");
      if (segsize > gasneti_MaxLocalSegmentSize) 
        INITERR(BAD_ARG, "segsize too large");
      if ((minheapoffset % GASNET_PAGESIZE) != 0) /* round up the minheapoffset to page sz */
        minheapoffset = ((minheapoffset / GASNET_PAGESIZE) + 1) * GASNET_PAGESIZE;
    #else
      segsize = 0;
      minheapoffset = 0;
    #endif

    segsize = gasneti_auxseg_preattach(segsize); /* adjust segsize for auxseg reqts */

    /* ------------------------------------------------------------------------------------ */
    /*  register handlers */
#ifdef GASNETC_MAX_NUMHANDLERS
    /* Initialize shadow handler table */
    { int i;
      for (i=0; i<GASNETC_MAX_NUMHANDLERS; i++)
          gasnetc_handler[i]=(gasneti_handler_fn_t)&gasneti_defaultAMHandler;
    }
#endif
    { /*  core API handlers */
      gasnet_handlerentry_t *ctable = (gasnet_handlerentry_t *)gasnetc_get_handlertable();
      int len = 0;
      int numreg = 0;
      gasneti_assert(ctable);
      while (ctable[len].fnptr) len++; /* calc len */
      if (gasnetc_reghandlers(ctable, len, 1, 63, 0, &numreg) != GASNET_OK)
        INITERR(RESOURCE,"Error registering core API handlers");
      gasneti_assert(numreg == len);
    }

    { /*  extended API handlers */
      gasnet_handlerentry_t *etable = (gasnet_handlerentry_t *)gasnete_get_handlertable();
      int len = 0;
      int numreg = 0;
      gasneti_assert(etable);
      while (etable[len].fnptr) len++; /* calc len */
      if (gasnetc_reghandlers(etable, len, 64, 127, 0, &numreg) != GASNET_OK)
        INITERR(RESOURCE,"Error registering extended API handlers");
      gasneti_assert(numreg == len);
    }

    if (table) { /*  client handlers */
      int numreg1 = 0;
      int numreg2 = 0;

      /*  first pass - assign all fixed-index handlers */
      if (gasnetc_reghandlers(table, numentries, 128, 255, 0, &numreg1) != GASNET_OK)
        INITERR(RESOURCE,"Error registering fixed-index client handlers");

      /*  second pass - fill in dontcare-index handlers */
      if (gasnetc_reghandlers(table, numentries, 128, 255, 1, &numreg2) != GASNET_OK)
        INITERR(RESOURCE,"Error registering fixed-index client handlers");

      gasneti_assert(numreg1 + numreg2 == numentries);
    }

    /* ------------------------------------------------------------------------------------ */
    /*  register fatal signal handlers */

    /* catch fatal signals and convert to SIGQUIT */
    gasneti_registerSignalHandlers(gasneti_defaultSignalHandler);

#if HAVE_ON_EXIT
    on_exit(gasnetc_on_exit, NULL);
#else
    atexit(gasnetc_atexit);
#endif

    /* ------------------------------------------------------------------------------------ */
    /*  register segment  */

    gasneti_seginfo = (gasnet_seginfo_t *)gasneti_malloc(gasneti_nodes*sizeof(gasnet_seginfo_t));
    gasneti_leak(gasneti_seginfo);

    #if GASNET_SEGMENT_FAST || GASNET_SEGMENT_LARGE
      gasneti_segmentAttach(segsize, minheapoffset, gasneti_seginfo, &gasnetc_bootstrapExchange);
    #else /* GASNET_SEGMENT_EVERYTHING */
      { int i;
        for (i=0;i<gasneti_nodes;i++) {
          gasneti_seginfo[i].addr = (void *)0;
          gasneti_seginfo[i].size = (uintptr_t)-1;
        }
      }
    #endif
    segbase = gasneti_seginfo[gasneti_mynode].addr;
    segsize = gasneti_seginfo[gasneti_mynode].size;
  
    /* After local segment is attached, call optional client-provided hook
       (###) should call BEFORE any conduit-specific pinning/registration of the segment
     */
    if (gasnet_client_attach_hook) {
      gasnet_client_attach_hook(segbase, segsize);
    }

    /*  AMUDP allows arbitrary registration with no further action  */
    if (segsize) {
      retval = AM_SetSeg(gasnetc_endpoint, segbase, segsize);
      if (retval != AM_OK) INITERR(RESOURCE, "AM_SetSeg() failed");
    }

    #if GASNET_TRACE
      if (GASNETI_TRACE_ENABLED(A))
        GASNETI_AM_SAFE(AMUDP_SetHandlerCallbacks(gasnetc_endpoint,
          gasnetc_enteringHandler_hook, gasnetc_leavingHandler_hook));
    #endif

    /* ------------------------------------------------------------------------------------ */
    /*  primary attach complete */
    gasneti_attach_done = 1;
    gasnetc_bootstrapBarrier();
  AMUNLOCK();

  GASNETI_TRACE_PRINTF(C,("gasnetc_attach(): primary attach complete\n"));

  gasneti_auxseg_attach(); /* provide auxseg */

  gasnete_init(); /* init the extended API */

  gasneti_nodemapFini();

  /* ensure extended API is initialized across nodes */
  AMLOCK();
  gasnetc_bootstrapBarrier();
  AMUNLOCK();

  gasneti_assert(retval == GASNET_OK);
  return retval;

done: /*  error return while locked */
  AMUNLOCK();
  GASNETI_RETURN(retval);
}
Пример #28
0
/* ------------------------------------------------------------------------------------ */
extern int gasnetc_attach(gasnet_handlerentry_t *table, int numentries,
                          uintptr_t segsize, uintptr_t minheapoffset) {
  void *segbase = NULL;
  
  GASNETI_TRACE_PRINTF(C,("gasnetc_attach(table (%i entries), segsize=%"PRIuPTR", minheapoffset=%"PRIuPTR")",
                          numentries, segsize, minheapoffset));

  if (!gasneti_init_done) 
    GASNETI_RETURN_ERRR(NOT_INIT, "GASNet attach called before init");
  if (gasneti_attach_done) 
    GASNETI_RETURN_ERRR(NOT_INIT, "GASNet already attached");

  /*  check argument sanity */
  #if GASNET_SEGMENT_FAST || GASNET_SEGMENT_LARGE
    if ((segsize % GASNET_PAGESIZE) != 0) 
      GASNETI_RETURN_ERRR(BAD_ARG, "segsize not page-aligned");
    if (segsize > gasneti_MaxLocalSegmentSize) 
      GASNETI_RETURN_ERRR(BAD_ARG, "segsize too large");
    if ((minheapoffset % GASNET_PAGESIZE) != 0) /* round up the minheapoffset to page sz */
      minheapoffset = ((minheapoffset / GASNET_PAGESIZE) + 1) * GASNET_PAGESIZE;
  #else
    segsize = 0;
    minheapoffset = 0;
  #endif

  segsize = gasneti_auxseg_preattach(segsize); /* adjust segsize for auxseg reqts */

  /* ------------------------------------------------------------------------------------ */
  /*  register handlers */
  { int i;
    for (i = 0; i < GASNETC_MAX_NUMHANDLERS; i++) 
      gasnetc_handler[i] = (gasneti_handler_fn_t)&gasneti_defaultAMHandler;
  }
  { /*  core API handlers */
    gasnet_handlerentry_t *ctable = (gasnet_handlerentry_t *)gasnetc_get_handlertable();
    int len = 0;
    int numreg = 0;
    gasneti_assert(ctable);
    while (ctable[len].fnptr) len++; /* calc len */
    if (gasneti_amregister(ctable, len, 1, 63, 0, &numreg) != GASNET_OK)
      GASNETI_RETURN_ERRR(RESOURCE,"Error registering core API handlers");
    gasneti_assert(numreg == len);
  }

  { /*  extended API handlers */
    gasnet_handlerentry_t *etable = (gasnet_handlerentry_t *)gasnete_get_handlertable();
    int len = 0;
    int numreg = 0;
    gasneti_assert(etable);
    while (etable[len].fnptr) len++; /* calc len */
    if (gasneti_amregister(etable, len, 64, 127, 0, &numreg) != GASNET_OK)
      GASNETI_RETURN_ERRR(RESOURCE,"Error registering extended API handlers");
    gasneti_assert(numreg == len);
  }

  if (table) { /*  client handlers */
    int numreg1 = 0;
    int numreg2 = 0;

    /*  first pass - assign all fixed-index handlers */
    if (gasneti_amregister(table, numentries, 128, 255, 0, &numreg1) != GASNET_OK)
      GASNETI_RETURN_ERRR(RESOURCE,"Error registering fixed-index client handlers");

    /*  second pass - fill in dontcare-index handlers */
    if (gasneti_amregister(table, numentries, 128, 255, 1, &numreg2) != GASNET_OK)
      GASNETI_RETURN_ERRR(RESOURCE,"Error registering variable-index client handlers");

    gasneti_assert(numreg1 + numreg2 == numentries);
  }

  /* ------------------------------------------------------------------------------------ */
  /*  register fatal signal handlers */

  /* catch fatal signals and convert to SIGQUIT */
  gasneti_registerSignalHandlers(gasneti_defaultSignalHandler);

  /* ------------------------------------------------------------------------------------ */
  /*  setup fo rexit coordination */

  gasnetc_exittimeout = gasneti_get_exittimeout(GASNETC_DEFAULT_EXITTIMEOUT_MAX,
                                                GASNETC_DEFAULT_EXITTIMEOUT_MIN,
                                                GASNETC_DEFAULT_EXITTIMEOUT_FACTOR,
                                                GASNETC_DEFAULT_EXITTIMEOUT_MIN);
  #if HAVE_ON_EXIT
    on_exit(gasnetc_on_exit, NULL);
  #else
    atexit(gasnetc_atexit);
  #endif

  /* ------------------------------------------------------------------------------------ */
  /*  register segment  */

  gasneti_seginfo = (gasnet_seginfo_t *)gasneti_malloc(gasneti_nodes*sizeof(gasnet_seginfo_t));
  gasneti_leak(gasneti_seginfo);

  #if GASNET_SEGMENT_FAST || GASNET_SEGMENT_LARGE
    if (segsize == 0) segbase = NULL; /* no segment */
    else {
      gasneti_segmentAttach(segsize, minheapoffset, gasneti_seginfo, gasneti_bootstrapExchange);
      segbase = gasneti_seginfo[gasneti_mynode].addr;
      segsize = gasneti_seginfo[gasneti_mynode].size;
      gasneti_assert(((uintptr_t)segbase) % GASNET_PAGESIZE == 0);
      gasneti_assert(segsize % GASNET_PAGESIZE == 0);
    }
  #else
  { /* GASNET_SEGMENT_EVERYTHING */
    gasnet_node_t i;
    for (i=0; i<gasneti_nodes; i++) {
      gasneti_seginfo[i].addr = (void *)0;
      gasneti_seginfo[i].size = (uintptr_t)-1;
    }
    segbase = (void *)0;
    segsize = (uintptr_t)-1;
  }
  #endif

  gasnetc_ofi_attach(segbase, segsize);

  /* After local segment is attached, call optional client-provided hook
     (###) should call BEFORE any conduit-specific pinning/registration of the segment
   */
  if (gasnet_client_attach_hook) {
    gasnet_client_attach_hook(segbase, segsize);
  }

  /* ------------------------------------------------------------------------------------ */
  /*  primary attach complete */
  gasneti_attach_done = 1;
  gasneti_bootstrapBarrier();

  GASNETI_TRACE_PRINTF(C,("gasnetc_attach(): primary attach complete"));

  gasneti_assert(gasneti_seginfo[gasneti_mynode].addr == segbase &&
         gasneti_seginfo[gasneti_mynode].size == segsize);

  /* (###) exchange_fn is optional (may be NULL) and is only used with GASNET_SEGMENT_EVERYTHING
           if your conduit has an optimized bootstrapExchange pass it in place of NULL
   */
  gasneti_auxseg_attach(NULL); /* provide auxseg */

  gasnete_init(); /* init the extended API */

  gasneti_nodemapFini();

  /* ensure extended API is initialized across nodes */
  gasneti_bootstrapBarrier();

  return GASNET_OK;
}
Пример #29
0
/* Packetizes remotelist into a list of gasnete_packetdesc_t entries based on maxpayload packet size
     sharedpacket  => metadata and corresponding data travel together in unified packets (put)
                      so that for each packet i: datasz_i + metadatasz_i <= maxpayload
     !sharedpacket => metadata and corresponding data travel in separate packets (get)
                      so that for each packet i: MAX(datasz_i,metadatasz_i) <= maxpayload
   A local packet table is also computed to match the remote packetization boundaries of the data
     on a byte-for-byte basis
   Allocates and populates the plocalpt and premotept arrays with the packetization information
   Returns the number of packets described by the resulting plocalpt and premotept arrays
 */
size_t gasnete_packetize_addrlist(size_t remotecount, size_t remotelen,
                                  size_t localcount, size_t locallen,
                                  gasnete_packetdesc_t **premotept,
                                  gasnete_packetdesc_t **plocalpt,
                                  size_t maxpayload, int sharedpacket) {
  size_t ptidx;
  int done = 0;
  size_t ridx = 0, roffset = 0, lidx = 0, loffset = 0;
  size_t const metadatasz = sizeof(void *);
  size_t const runit = (sharedpacket ? metadatasz + remotelen : MAX(metadatasz,remotelen));
  size_t ptsz = (runit <= maxpayload ? /* conservative upper bound on packet count */
                 remotecount / (maxpayload / runit) + 1 : 
                 remotelen*remotecount / (maxpayload - 2*metadatasz) + 1); 
  gasnete_packetdesc_t *remotept = gasneti_malloc(ptsz*sizeof(gasnete_packetdesc_t));
  gasnete_packetdesc_t *localpt = gasneti_malloc(ptsz*sizeof(gasnete_packetdesc_t));
  gasneti_assert(premotept && plocalpt && remotecount && remotelen && localcount && locallen);
  gasneti_assert(remotecount*remotelen == localcount*locallen);
  gasneti_assert(remotecount*remotelen > 0);

  for (ptidx = 0; ; ptidx++) {
    ssize_t packetremain = maxpayload;
    ssize_t packetdata = 0;
    size_t rdatasz, ldatasz; 

    gasneti_assert(ptidx < ptsz);

    /* begin remote packet */
    remotept[ptidx].firstidx = ridx;
    remotept[ptidx].firstoffset = roffset;
    /* begin local packet */
    if_pf (lidx == localcount) localpt[ptidx].firstidx = lidx-1; 
    else                       localpt[ptidx].firstidx = lidx;
    localpt[ptidx].firstoffset = loffset;

    if (roffset > 0) { /* initial partial entry */
      gasneti_assert(roffset < remotelen);
      rdatasz = remotelen - roffset; /* data left in current entry */
      /* try to add the entire entry to packet */
      if (sharedpacket) packetremain -= (metadatasz + rdatasz);
      else              packetremain -= MAX(metadatasz, rdatasz);
      if (packetremain < 0) { /* overflowed - finished a packet, and spill to next */
        rdatasz += packetremain; /* compute truncated datasz that fits in this packet */
        roffset += rdatasz; /* update offset into current entry */
        packetdata += rdatasz;
        goto rend;
      } else {
        packetdata += rdatasz;
        roffset = 0; /* finished an entry */
        ridx++;
        if (ridx == remotecount) { done = 1; goto rend; } /* done - this is last packet */
      }
    }
    if (packetremain >= runit) { /* whole entries */
      size_t numunits = packetremain / runit;
      if (ridx + numunits > remotecount) numunits = remotecount - ridx;
      rdatasz = remotelen;
      packetremain -= runit*numunits;
      packetdata += remotelen*numunits;
      ridx += numunits;
      gasneti_assert(roffset == 0);
      if (ridx == remotecount) { done = 1; goto rend; } /* done - this is last packet */
    }
    if (packetremain > metadatasz) { /* trailing partial entry */
      gasneti_assert(packetremain < runit);
      if (sharedpacket) rdatasz = packetremain - metadatasz;
      else              rdatasz = packetremain;
      packetdata += rdatasz;
      roffset = rdatasz;
    }
    rend:
    /* end remote packet */
    if (roffset == 0) remotept[ptidx].lastidx = ridx-1;
    else              remotept[ptidx].lastidx = ridx;
    remotept[ptidx].lastlen = rdatasz;

    #if GASNET_DEBUG /* verify packing properties */
      gasnete_packetize_verify(remotept, ptidx, done, remotecount, remotelen, 0);
      { size_t datachk = 0, i;
        size_t entries = remotept[ptidx].lastidx - remotept[ptidx].firstidx + 1;
        for (i = remotept[ptidx].firstidx; i <= remotept[ptidx].lastidx; i++) {
          if (i == remotept[ptidx].lastidx) datachk += remotept[ptidx].lastlen;
          else if (i == remotept[ptidx].firstidx) datachk += (remotelen - remotept[ptidx].firstoffset);
          else datachk += remotelen;
        }
        gasneti_assert(packetdata == datachk);
        if (sharedpacket) { 
          gasneti_assert((metadatasz*entries + packetdata) <= maxpayload); /* not overfull */
          gasneti_assert(((metadatasz*entries + packetdata) >= maxpayload - metadatasz) || done); /* not underfull */
        } else {
          gasneti_assert(MAX(metadatasz*entries,packetdata) <= maxpayload); /* not overfull */
          gasneti_assert((MAX(metadatasz*entries,packetdata) >= maxpayload - 2*metadatasz) || done); /* not underfull */
        }
      }
    #endif

    ldatasz = 0;
    if (loffset > 0) { /* initial partial entry */
      gasneti_assert(loffset < locallen);
      ldatasz = locallen - loffset; /* data left in current entry */
      packetdata -= ldatasz;
      if (packetdata < 0) { /* overflowed - this entry spills into next packet */
        ldatasz += packetdata; /* compute truncated datasz that fits in this packet */
        loffset += ldatasz; /* update offset into current entry */
        packetdata = 0;
      } else {
        loffset = 0; /* finished an entry */
        lidx++;
        gasneti_assert(lidx < localcount || (lidx == localcount && packetdata == 0));
      }
    }
    if (packetdata >= locallen) { /* whole entries */
      size_t numunits = packetdata / locallen;
      if (lidx + numunits > localcount) numunits = localcount - lidx;
      ldatasz = locallen;
      packetdata -= locallen*numunits;
      lidx += numunits;
      gasneti_assert(lidx < localcount || (lidx == localcount && packetdata == 0));
      gasneti_assert(loffset == 0);
    }
    if (packetdata > 0) { /* trailing partial entry */
      gasneti_assert(packetdata < locallen);
      ldatasz = packetdata;
      loffset = ldatasz;
    }
    /* end local packet */
    if (loffset == 0) localpt[ptidx].lastidx = lidx-1;
    else              localpt[ptidx].lastidx = lidx;
    localpt[ptidx].lastlen = ldatasz;

    #if GASNET_DEBUG /* verify packing properties */
      gasnete_packetize_verify(localpt, ptidx, done, localcount, locallen, 0);
    #endif

    if (done) {
      gasneti_assert(ridx == remotecount && roffset == 0 && lidx == localcount && loffset == 0);
      *premotept = remotept;
      *plocalpt = localpt;
      return ptidx+1;
    }
  }
Пример #30
0
void smp_coll_set_barrier_routine_with_root(smp_coll_t handle, smp_coll_barrier_routine_t routine_id, int in_radix, int root) {
  
  smp_coll_safe_barrier(handle, 0);
  if(handle->dissem_info) smp_coll_free_dissemination(handle->dissem_info);
  handle->dissem_info = smp_coll_build_dissemination(in_radix, handle->MYTHREAD, handle->THREADS);
  
  handle->barrier_root = root;
  handle->barrier_radix = in_radix;
  handle->barrier_log_2_radix = smp_coll_mylogn(in_radix,2);
  handle->barrier_log_radix_THREADS = smp_coll_mylogn(handle->THREADS, in_radix);
  
  
  if(routine_id < SMP_COLL_NUM_BARR_ROUTINES /* && routine_id >=0 (TYPE IS UNSIGNED) */) { 
    handle->curr_barrier_routine = routine_id;
  } else {
    if(handle->MYTHREAD==0) fprintf(stderr, "bad barrier routine id: %d\n", routine_id);
    exit(1);
  }
#define ACT2REL(actrank) ( ((actrank) >= (root)) ? (actrank) - (root) : (actrank) \
- (root) + (handle->THREADS) )
#define REL2ACT(relrank) ( (relrank) < (handle->THREADS-root) ? \
(relrank) + (root) : (relrank) + (root) - (handle->THREADS))
  
  {
    int num_digits = handle->barrier_log_radix_THREADS;
    int radixlog2 = handle->barrier_log_2_radix;
    int radix = handle->barrier_radix;
    int i,j,k;
    int child_count=0;
    int myrelrank = ACT2REL(handle->MYTHREAD);
    
    if(myrelrank!=0) {
      i=0; 
      while(SMP_COLL_GET_ITH_DIGIT_POWER2RADIX(myrelrank,i,radix,radixlog2)==0) {
        i++;
      }
      handle->barrier_parent = REL2ACT(SMP_COLL_REPLACE_DIGIT_POWER2RADIX(myrelrank,i,0,radix,radixlog2));
    } else {
      handle->barrier_parent = -1;
    }
    
    /* reduce data from all the children*/
    for(i=num_digits-1,j=0; i>=0; i--,j++) {
      /*if my i^th digit is 0 that means that i am a sender for this round*/
      if(SMP_COLL_GET_ITH_DIGIT_POWER2RADIX(myrelrank, i, radix, radixlog2)==0 && 
         SMP_COLL_GET_LOWER_K_DIGITS_POWER2RADIX(myrelrank, i, radix, radixlog2)==0) {
        for(k=1;k<radix;k++) {
          int dest = SMP_COLL_MAKE_NUM_POWER2RADIX(myrelrank, i, k, radix, radixlog2);
          if(dest<handle->THREADS) {
            child_count++;
          }
        }
      } 
    }
    
    handle->barrier_children = (int*) gasneti_malloc(sizeof(int)*child_count);
    

    
    /*     if(child_count > 0) { */
    
    /*     } else { */
    /*       handle->barrier_children = NULL; */
    /*     } */
    
    handle->barrier_num_children = child_count;
    child_count = 0;
    
    for(i=num_digits-1,j=0; i>=0; i--,j++) {
      /*if my i^th digit is 0 that means that i am a sender for this round*/
      if(SMP_COLL_GET_ITH_DIGIT_POWER2RADIX(myrelrank, i, radix, radixlog2)==0 && 
         SMP_COLL_GET_LOWER_K_DIGITS_POWER2RADIX(myrelrank, i, radix, radixlog2)==0) {
        for(k=1;k<radix;k++) {
          int dest = SMP_COLL_MAKE_NUM_POWER2RADIX(myrelrank, i, k, radix, radixlog2);
          if(dest<handle->THREADS) {
            handle->barrier_children[child_count] = REL2ACT(dest);
            child_count++;
          }
        }
      } 
    }
    
    /*    print_barrier_tree(handle);  */
    
  }
  
  smp_coll_safe_barrier(handle, 0);
  
}