📄 cb_config_list.c
字号:
yylval = NULL; ADIOI_Free(used_procnames); return cur_rank;}/* ADIOI_cb_copy_name_array() - attribute copy routine */int ADIOI_cb_copy_name_array(MPI_Comm comm, int *keyval, void *extra, void *attr_in, void **attr_out, int *flag){ ADIO_cb_name_array array; array = (ADIO_cb_name_array) attr_in; array->refct++; *attr_out = attr_in; *flag = 1; /* make a copy in the new communicator */ return MPI_SUCCESS;}/* ADIOI_cb_delete_name_array() - attribute destructor */int ADIOI_cb_delete_name_array(MPI_Comm comm, int *keyval, void *attr_val, void *extra){ int i; ADIO_cb_name_array array; array = (ADIO_cb_name_array) attr_val; array->refct--; if (array->refct <= 0) { /* time to free the structures (names, array of ptrs to names, struct) */ for (i=0; i < array->namect; i++) { ADIOI_Free(array->names[i]); } if (array->names != NULL) ADIOI_Free(array->names); ADIOI_Free(array); } return MPI_SUCCESS;}/* match_procs() - given a name (or NULL for wildcard) and a max. number * of aggregator processes (per processor name), this * matches in the procnames[] array and puts appropriate * ranks in the ranks array. * * Parameters: * name - processor name (or NULL for wildcard) * max_per_proc - maximum # of processes to use for aggregation from a * single processor * procnames - array of processor names * nr_procnames - length of procnames array * ranks - array of process ranks * nr_ranks - length of process ranks array (also max. # of aggregators) * nr_ranks_allocated - # of array entries which have been filled in, * which is also the index to the first empty entry * * Returns number of matches. */static int match_procs(char *name, int max_per_proc, char *procnames[], char used_procnames[], int nr_procnames, int ranks[], int nr_ranks, int *nr_ranks_allocated){ int wildcard_proc, cur_proc, old_nr_allocated, ret; /* save this so we can report on progress */ old_nr_allocated = *nr_ranks_allocated; if (name == NULL) { /* wildcard case */ /* optimize for *:0 case */ if (max_per_proc == 0) { /* loop through procnames and mark them all as used */ for (cur_proc = 0; cur_proc < nr_procnames; cur_proc++) { used_procnames[cur_proc] = 1; } return 0; } /* the plan here is to start at the beginning of the procnames * array looking for processor names to apply the wildcard to. * * we set wildcard_proc to 0 here but do the search inside the * while loop so that we aren't starting our search from the * beginning of the procnames array each time. */ wildcard_proc = 0; while (nr_ranks - *nr_ranks_allocated > 0) { /* find a name */ while ((wildcard_proc < nr_procnames) && (used_procnames[wildcard_proc] != 0)) { wildcard_proc++; } if (wildcard_proc == nr_procnames) { /* we have used up the entire procnames list */ return *nr_ranks_allocated - old_nr_allocated; }#ifdef CB_CONFIG_LIST_DEBUG FPRINTF(stderr, "performing wildcard match (*:%d) starting with %s (%d)\n", max_per_proc, procnames[wildcard_proc], wildcard_proc);#endif cur_proc = wildcard_proc;#ifdef CB_CONFIG_LIST_DEBUG FPRINTF(stderr, " assigning name %s (%d) to rank %d in mapping\n", procnames[cur_proc], cur_proc, *nr_ranks_allocated);#endif /* alloc max_per_proc from this host; cur_proc points to * the first one. We want to save this name for use in * our while loop. */ ranks[*nr_ranks_allocated] = cur_proc; *nr_ranks_allocated = *nr_ranks_allocated + 1; cur_proc++; /* so, to accomplish this we use the match_this_proc() to * alloc max_per_proc-1. we increment cur_proc so that the * procnames[] entry doesn't get trashed. then AFTER the call * we clean up the first instance of the name. */ ret = match_this_proc(procnames[wildcard_proc], cur_proc, max_per_proc-1, procnames, used_procnames, nr_procnames, ranks, nr_ranks, *nr_ranks_allocated); if (ret > 0) *nr_ranks_allocated = *nr_ranks_allocated + ret; /* clean up and point wildcard_proc to the next entry, since * we know that this one is NULL now. */ used_procnames[wildcard_proc] = 1; wildcard_proc++; } } else { /* specific host was specified; this one is easy */#ifdef CB_CONFIG_LIST_DEBUG FPRINTF(stderr, "performing name match (%s:%d)\n", name, max_per_proc);#endif ret = match_this_proc(name, 0, max_per_proc, procnames, used_procnames, nr_procnames, ranks, nr_ranks, *nr_ranks_allocated); if (ret > 0) *nr_ranks_allocated = *nr_ranks_allocated + ret; } return *nr_ranks_allocated - old_nr_allocated;}/* match_this_proc() - find each instance of processor name "name" in * the "procnames" array, starting with index "cur_proc" * and add the first "max_matches" into the "ranks" * array. remove all instances of "name" from * "procnames". * * Parameters: * name - processor name to match * cur_proc - index into procnames[] at which to start matching * procnames - array of processor names * used_procnames - array of values indicating if a given procname has * been allocated or removed already * nr_procnames - length of procnames array * ranks - array of processor ranks * nr_ranks - length of ranks array * nr_ranks_allocated - number of ranks already filled in, or the next * entry to fill in (equivalent) * * Returns number of ranks filled in (allocated). */static int match_this_proc(char *name, int cur_proc, int max_matches, char *procnames[], char used_procnames[], int nr_procnames, int ranks[], int nr_ranks, int nr_ranks_allocated){ int ranks_remaining, nr_to_alloc, old_nr_allocated; old_nr_allocated = nr_ranks_allocated; /* calculate how many ranks we want to allocate */ ranks_remaining = nr_ranks - nr_ranks_allocated; nr_to_alloc = (max_matches < ranks_remaining) ? max_matches : ranks_remaining; while (nr_to_alloc > 0) { cur_proc = find_name(name, procnames, used_procnames, nr_procnames, cur_proc); if (cur_proc < 0) { /* didn't find it */ return nr_ranks_allocated - old_nr_allocated; } /* need bounds checking on ranks */#ifdef CB_CONFIG_LIST_DEBUG FPRINTF(stderr, " assigning name %s (%d) to rank %d in mapping\n", procnames[cur_proc], cur_proc, nr_ranks_allocated);#endif ranks[nr_ranks_allocated] = cur_proc; nr_ranks_allocated++; used_procnames[cur_proc] = 1; cur_proc++; nr_to_alloc--; } /* take all other instances of this host out of the list */ while (cur_proc >= 0) { cur_proc = find_name(name, procnames, used_procnames, nr_procnames, cur_proc); if (cur_proc >= 0) {#ifdef CB_CONFIG_LIST_DEBUG FPRINTF(stderr, " taking name %s (%d) out of procnames\n", procnames[cur_proc], cur_proc);#endif used_procnames[cur_proc] = 1; cur_proc++; } } return nr_ranks_allocated - old_nr_allocated;} /* find_name() - finds the first entry in procnames[] which matches name, * starting at index start_ind * * Returns an index [0..nr_procnames-1] on success, -1 if not found. */static int find_name(char *name, char *procnames[], char used_procnames[], int nr_procnames, int start_ind){ int i; for (i=start_ind; i < nr_procnames; i++) { if (!used_procnames[i] && !strcmp(name, procnames[i])) break; } if (i < nr_procnames) return i; else return -1;}/* get_max_procs() - grab the maximum number of processes to use out of * the cb_config_list string * * Parameters: * cb_nodes - cb_nodes value. this is returned when a "*" is encountered * as the max_procs value. * * Returns # of processes, or -1 on error. */static int get_max_procs(int cb_nodes){ int token, max_procs = -1; char *errptr; token = cb_config_list_lex(); switch(token) { case AGG_EOS: case AGG_COMMA: return 1; case AGG_COLON: token = cb_config_list_lex(); if (token != AGG_WILDCARD && token != AGG_STRING) return -1; if (token == AGG_WILDCARD) max_procs = cb_nodes; else if (token == AGG_STRING) { max_procs = strtol(yylval, &errptr, 10); if (*errptr != '\0') { /* some garbage value; default to 1 */ max_procs = 1; } } /* strip off next comma (if there is one) */ token = cb_config_list_lex(); if (token != AGG_COMMA && token != AGG_EOS) return -1; /* return max_procs */ if (max_procs < 0) return -1; else return max_procs; } return -1;}/* cb_config_list_lex() - lexical analyzer for cb_config_list language * * Returns a token of types defined at top of this file. */static int cb_config_list_lex(void){ int slen; if (*token_ptr == '\0') return AGG_EOS; slen = strcspn(token_ptr, ":,"); if (*token_ptr == ':') { token_ptr++; return AGG_COLON; } if (*token_ptr == ',') { token_ptr++; return AGG_COMMA; } if (*token_ptr == '*') { /* make sure that we don't have characters after the '*' */ if (slen == 1) { token_ptr++; return AGG_WILDCARD; } else return AGG_ERROR; } /* last case: some kind of string. for now we copy the string. */ /* it would be a good idea to look at the string and make sure that * it doesn't have any illegal characters in it. in particular we * should ensure that no one tries to use wildcards with strings * (e.g. "ccn*"). */ strncpy(yylval, token_ptr, slen); yylval[slen] = '\0'; token_ptr += slen; return AGG_STRING;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -