az_mat_free_com.c

来自「并行解法器,功能强大」· C语言 代码 · 共 273 行

C
273
字号
/*==================================================================== * ------------------------ * | CVS File Information | * ------------------------ * * $RCSfile: az_mat_free_com.c,v $ * * $Author: tuminaro $ * * $Date: 2000/06/02 16:46:55 $ * * $Revision: 1.8 $ * * $Name:  $ *====================================================================*/#ifndef lintstatic char rcsid[] = "$Id: az_mat_free_com.c,v 1.8 2000/06/02 16:46:55 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.                                                                 * ******************************************************************************//******************************************************************************* * MATRIX FREE  communication. ******************************************************************************/#include <stdio.h>#include <stdlib.h>#include <math.h>#include "az_aztec.h"#include "example_specific.h"void example_specific_comm_setup(int npoints, int *nx, int *ny, int proc,                              int nproc, struct exchange *comm_structure){/* * Set up the data structure 'comm_structure'. In particular, set  * *   comm_structure->length_message[i] number of data points to exchange *                                     with the ith neighbor. *   comm_structure->neighbor_list[i]  proc id of ith neighbor (if the ith *                                     neighbor does not exist, = -1). *   comm_structure->buf               buffer space for grouping data *   comm_structure->send_list[i][j]   jth point index to send to ith neighbor *   comm_structure->recv_data[i]      data_buffer where information from the *                                     ith neighbor will be received. * * Note: i = LEFT, RIGHT, BOTTOM, TOP * * The data (npoints) is set so up as uniformly as possible on a processor  * array of size 'nproc X nproc'.  * * Parameters * ========== * * npoints          On input, number of data points to be distributed. * * nx,ny            On output, grid size of local grid. * * proc             On input, processor id of this processor. * * nproc            On input, nproc * nproc is the total number of processors. *  * comm_structure   On output, comm_structure is set (as described above)  *                  to do local data exchanges to update ghost variables. */   int    px, py, N_augmented_procs,  j;   int    send_coord;  /* Convert the proc id's to processor array coordinates: (px, py) */  /* Note: the processors are aligned on a nproc X nproc processor  */  /*       array.                                                   */  py = proc/nproc;  px = proc%nproc;  /* Compute the number of points per processor in each direction   */  /* Note: some processors may contain 1 additional point in a      */  /*       coordinate direction than others.                        */  *nx = npoints/nproc;  *ny = *nx;  N_augmented_procs = npoints%nproc;  if (px >= nproc-N_augmented_procs) *nx = *nx+1;  if (py >= nproc-N_augmented_procs) *ny = *ny+1;  /* allocate space to hold indices of data points to be */  /* sent to neighbors and indices of data points to be  */  /* received from neighbors.                            */  comm_structure->send_list[LEFT  ] = (int *) malloc(*ny * sizeof(int));  comm_structure->send_list[RIGHT ] = (int *) malloc(*ny * sizeof(int));  comm_structure->send_list[BOTTOM] = (int *) malloc(*nx * sizeof(int));  comm_structure->send_list[TOP   ] = (int *) malloc(*nx * sizeof(int));  comm_structure->rcv_data[LEFT   ] = (double *) malloc(*ny * sizeof(double));  comm_structure->rcv_data[RIGHT  ] = (double *) malloc(*ny * sizeof(double));  comm_structure->rcv_data[BOTTOM ] = (double *) malloc(*nx * sizeof(double));  comm_structure->rcv_data[TOP    ] = (double *) malloc(*nx * sizeof(double));  if (comm_structure->rcv_data[TOP    ] == NULL) {     printf("%d: Not enough memory to setup communication structure\n", proc);     exit(1);  }  comm_structure->length_message[LEFT]   = 0;  comm_structure->length_message[RIGHT]  = 0;  comm_structure->length_message[TOP]    = 0;  comm_structure->length_message[BOTTOM] = 0;      /* get the neighbor numbers and indices */  /* to exchange with each neighbor       */      /* if there is a left neighbor*/  comm_structure->neighbor_list[LEFT] = -1;  if (px !=0) {       comm_structure->neighbor_list[LEFT]  = proc-1;       comm_structure->length_message[LEFT] = *ny;       send_coord = 0;       for ( j = 0; j< *ny; j++) {             comm_structure->send_list[LEFT][j] = send_coord;             send_coord += *nx;       }  }  /* if right neighbor exists */  comm_structure->neighbor_list[RIGHT] = -1;  if (px != nproc -1) {       comm_structure->neighbor_list[RIGHT]  = proc+1;       comm_structure->length_message[RIGHT] = *ny;       send_coord = *nx - 1;       for ( j = 0; j< *ny; j++) {          comm_structure->send_list[RIGHT][j] = send_coord;          send_coord = send_coord + *nx;       }  }  /* if bottom neighbor exists */  comm_structure->neighbor_list[BOTTOM] = -1;  if (py != 0) {       comm_structure->neighbor_list[BOTTOM]  = proc-nproc;       comm_structure->length_message[BOTTOM] = *nx;       for ( j = 0; j< *nx; j++)           comm_structure->send_list[BOTTOM][j] = j;  }  /* if top neighbor exists */  comm_structure->neighbor_list[TOP] = -1;  if (py !=nproc -1) {       comm_structure->neighbor_list[TOP] = proc+nproc;       comm_structure->length_message[TOP] = *nx;       send_coord = (*ny-1)*(*nx);       for ( j = 0; j< *nx; j++) {             comm_structure->send_list[TOP][j] = send_coord;             send_coord++;       }  }  comm_structure->buf   = (double *) malloc(2*((*nx)+(*ny)) * sizeof(double));  if (comm_structure->buf  == NULL) {     printf("%d: Not enough memory to setup communication structure\n",proc);     exit(1);  }#ifdef AZ_MPI  AZ_set_proc_config(comm_structure->proc_config, MPI_COMM_WORLD);#else  AZ_set_proc_config(comm_structure->proc_config, AZ_NOT_MPI);#endif}/*********************************************************************//*********************************************************************//*********************************************************************/void example_specific_exchange_data ( double *x, struct exchange *comm_structure){ /* * Exchange data between neighboring processors to update ghost * variables. Specifically, on output comm_structure->recv_data[i] holds * the appropriate data for each neighbor. This data is determined * by the structure 'comm_structure': * *     comm_structure->length_message[i]    number of data points to exchange *                                   with the ith neighbor. *     comm_structure->nieghbor_list[i]     proc id of ith neighbor (if the ith *                                   neighbor does not exist, = -1). *     comm_structure->buf                  buffer space for grouping data *     comm_structure->send_list[i][j]      index of jth point to send to ith neighbor *     comm_structure->recv_data[i]         data_buffer where information from the *                                   ith neighbor will be received. * Note: i = LEFT, RIGHT, BOTTOM, TOP */int         *neighbor_list, *length_message; int         *send_list;int         i, j, k, type, flag, count;double      *buf; MPI_AZRequest request[4];int         *proc_config;    length_message = comm_structure->length_message;    neighbor_list  = comm_structure->neighbor_list;    buf            = (double *) comm_structure->buf;    proc_config    = comm_structure->proc_config;    type = 123;    for (i = 0 ; i < 4 ; i++ ) {       if (neighbor_list[i] != -1)           mdwrap_iread((void *) comm_structure->rcv_data[i],                         sizeof(double)*length_message[i], &(neighbor_list[i]),                         &type, &(request[i]));    }       count = 0;    for (i = 0 ; i < 4 ; i++ ) {       if (neighbor_list[i] != -1) {          send_list   =  comm_structure->send_list[i];          k = count;          for ( j =0;j<length_message[i];j++) buf[count++] = x[send_list[j]];          mdwrap_write((void *) &(buf[k]), sizeof(double)*length_message[i],		        neighbor_list[i], type, &flag);       }    }    for ( i =0; i< 4; i++) {       if (neighbor_list[i] != -1) {          mdwrap_wait((void *) comm_structure->rcv_data[i], sizeof(double)*                     length_message[i], &(neighbor_list[i]), &type, &flag,                     &(request[i]));       }    }}/******************************************************************//******************************************************************//******************************************************************/void example_specific_frees(struct exchange *comm_structure){  /* free all fields of 'comm_structure' that we allocated inside */  /* az_mat_free_com_set_up.                               */  free(comm_structure->buf);  free(comm_structure->rcv_data[TOP    ]);  free(comm_structure->rcv_data[BOTTOM ]);  free(comm_structure->rcv_data[RIGHT  ]);  free(comm_structure->rcv_data[LEFT   ]);  free(comm_structure->send_list[TOP   ]);  free(comm_structure->send_list[BOTTOM]);  free(comm_structure->send_list[RIGHT ]);  free(comm_structure->send_list[LEFT  ]);}

⌨️ 快捷键说明

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