--- ad_lustre_aggregate.c 2009-07-02 17:19:27.000000000 +0200 +++ ad_lustre_aggregate.c.new 2010-01-14 14:58:15.000000000 +0100 @@ -22,9 +22,8 @@ * striping_info[1]: stripe_count * striping_info[2]: avail_cb_nodes */ - int stripe_size, stripe_count, CO = 1, CO_max = 1, CO_nodes, lflag; + int stripe_size, stripe_count, CO = 1; int avail_cb_nodes, divisor, nprocs_for_coll = fd->hints->cb_nodes; - char *value = (char *) ADIOI_Malloc((MPI_MAX_INFO_VAL + 1) * sizeof(char)); /* Get hints value */ /* stripe size */ @@ -33,9 +32,7 @@ /* stripe_size and stripe_count have been validated in ADIOI_LUSTRE_Open() */ stripe_count = fd->hints->striping_factor; - /* Calculate the available number of I/O clients, that is - * avail_cb_nodes=min(cb_nodes, stripe_count*CO), where - * CO=1 by default + /* Calculate the available number of I/O clients */ if (!mode) { /* for collective read, @@ -47,32 +44,43 @@ CO = 1; /*XXX: maybe there are other better way for collective read */ } else { - /* CO_max: the largest number of IO clients for each ost group */ - CO_max = (nprocs_for_coll - 1)/ stripe_count + 1; /* CO also has been validated in ADIOI_LUSTRE_Open(), >0 */ CO = fd->hints->fs_hints.lustre.co_ratio; - CO = ADIOI_MIN(CO_max, CO); } + /* Calculate how many IO clients we need */ /* To avoid extent lock conflicts, - * avail_cb_nodes should divide (stripe_count*CO) exactly, - * so that each OST is accessed by only one or more constant clients. */ - CO_nodes = stripe_count * CO; - avail_cb_nodes = ADIOI_MIN(nprocs_for_coll, CO_nodes); - if (avail_cb_nodes == CO_nodes) { - do { - /* find the divisor of CO_nodes */ - divisor = 1; - do { - divisor ++; - } while (CO_nodes % divisor); - CO_nodes = CO_nodes / divisor; - /* if stripe_count*CO is a prime number, change nothing */ - if ((CO_nodes <= avail_cb_nodes) && (CO_nodes != 1)) { - avail_cb_nodes = CO_nodes; - break; - } - } while (CO_nodes != 1); + * avail_cb_nodes should either be a multiple of stripe_count, + or divide stripe_count exactly. + * so that each OST is accessed by a maximum of CO constant clients. */ + + if (nprocs_for_coll >= stripe_count) + /* avail_cb_nodes should be a multiple of stripe_count and the number of procs per OST + should be limited to the minimum between nprocs_for_coll/stripe_count and CO + e.g. if stripe_count=20, nprocs_for_coll=42 and CO=3 then avail_cb_nodes should be egal to 40 */ + avail_cb_nodes = stripe_count * ADIOI_MIN(nprocs_for_coll/stripe_count, CO); + else { + /* nprocs_for_coll is less than stripe_count */ + /* avail_cb_nodes should divide stripe_count */ + /* e.g. if stripe_count=60 and nprocs_for_coll=8 then avail_cb_nodes should be egal to 6 */ + /* This could be done with : + while (stripe_count % avail_cb_nodes != 0) avail_cb_nodes--; + but this can be optimized for large values of nprocs_for_coll and stripe_count */ + divisor = 2; + avail_cb_nodes = 1; + /* try to divise */ + while (stripe_count >= divisor*divisor) { + if ((stripe_count % divisor) == 0) { + if (stripe_count/divisor <= nprocs_for_coll) { + /* The value is found ! */ + avail_cb_nodes = stripe_count/divisor; + break; + } + /* if divisor is less than nprocs_for_coll, divisor is a solution, but it is not sure that it is the best one */ + else if (divisor <= nprocs_for_coll) avail_cb_nodes = divisor; + } + divisor++; + } } *striping_info_ptr = (int *) ADIOI_Malloc(3 * sizeof(int)); @@ -80,8 +88,6 @@ striping_info[0] = stripe_size; striping_info[1] = stripe_count; striping_info[2] = avail_cb_nodes; - - ADIOI_Free(value); } int ADIOI_LUSTRE_Calc_aggregator(ADIO_File fd, ADIO_Offset off,