static HRESULT create_proxy( WS_CHANNEL *channel, const WS_PROXY_PROPERTY *properties, ULONG count, WS_SERVICE_PROXY **handle ) { struct proxy *proxy; HRESULT hr; ULONG i; if (!(proxy = alloc_proxy())) return E_OUTOFMEMORY; for (i = 0; i < count; i++) { hr = prop_set( proxy->prop, proxy->prop_count, properties[i].id, properties[i].value, properties[i].valueSize ); if (hr != S_OK) { free_proxy( proxy ); return hr; } } proxy->channel = channel; *handle = (WS_SERVICE_PROXY *)proxy; return S_OK; }
HYD_status HYDU_create_proxy_list(struct HYD_exec *exec_list, struct HYD_node *node_list, struct HYD_pg *pg) { struct HYD_proxy *proxy = NULL, *last_proxy = NULL, *tmp; struct HYD_exec *exec; struct HYD_node *node; int max_oversubscribe, c, num_procs, proxy_rem_cores, exec_rem_procs, allocated_procs; int filler_round, num_nodes, i, dummy_fillers; #if defined(FINEGRAIN_MPI) int current_exec_start_rank = 0; #endif HYD_status status = HYD_SUCCESS; HYDU_FUNC_ENTER(); /* Find the current maximum oversubscription on the nodes */ max_oversubscribe = 1; num_nodes = 0; for (node = node_list; node; node = node->next) { c = HYDU_dceil(node->active_processes, node->core_count); if (c > max_oversubscribe) max_oversubscribe = c; num_nodes++; } /* make sure there are non-zero cores available */ c = 0; for (node = node_list; node; node = node->next) c += (node->core_count * max_oversubscribe) - node->active_processes; if (c == 0) max_oversubscribe++; allocated_procs = 0; dummy_fillers = 1; for (node = node_list; node; node = node->next) { /* check how many cores are available */ c = (node->core_count * max_oversubscribe) - node->active_processes; /* create a proxy associated with this node */ status = alloc_proxy(&proxy, pg, node); HYDU_ERR_POP(status, "error allocating proxy\n"); proxy->filler_processes = c; allocated_procs += c; if (proxy->filler_processes < node->core_count) dummy_fillers = 0; if (pg->proxy_list == NULL) pg->proxy_list = proxy; else last_proxy->next = proxy; last_proxy = proxy; if (allocated_procs >= pg->pg_process_count) break; } /* If all proxies have as many filler processes as the number of * cores, we can reduce those filler processes */ if (dummy_fillers) for (proxy = pg->proxy_list; proxy; proxy = proxy->next) proxy->filler_processes -= proxy->node->core_count; /* Proxy list is created; add the executables to the proxy list */ if (pg->proxy_list->next == NULL) { /* Special case: there is only one proxy, so all executables * directly get appended to this proxy */ for (exec = exec_list; exec; exec = exec->next) { #if defined(FINEGRAIN_MPI) status = add_exec_to_proxy(exec, pg->proxy_list, exec->proc_count, current_exec_start_rank); HYDU_ERR_POP(status, "unable to add executable to proxy\n"); current_exec_start_rank += exec->proc_count * exec->nfg; #else status = add_exec_to_proxy(exec, pg->proxy_list, exec->proc_count); HYDU_ERR_POP(status, "unable to add executable to proxy\n"); #endif } } else { exec = exec_list; filler_round = 1; for (proxy = pg->proxy_list; proxy && proxy->filler_processes == 0; proxy = proxy->next); if (proxy == NULL) { filler_round = 0; proxy = pg->proxy_list; } exec_rem_procs = exec->proc_count; proxy_rem_cores = filler_round ? proxy->filler_processes : proxy->node->core_count; while (exec) { if (exec_rem_procs == 0) { exec = exec->next; if (exec) exec_rem_procs = exec->proc_count; else break; } HYDU_ASSERT(exec_rem_procs, status); while (proxy_rem_cores == 0) { proxy = proxy->next; if (proxy == NULL) { filler_round = 0; proxy = pg->proxy_list; } proxy_rem_cores = filler_round ? proxy->filler_processes : proxy->node->core_count; } num_procs = (exec_rem_procs > proxy_rem_cores) ? proxy_rem_cores : exec_rem_procs; HYDU_ASSERT(num_procs, status); exec_rem_procs -= num_procs; proxy_rem_cores -= num_procs; #if defined(FINEGRAIN_MPI) status = add_exec_to_proxy(exec, proxy, num_procs, current_exec_start_rank); HYDU_ERR_POP(status, "unable to add executable to proxy\n"); current_exec_start_rank += num_procs * exec->nfg; #else status = add_exec_to_proxy(exec, proxy, num_procs); HYDU_ERR_POP(status, "unable to add executable to proxy\n"); #endif } } /* find dummy proxies and remove them */ while (pg->proxy_list->exec_list == NULL) { tmp = pg->proxy_list->next; pg->proxy_list->next = NULL; HYDU_free_proxy_list(pg->proxy_list); pg->proxy_list = tmp; } for (proxy = pg->proxy_list; proxy->next;) { if (proxy->next->exec_list == NULL) { tmp = proxy->next; proxy->next = proxy->next->next; tmp->next = NULL; HYDU_free_proxy_list(tmp); } else { proxy = proxy->next; } } for (proxy = pg->proxy_list, i = 0; proxy; proxy = proxy->next, i++) proxy->proxy_id = i; fn_exit: HYDU_FUNC_EXIT(); return status; fn_fail: goto fn_exit; }