⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 az_gsumd_puma.c

📁 并行解法器,功能强大
💻 C
字号:
/*==================================================================== * ------------------------ * | CVS File Information | * ------------------------ * * $RCSfile: az_gsumd_puma.c,v $ * * $Author: tuminaro $ * * $Date: 1996/04/26 20:35:35 $ * * $Revision: 1.6 $ * * $Name:  $ *====================================================================*/#ifndef lintstatic char rcsid[] = "$Id: az_gsumd_puma.c,v 1.6 1996/04/26 20:35:35 tuminaro Exp $";#endif/******************************************************************************* * Copyright 1995, Sandia Corporation.  The United States Government retains a * * nonexclusive license in this software as prescribed in AL 88-1 and AL 91-7. * * Export of this program may require a license from the United States         * * Government.                                                                 * ******************************************************************************/#include <stdlib.h>     /* these appear outside of ifdef */#include <stdio.h>      /* to avoid a lint warning       */#ifdef PUMA_GSUMD       /* Only compiled in on request. */#include <sunmos.h>/****************************************************************************//****************************************************************************//****************************************************************************/double AZ_gsum_double(double val, int proc_config[])/*******************************************************************************  Sum a double value across all processors. Use a low level call and pack value  into header for efficiency. NOTE: must be compiled WITHOUT  -Mnodepchk  and  -Msafeptr.  Author:          Bruce Hendrickson, SNL, 1422  =======  Return code:     double, result of global sum.  ============  Parameter list:  ===============  val:             Value to be summed from each processor.  proc_config:     Machine configuration.  proc_config[AZ_node] is the node                   number.  proc_config[AZ_N_procs] is the number of processors.*******************************************************************************/{  /* local variables */  int     type;                 /* type of next message */  int     data;                 /* integer message being sent */  int     partner;              /* processor I exchange with */  int     mask;                 /* bit pattern identifying partner */  int     hbit;                 /* largest nonzero bit in nprocs */  int     nprocs_small;         /* largest power of 2 <= nprocs */  int    *vptr;                 /* pointer into parts of val */  int    *vptrp;                /* pointer into parts of val */  int    *v2ptr;                /* pointer into parts of val2 */  int    *v2ptrp;               /* pointer into parts of val2 */  double  val2;                 /* arriving value to add */  int     cflag;                /* dummy argument for compatability */  void    exit();  int     _nsend(), _nrecv();  int     node, nprocs;  /**************************** execution begins ******************************/  node   = proc_config[AZ_node];  nprocs = proc_config[AZ_N_procs];  vptr   = (int *) &val;  vptrp  = vptr + 1;  v2ptr  = (int *) &val2;  v2ptrp = v2ptr + 1;  /* Find next lower power of 2. */  for (hbit = 0; (nprocs >> hbit) != 1; hbit++);  nprocs_small = 1 << hbit;  if (nprocs_small*2 == nprocs) {    nprocs_small *= 2;    hbit++;  }  partner = node ^ nprocs_small;  if (node & nprocs_small) {    data = *vptr;    type = *vptrp;    if (_nsend((char *) NULL, 0, partner, type, NULL, data)) {      (void)fprintf(stderr, "AZ_gsum_double: ERROR on node %d\n", node);      (void)fprintf(stderr, "nwrite failed, message type = %d\n", type);      exit(-1);    }  }  else if (node + nprocs_small < nprocs) {    type = -1;    cflag = 0;    if (_nrecv((char *) NULL, &cflag, &partner, &type, NULL, &data) != 0) {      (void)fprintf(stderr, "AZ_gsum_double: ERROR on node %d\n", node);      (void)fprintf(stderr, "nwrite failed, message type = %d\n", type);      exit(-1);    }    *(v2ptr)  = data;    *(v2ptrp) = type;    val      += *((double *) v2ptr);  }  /* Now do a binary exchange on nprocs_small nodes. */  if (!(node & nprocs_small)) {    for (mask = nprocs_small>>1; mask; mask >>= 1) {      partner = node ^ mask;      data    = *vptr;      type    = *(vptrp);      if (_nsend((char *) NULL, 0, partner, type, NULL, data)) {        (void)fprintf(stderr, "AZ_gsum_double: ERROR on node %d\n", node);        (void)fprintf(stderr, "nwrite failed, message type = %d\n", type);        exit(-1);      }      type  = -1;      cflag = 0;      if (_nrecv((char *)NULL, &cflag, &partner, &type, NULL, &data) != 0) {        (void) fprintf(stderr, "AZ_gsum_double: ERROR on node %d\n",                       node);        (void) fprintf(stderr, "nwrite failed, message type = %d\n",                       type);        exit(-1);      }      *(v2ptr)  = data;      *(v2ptrp) = type;      val      += *((double *) v2ptr);    }  }  else type += hbit;  /* Finally, send message from lower half to upper half. */  partner = node ^ nprocs_small;  if (node & nprocs_small) {    type  = -1;    cflag = 0;    if (_nrecv((char *) NULL, &cflag, &partner, &type, NULL, &data) != 0) {      (void) fprintf(stderr, "AZ_gsum_double: ERROR on node %d\n", node);      (void) fprintf(stderr, "nwrite failed, message type = %d\n", type);      exit(-1);    }    *(vptr)  = data;    *(vptrp) = type;  }  else if (node+nprocs_small < nprocs) {    data = *vptr;    type = *(vptrp);    if (_nsend((char *) NULL, 0, partner, type, NULL, data)) {      (void) fprintf(stderr, "AZ_gsum_double: ERROR on node %d\n", node);      (void) fprintf(stderr, "nwrite failed, message type = %d\n", type);      exit(-1);    }  }  return val;}#endif /* ifdef PUMA_GSUMD */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -