#include "src/include/pmix_config.h"
#include "include/pmix.h"
#include "src/class/pmix_object.h"
#include "src/class/pmix_list.h"
#include "src/client/pmix_client_ops.h"
#include "src/include/pmix_globals.h"
pmix_status_t pmix_client_convert_group_procs(const pmix_proc_t *inprocs, size_t insize,
pmix_proc_t **outprocs, size_t *outsize)
{
pmix_list_t cache;
pmix_proclist_t *nm;
pmix_group_t *grp;
size_t n, i, cnt, sz;
bool match;
uint32_t jsize;
pmix_status_t rc;
pmix_kval_t *kv;
pmix_proc_t *procs;
pmix_cb_t cb2;
PMIX_CONSTRUCT(&cache, pmix_list_t);
for (n = 0; n < insize; n++) {
match = false;
PMIX_LIST_FOREACH(grp, &pmix_client_globals.groups, pmix_group_t) {
if (PMIX_CHECK_NSPACE(grp->grpid, inprocs[n].nspace)) {
match = true;
if (PMIX_RANK_WILDCARD == inprocs[n].rank) {
for (i=0; i < grp->nmbrs; i++) {
nm = PMIX_NEW(pmix_proclist_t);
memcpy(&nm->proc, &grp->members[i], sizeof(pmix_proc_t));
pmix_list_append(&cache, &nm->super);
}
continue;
}
cnt = 0;
for (i = 0; i < grp->nmbrs; i++) {
if (PMIX_RANK_WILDCARD == grp->members[i].rank) {
PMIX_CONSTRUCT(&cb2, pmix_cb_t);
cb2.proc = (pmix_proc_t*)&grp->members[i];
cb2.key = PMIX_JOB_SIZE;
PMIX_GDS_FETCH_KV(rc, pmix_globals.mypeer, &cb2);
if (PMIX_SUCCESS != rc && PMIX_OPERATION_SUCCEEDED != rc) {
PMIX_LIST_DESTRUCT(&cache);
PMIX_DESTRUCT(&cb2);
return rc;
}
kv = (pmix_kval_t*)pmix_list_remove_first(&cb2.kvs);
PMIX_DESTRUCT(&cb2);
if (NULL == kv) {
PMIX_LIST_DESTRUCT(&cache);
return PMIX_ERR_NOT_FOUND;
}
PMIX_VALUE_GET_NUMBER(rc, kv->value, jsize, uint32_t);
PMIX_RELEASE(kv);
if (PMIX_SUCCESS != rc) {
PMIX_LIST_DESTRUCT(&cache);
return PMIX_ERR_BAD_PARAM;
}
if (cnt + jsize > inprocs[n].rank) {
nm = PMIX_NEW(pmix_proclist_t);
PMIX_LOAD_NSPACE(nm->proc.nspace, grp->members[i].nspace);
nm->proc.rank = inprocs[n].rank - cnt;
break;
} else {
cnt += jsize;
}
} else {
if (cnt == inprocs[n].rank) {
nm = PMIX_NEW(pmix_proclist_t);
memcpy(&nm->proc, &grp->members[i], sizeof(pmix_proc_t));
pmix_list_append(&cache, &nm->super);
break;
} else {
++cnt;
}
}
}
}
if (match) {
break;
}
}
if (!match) {
nm = PMIX_NEW(pmix_proclist_t);
memcpy(&nm->proc, &inprocs[n], sizeof(pmix_proc_t));
pmix_list_append(&cache, &nm->super);
}
}
sz = pmix_list_get_size(&cache);
PMIX_PROC_CREATE(procs, sz);
n = 0;
PMIX_LIST_FOREACH(nm, &cache, pmix_proclist_t) {
memcpy(&procs[n], &nm->proc, sizeof(pmix_proc_t));
++n;
}
PMIX_LIST_DESTRUCT(&cache);
*outprocs = procs;
*outsize = sz;
return PMIX_SUCCESS;
}