Omit usage of pre calculated prime numbers and factorize directly.
Optimization of the MPI_Dims_create function which omits the usage of pre calculated prime numbers and factorize directly as discussed at the developer list. cmr=v1.7.5:ticket=4217:reviewer=jsquyres This commit was SVN r30695. The following Trac tickets were found above: Ticket 4217 --> https://svn.open-mpi.org/trac/ompi/ticket/4217
Этот коммит содержится в:
родитель
85dce869c8
Коммит
010a806a58
@ -5,7 +5,7 @@
|
|||||||
* Copyright (c) 2004-2005 The University of Tennessee and The University
|
* Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||||
* of Tennessee Research Foundation. All rights
|
* of Tennessee Research Foundation. All rights
|
||||||
* reserved.
|
* reserved.
|
||||||
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
* Copyright (c) 2004-2014 High Performance Computing Center Stuttgart,
|
||||||
* University of Stuttgart. All rights reserved.
|
* University of Stuttgart. All rights reserved.
|
||||||
* Copyright (c) 2004-2005 The Regents of the University of California.
|
* Copyright (c) 2004-2005 The Regents of the University of California.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
@ -20,6 +20,8 @@
|
|||||||
|
|
||||||
#include "ompi_config.h"
|
#include "ompi_config.h"
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
#include "ompi/mpi/c/bindings.h"
|
#include "ompi/mpi/c/bindings.h"
|
||||||
#include "ompi/runtime/params.h"
|
#include "ompi/runtime/params.h"
|
||||||
#include "ompi/communicator/communicator.h"
|
#include "ompi/communicator/communicator.h"
|
||||||
@ -36,9 +38,8 @@
|
|||||||
static const char FUNC_NAME[] = "MPI_Dims_create";
|
static const char FUNC_NAME[] = "MPI_Dims_create";
|
||||||
|
|
||||||
/* static functions */
|
/* static functions */
|
||||||
static int assignnodes(int ndim, int nfactor, int *pfacts, int *counts, int **pdims);
|
static int assignnodes(int ndim, int nfactor, int *pfacts,int **pdims);
|
||||||
static int getfactors(int num, int nprime, int *primes, int **pcounts);
|
static int getfactors(int num, int *nfators, int **factors);
|
||||||
static int getprimes(int num, int *pnprime, int **pprimes);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -50,8 +51,7 @@ int MPI_Dims_create(int nnodes, int ndims, int dims[])
|
|||||||
int i;
|
int i;
|
||||||
int freeprocs;
|
int freeprocs;
|
||||||
int freedims;
|
int freedims;
|
||||||
int nprimes;
|
int nfactors;
|
||||||
int *primes;
|
|
||||||
int *factors;
|
int *factors;
|
||||||
int *procs;
|
int *procs;
|
||||||
int *p;
|
int *p;
|
||||||
@ -109,20 +109,14 @@ int MPI_Dims_create(int nnodes, int ndims, int dims[])
|
|||||||
return MPI_SUCCESS;
|
return MPI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Compute the relevant prime numbers for factoring */
|
|
||||||
if (MPI_SUCCESS != (err = getprimes(freeprocs, &nprimes, &primes))) {
|
|
||||||
return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, err,
|
|
||||||
FUNC_NAME);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Factor the number of free processes */
|
/* Factor the number of free processes */
|
||||||
if (MPI_SUCCESS != (err = getfactors(freeprocs, nprimes, primes, &factors))) {
|
if (MPI_SUCCESS != (err = getfactors(freeprocs, &nfactors, &factors))) {
|
||||||
return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, err,
|
return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, err,
|
||||||
FUNC_NAME);
|
FUNC_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Assign free processes to free dimensions */
|
/* Assign free processes to free dimensions */
|
||||||
if (MPI_SUCCESS != (err = assignnodes(freedims, nprimes, primes, factors, &procs))) {
|
if (MPI_SUCCESS != (err = assignnodes(freedims, nfactors, factors, &procs))) {
|
||||||
return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, err,
|
return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, err,
|
||||||
FUNC_NAME);
|
FUNC_NAME);
|
||||||
}
|
}
|
||||||
@ -135,7 +129,6 @@ int MPI_Dims_create(int nnodes, int ndims, int dims[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
free((char *) primes);
|
|
||||||
free((char *) factors);
|
free((char *) factors);
|
||||||
free((char *) procs);
|
free((char *) procs);
|
||||||
|
|
||||||
@ -154,12 +147,11 @@ int MPI_Dims_create(int nnodes, int ndims, int dims[])
|
|||||||
* Accepts: - # of dimensions
|
* Accepts: - # of dimensions
|
||||||
* - # of prime factors
|
* - # of prime factors
|
||||||
* - array of prime factors
|
* - array of prime factors
|
||||||
* - array of factor counts
|
|
||||||
* - ptr to array of dimensions (returned value)
|
* - ptr to array of dimensions (returned value)
|
||||||
* Returns: - 0 or ERROR
|
* Returns: - 0 or ERROR
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
assignnodes(int ndim, int nfactor, int *pfacts, int *counts, int **pdims)
|
assignnodes(int ndim, int nfactor, int *pfacts, int **pdims)
|
||||||
{
|
{
|
||||||
int *bins;
|
int *bins;
|
||||||
int i, j;
|
int i, j;
|
||||||
@ -185,17 +177,15 @@ assignnodes(int ndim, int nfactor, int *pfacts, int *counts, int **pdims)
|
|||||||
|
|
||||||
/* Loop assigning factors from the highest to the lowest */
|
/* Loop assigning factors from the highest to the lowest */
|
||||||
for (j = nfactor - 1; j >= 0; --j) {
|
for (j = nfactor - 1; j >= 0; --j) {
|
||||||
f = pfacts[j];
|
f = pfacts[j];
|
||||||
for (n = counts[j]; n > 0; --n) {
|
/* Assign a factor to the smallest bin */
|
||||||
/* Assign a factor to the smallest bin */
|
pmin = bins;
|
||||||
pmin = bins;
|
for (i = 1, p = pmin + 1; i < ndim; ++i, ++p) {
|
||||||
for (i = 1, p = pmin + 1; i < ndim; ++i, ++p) {
|
if (*p < *pmin) {
|
||||||
if (*p < *pmin) {
|
pmin = p;
|
||||||
pmin = p;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
*pmin *= f;
|
|
||||||
}
|
}
|
||||||
|
*pmin *= f;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sort dimensions in decreasing order (O(n^2) for now) */
|
/* Sort dimensions in decreasing order (O(n^2) for now) */
|
||||||
@ -217,96 +207,47 @@ assignnodes(int ndim, int nfactor, int *pfacts, int *counts, int **pdims)
|
|||||||
*
|
*
|
||||||
* Function: - factorize a number
|
* Function: - factorize a number
|
||||||
* Accepts: - number
|
* Accepts: - number
|
||||||
* - # of primes
|
* - # prime factors
|
||||||
* - array of primes
|
* - array of prime factors
|
||||||
* - ptr to array of counts (returned value)
|
* Returns: - MPI_SUCCESS or ERROR
|
||||||
* Returns: - 0 or ERROR
|
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
getfactors(int num, int nprime, int *primes, int **pcounts)
|
getfactors(int num, int *nfactors, int **factors) {
|
||||||
{
|
int size;
|
||||||
int *counts;
|
int n;
|
||||||
|
int d;
|
||||||
int i;
|
int i;
|
||||||
int *p;
|
int sqrtnum;
|
||||||
int *c;
|
|
||||||
|
if(num < 2) {
|
||||||
if (0 >= nprime) {
|
(*nfactors) = 0;
|
||||||
return MPI_ERR_INTERN;
|
(*factors) = NULL;
|
||||||
|
return MPI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
/* Allocate the array of prime factors which cannot exceed log_2(num) entries */
|
||||||
|
n = num;
|
||||||
|
sqrtnum = ceil(sqrt(num));
|
||||||
|
size = ceil(log(num) / log(2));
|
||||||
|
*factors = (int *) malloc((unsigned) size * sizeof(int));
|
||||||
|
|
||||||
/* Allocate the factor counts array */
|
i = 0;
|
||||||
counts = (int *) malloc((unsigned) nprime * sizeof(int));
|
/* determine all occurences of factor 2 */
|
||||||
if (NULL == counts) {
|
while((num % 2) == 0) {
|
||||||
return MPI_ERR_NO_MEM;
|
num /= 2;
|
||||||
|
(*factors)[i++] = 2;
|
||||||
}
|
}
|
||||||
|
/* determine all occurences of uneven prime numbers up to sqrt(num) */
|
||||||
*pcounts = counts;
|
d = 3;
|
||||||
|
for(d = 3; (num > 1) && (d < sqrtnum); d += 2) {
|
||||||
/* Loop over the prime numbers */
|
while((num % d) == 0) {
|
||||||
i = nprime - 1;
|
num /= d;
|
||||||
p = primes + i;
|
(*factors)[i++] = d;
|
||||||
c = counts + i;
|
|
||||||
|
|
||||||
for (; i >= 0; --i, --p, --c) {
|
|
||||||
*c = 0;
|
|
||||||
while ((num % *p) == 0) {
|
|
||||||
++(*c);
|
|
||||||
num /= *p;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* as we looped only up to sqrt(num) one factor > sqrt(num) may be left over */
|
||||||
if (1 != num) {
|
if(num != 1) {
|
||||||
return MPI_ERR_INTERN;
|
(*factors)[i++] = num;
|
||||||
}
|
}
|
||||||
|
(*nfactors) = i;
|
||||||
return MPI_SUCCESS;
|
return MPI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* getprimes
|
|
||||||
*
|
|
||||||
* Function: - get primes smaller than number
|
|
||||||
* - array of primes dynamically allocated
|
|
||||||
* Accepts: - number
|
|
||||||
* - ptr # of primes (returned value)
|
|
||||||
* - ptr array of primes (returned values)
|
|
||||||
* Returns: - 0 or ERROR
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
getprimes(int num, int *pnprime, int **pprimes) {
|
|
||||||
|
|
||||||
int i, j;
|
|
||||||
int n;
|
|
||||||
int size;
|
|
||||||
int *primes;
|
|
||||||
|
|
||||||
/* Allocate the array of primes */
|
|
||||||
size = (num / 2) + 1;
|
|
||||||
primes = (int *) malloc((unsigned) size * sizeof(int));
|
|
||||||
if (NULL == primes) {
|
|
||||||
return MPI_ERR_NO_MEM;
|
|
||||||
}
|
|
||||||
*pprimes = primes;
|
|
||||||
|
|
||||||
/* Find the prime numbers */
|
|
||||||
i = 0;
|
|
||||||
primes[i++] = 2;
|
|
||||||
|
|
||||||
for (n = 3; n <= num; n += 2) {
|
|
||||||
for (j = 1; j < i; ++j) {
|
|
||||||
if ((n % primes[j]) == 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (j == i) {
|
|
||||||
if (i >= size) {
|
|
||||||
return MPI_ERR_DIMS;
|
|
||||||
}
|
|
||||||
primes[i++] = n;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*pnprime = i;
|
|
||||||
return MPI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user