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

📄 az_tools.c

📁 并行解法器,功能强大
💻 C
📖 第 1 页 / 共 5 页
字号:
   * Create 'new_external' which explicitly put the external elements in the   * order given by 'extern_index'   */  new_external = (int *) AZ_allocate((unsigned) (N_external+1)*sizeof(int));  if (new_external == NULL) {    (void) fprintf(stderr, "%sERROR: Not enough dynamic space.\n", yo);    exit(-1);  }  for (i = 0; i < N_external; i++) {    new_external[extern_index[i] - N_update] = external[i];  }  /*   * Send each processor the global index list of the external elements in the   * order that I will want to receive them when updating my external elements   */  type            = AZ_sys_msg_type;  AZ_sys_msg_type = (AZ_sys_msg_type+1-AZ_MSG_TYPE) % AZ_NUM_MSGS + AZ_MSG_TYPE;  lens = (int *) AZ_allocate((num_recv_neighbors+1)*sizeof(int));  if (lens == NULL) {    (void) fprintf(stderr, "%sERROR: Not enough dynamic space.\n", yo);    exit(-1);  }  for (i = 0; i < num_recv_neighbors; i++) {    length     = sizeof(int);    partner    = recv_list[i];    mdwrap_iread((void *) &(lens[i]), length, &partner, &type, request+i);  }  j = 0;  for (i = 0; i < num_recv_neighbors; i++) {    start  = j;    newlength = 0;    /* go through list of external elements until updating processor changes */    while ((j < N_external) && (new_extern_proc[j] == recv_list[i])) {      if (mat_type != AZ_VBR_MATRIX) newlength++;      else newlength += (cnptr[j + 1 + N_update] - cnptr[j + N_update]);      j++;      if (j == N_external) break;    }    (*data_org)[AZ_rec_length+i] = newlength;    (*data_org)[AZ_neighbors+i]  = recv_list[i];    length = j - start;    mdwrap_write((void *) &length, sizeof(int), recv_list[i], type, &cflag);  }  /* receive from each neighbor the global index list of external ele */  for (i = 0; i < num_recv_neighbors; i++) {    length     = sizeof(int);    partner    = (*data_org)[AZ_neighbors+i];    mdwrap_wait((void *) &(lens[i]), length, &partner, &type, &cflag,request+i);    (*data_org)[AZ_send_length + i] = lens[i];  }  AZ_free(lens);  type            = AZ_sys_msg_type;  AZ_sys_msg_type = (AZ_sys_msg_type+1-AZ_MSG_TYPE) % AZ_NUM_MSGS + AZ_MSG_TYPE;  j = 0;  for (i = 0; i < num_recv_neighbors; i++) {    length     = (  (*data_org)[AZ_send_length + i] ) * sizeof(int);    partner    = (*data_org)[AZ_neighbors+i];    mdwrap_iread((void *) &(send_ptr[j]), length, &partner, &type, request+i);    j += (*data_org)[AZ_send_length + i];  }  j = 0;  for (i = 0; i < num_recv_neighbors; i++) {    start  = j;    newlength = 0;    /* go through list of external elements until updating processor changes */    while ((j < N_external) && (new_extern_proc[j] == recv_list[i])) {      if (mat_type != AZ_VBR_MATRIX) newlength++;      else newlength += (cnptr[j + 1 + N_update] - cnptr[j + N_update]);      j++;      if (j == N_external) break;    }    mdwrap_write((void *) &(new_external[start]), (j-start)* sizeof(int),             recv_list[i], type, &cflag);  }  /* receive from each neighbor the global index list of external ele */  j = 0;  for (i = 0; i < num_recv_neighbors; i++) {    length     = (  (*data_org)[AZ_send_length + i] ) * sizeof(int);    partner    = (*data_org)[AZ_neighbors+i];    mdwrap_wait((void *) &(send_ptr[j]), length, &partner, &type, &cflag,		 request+i);    j += (*data_org)[AZ_send_length + i];  }  tj = 0;  if (mat_type == AZ_VBR_MATRIX) {    (*data_org)[AZ_matrix_type] = AZ_VBR_MATRIX;    /* move the information to the back of the send_ptr */    for (i = j - 1; i >= 0; i--) send_ptr[total_to_be_sent+i-j] = send_ptr[i];    tj = total_to_be_sent - j;  }  else (*data_org)[AZ_matrix_type] = AZ_MSR_MATRIX;  total_to_be_sent = j;  /* replace global indices by local indices */  oldii     = ii = 0;  tt        = tj;  firstone  = AZ_send_length;  current   = firstone;  while (((*data_org)[current] == 0) && (current-firstone < num_recv_neighbors))    current++;  bins = (int *) AZ_allocate((unsigned) (N_update / 4 + 10)*sizeof(int));  if (bins == NULL) {    (void) fprintf(stderr, "%sERROR: Not enough dynamic space.\n", yo);    exit(-1);  }  for (i = 0 ; i < N_update / 4 + 10 ; i++ ) bins[i] = 0;  AZ_init_quick_find(update, N_update, &shift, bins);  for (i = tj; i < total_to_be_sent + tj; i++) {    /*     * j = AZ_find_index(send_ptr[i], update, N_update);     */    j = AZ_quick_find(send_ptr[i], update, N_update, shift, bins);    if (j == -1) {      (void) fprintf(stderr, "%sERROR: A point (%d) requested from processor "                     "%d\nwas not found among the update ele of proc %d\n", yo,                     send_ptr[i], (*data_org)[AZ_neighbors+current-firstone],                     proc);      exit(-1);    }    if (mat_type != AZ_VBR_MATRIX) {      send_ptr[ii] = update_index[j];      ii +=  1;    }    else {      start = cnptr[update_index[j]];      end   = cnptr[update_index[j] + 1] - 1;      for (new_i = start; new_i <= end; new_i++) send_ptr[ii++] = new_i;      if (i - tt + 1 == (*data_org)[current]) {        (*data_org)[current] = ii - oldii;        current++;        while ( ((*data_org)[current] == 0) &&                (current-firstone < num_recv_neighbors)) current++;        oldii = ii;        tt    = i + 1;      }    }  }  AZ_free((char *) bins);  AZ_free((char *) recv_list);  AZ_free((char *) new_external);  AZ_free((char *) new_extern_proc);  (*data_org)[AZ_N_neigh] = num_send_neighbors;} /* AZ_set_message_info *//******************************************************************************//******************************************************************************//******************************************************************************/void AZ_convert_values_to_ptrs(int array[], int length, int start)/*******************************************************************************  Change 'array[]' so that on exit     1) array[0] = start     2) array[i+1] - array[i] = value of array[i] on entry to this routine.  Author:          Ray S. Tuminaro, SNL, 1422  =======  Return code:     void  ============  Parameter list:  ===============  array:           On entry to this routine and array[0] = start.                   On output, array[i+1] - array[i] = value of array[i].  length:          Length of array[].*******************************************************************************/{  /* local variables */  int i;  /**************************** execution begins ******************************/  for (i = 1; i < length; i++) array[i] += array[i - 1];  for (i = length; i > 0; i--)  array[i]  = array[i - 1] + start;  array[0] = start;} /* AZ_convert_values_to_ptrs *//******************************************************************************//******************************************************************************//******************************************************************************/void AZ_convert_ptrs_to_values(int array[], int length)/*******************************************************************************  Author:          Ray S. Tuminaro, SNL, 1422  =======  Return code:     void  ============  Parameter list:  ===============  array:           On entry to this routine and array[0] = start.                   On output, array[i+1] - array[i] = value of array[i].  length:          Length of array[].*******************************************************************************/{  int i;  for (i = 0; i < length; i++) array[i] = array[i + 1] - array[i];}/******************************************************************************//******************************************************************************//******************************************************************************/void AZ_msr2vbr(double val[], int indx[], int rnptr[], int cnptr[], int bnptr[],                int bindx[], int msr_bindx[], double msr_val[],                int total_blk_rows, int total_blk_cols, int blk_space,                int nz_space, int blk_type)/*******************************************************************************  Convert the MSR matrix defined in [msr_val,msr_bindx] to a VBR matrix.  Author:          Ray S. Tuminaro, SNL, 1422  =======  Return code:     void  ============  Parameter list:  ===============  val,  rnptr,  bindx,  indx,  bnptr,  cnptr:           Sparse matrix arrays. See User's Guide.                   On input, the matrix corresponds to the initial ordering                   (e.g. row i corresponds to global row update[i]).                   On output, the matrix rows and columns are renumbered to                   correspond to the ordering given by 'update_index' and                   'extern_index'. (e.g. global row update[i] now appears                   as row update_index[i] in the matrix).  msr_val,  msr_bindx:       On input, MSR matrix to be converted to VBR.                   See User's Guide.  total_blk_rows:  Number of block rows in resulting local VBR matrix.  total_blk_cols:  Number of block columns in resulting local VBR matrix.  blk_space:       Length of storage allocated for bindx[] and indx[]. An error                   message will be printed if we try to write past these arrays.  nz_space:        Length of storage allocated for val[]. An error message will                   be printed if we try to write past this array.  blk_type:        If blk_type > 0, blk_type indicates that all block rows (and                   colunns) have the same size given by 'blk_type'. If                   blk_type < 0, the block rows have different sizes.*******************************************************************************/{  /* local variables */  int therow, thecol;  int i, j;  /**************************** execution begins ******************************/  for (i = 0; i < total_blk_rows; i++) rnptr[i] = cnptr[i];  AZ_convert_values_to_ptrs(rnptr, total_blk_rows, 0);  AZ_convert_values_to_ptrs(cnptr, total_blk_cols, 0);  indx[0] = bnptr[0] = 0;  /* go through each block row */  for (i = 0; i < total_blk_rows; i++) {    bnptr[i + 1] = bnptr[i];    for (therow = rnptr[i]; therow < rnptr[i + 1]; therow++) {      /* add the diagonal entry */      thecol = therow;      AZ_add_new_ele(cnptr, therow, i, bindx, bnptr, indx, val, therow,                     msr_val[therow], total_blk_cols, blk_space, nz_space,                     blk_type);      /* add off diagonal entries */      for (j = msr_bindx[therow]; j < msr_bindx[therow + 1]; j++) {        thecol = msr_bindx[j];        AZ_add_new_ele(cnptr, thecol, i, bindx, bnptr, indx, val, therow,                       msr_val[j], total_blk_cols, blk_space, nz_space,                       blk_type);      }    }  }} /* AZ_msr2vbr *//******************************************************************************//******************************************************************************//******************************************************************************/int AZ_find_block_col(int cnptr[], int column, int max_blocks, int blk_size)/*******************************************************************************  Return the local index of the block column witch contains the point column  given by local index 'column'.  Author:          Ray S. Tuminaro, SNL, 1422  =======  Return code:     int, local index of the block column.  ============  Parameter list:  ===============  cnptr:           cnptr[0] = 0 and cnptr[i+1] - cnptr[i] gives the column                   dimension of global block column                     'update[i]' if  i <  N_update                     'external[k]' if  i >= N_update                   where k = i - N_update.  column:          Local column index of the column for which we are trying to                   find the block column containing it.  blk_size:        blk_size > 0 ==> all the blocks are the same size so we can                   use a shortcut in computing the block column index.                   blk_size = 0 ==> short cut not used.*******************************************************************************/

⌨️ 快捷键说明

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