abc -DHYPRE_TIMING -iquote ./AMG2013 -iquote AMG2013/IJ_mv -iquote AMG2013/krylov -iquote AMG2013/parcsr_ls -iquote AMG2013/parcsr_mv -iquote AMG2013/seq_mv -iquote AMG2013/sstruct_mv -iquote AMG2013/struct_mv -iquote AMG2013/test -iquote AMG2013/utilities  AMG2013/test/amg2013.c AMG2013/IJ_mv/HYPRE_IJMatrix.c AMG2013/IJ_mv/HYPRE_IJVector.c AMG2013/IJ_mv/IJMatrix_parcsr.c AMG2013/IJ_mv/IJVector_parcsr.c AMG2013/IJ_mv/aux_par_vector.c AMG2013/IJ_mv/aux_parcsr_matrix.c AMG2013/krylov/HYPRE_gmres.c AMG2013/krylov/HYPRE_pcg.c AMG2013/krylov/gmres.c AMG2013/krylov/pcg.c AMG2013/parcsr_ls/HYPRE_parcsr_amg.c AMG2013/parcsr_ls/HYPRE_parcsr_gmres.c AMG2013/parcsr_ls/HYPRE_parcsr_pcg.c AMG2013/parcsr_ls/aux_interp.c AMG2013/parcsr_ls/gen_redcs_mat.c AMG2013/parcsr_ls/par_amg.c AMG2013/parcsr_ls/par_amg_setup.c AMG2013/parcsr_ls/par_amg_solve.c AMG2013/parcsr_ls/par_cg_relax_wt.c AMG2013/parcsr_ls/par_coarse_parms.c AMG2013/parcsr_ls/par_coarsen.c AMG2013/parcsr_ls/par_cycle.c AMG2013/parcsr_ls/par_indepset.c AMG2013/parcsr_ls/par_interp.c AMG2013/parcsr_ls/par_jacobi_interp.c AMG2013/parcsr_ls/par_laplace.c AMG2013/parcsr_ls/par_laplace_27pt.c AMG2013/parcsr_ls/par_lr_interp.c AMG2013/parcsr_ls/par_multi_interp.c AMG2013/parcsr_ls/par_nodal_systems.c AMG2013/parcsr_ls/par_rap.c AMG2013/parcsr_ls/par_rap_communication.c AMG2013/parcsr_ls/par_relax.c AMG2013/parcsr_ls/par_relax_interface.c AMG2013/parcsr_ls/par_relax_more.c AMG2013/parcsr_ls/par_scaled_matnorm.c AMG2013/parcsr_ls/par_stats.c AMG2013/parcsr_ls/par_strength.c AMG2013/parcsr_ls/par_vardifconv.c AMG2013/parcsr_ls/partial.c AMG2013/parcsr_ls/pcg_par.c AMG2013/parcsr_mv/HYPRE_parcsr_matrix.c AMG2013/parcsr_mv/HYPRE_parcsr_vector.c AMG2013/parcsr_mv/new_commpkg.c AMG2013/parcsr_mv/par_csr_assumed_part.c AMG2013/parcsr_mv/par_csr_communication.c AMG2013/parcsr_mv/par_csr_matop.c AMG2013/parcsr_mv/par_csr_matop_marked.c AMG2013/parcsr_mv/par_csr_matrix.c AMG2013/parcsr_mv/par_csr_matvec.c AMG2013/parcsr_mv/par_vector.c AMG2013/seq_mv/HYPRE_csr_matrix.c AMG2013/seq_mv/HYPRE_vector.c AMG2013/seq_mv/big_csr_matrix.c AMG2013/seq_mv/csr_matop.c AMG2013/seq_mv/csr_matrix.c AMG2013/seq_mv/csr_matvec.c AMG2013/seq_mv/genpart.c AMG2013/seq_mv/vector.c AMG2013/sstruct_mv/HYPRE_sstruct_graph.c AMG2013/sstruct_mv/HYPRE_sstruct_grid.c AMG2013/sstruct_mv/HYPRE_sstruct_matrix.c AMG2013/sstruct_mv/HYPRE_sstruct_stencil.c AMG2013/sstruct_mv/HYPRE_sstruct_vector.c AMG2013/sstruct_mv/box_map.c AMG2013/sstruct_mv/sstruct_axpy.c AMG2013/sstruct_mv/sstruct_copy.c AMG2013/sstruct_mv/sstruct_graph.c AMG2013/sstruct_mv/sstruct_grid.c AMG2013/sstruct_mv/sstruct_innerprod.c AMG2013/sstruct_mv/sstruct_matrix.c AMG2013/sstruct_mv/sstruct_matvec.c AMG2013/sstruct_mv/sstruct_overlap_innerprod.c AMG2013/sstruct_mv/sstruct_scale.c AMG2013/sstruct_mv/sstruct_stencil.c AMG2013/sstruct_mv/sstruct_vector.c AMG2013/struct_mv/HYPRE_struct_grid.c AMG2013/struct_mv/HYPRE_struct_matrix.c AMG2013/struct_mv/HYPRE_struct_stencil.c AMG2013/struct_mv/HYPRE_struct_vector.c AMG2013/struct_mv/assumed_part.c AMG2013/struct_mv/box.c AMG2013/struct_mv/box_algebra.c AMG2013/struct_mv/box_alloc.c AMG2013/struct_mv/box_boundary.c AMG2013/struct_mv/box_manager.c AMG2013/struct_mv/box_neighbors.c AMG2013/struct_mv/communication_info.c AMG2013/struct_mv/computation.c AMG2013/struct_mv/grow.c AMG2013/struct_mv/new_assemble.c AMG2013/struct_mv/new_box_neighbors.c AMG2013/struct_mv/project.c AMG2013/struct_mv/struct_axpy.c AMG2013/struct_mv/struct_communication.c AMG2013/struct_mv/struct_copy.c AMG2013/struct_mv/struct_grid.c AMG2013/struct_mv/struct_innerprod.c AMG2013/struct_mv/struct_io.c AMG2013/struct_mv/struct_matrix.c AMG2013/struct_mv/struct_matrix_mask.c AMG2013/struct_mv/struct_matvec.c AMG2013/struct_mv/struct_overlap_innerprod.c AMG2013/struct_mv/struct_scale.c AMG2013/struct_mv/struct_stencil.c AMG2013/struct_mv/struct_vector.c AMG2013/utilities/amg_linklist.c AMG2013/utilities/binsearch.c AMG2013/utilities/exchange_data.c AMG2013/utilities/hypre_error.c AMG2013/utilities/hypre_memory.c AMG2013/utilities/hypre_qsort.c AMG2013/utilities/memory_dmalloc.c AMG2013/utilities/mpistubs.c AMG2013/utilities/qsplit.c AMG2013/utilities/random.c AMG2013/utilities/thread_mpistubs.c AMG2013/utilities/threading.c AMG2013/utilities/timer.c AMG2013/utilities/timing.c AMG2013/utilities/umalloc_local.c -summarize -prune
ABC v0.2 of 31-mar-2014 -- http://vsl.cis.udel.edu/abc

//======================== stdlib.h ========================
typedef unsigned long size_t;
$system[stdlib] double atof(char* nptr);
int atoi(char* nptr);
double strtod(char* restrict nptr, char** restrict endptr);
long strtol(char* restrict nptr, char** restrict endptr, int base);
void* calloc(size_t nmemb, size_t size);
$atomic_f void free(void* ptr);
void* malloc(size_t size);
void* realloc(void* ptr, size_t size);
$atomic_f void exit(int status);
int abs(int j);
//========================== op.h ==========================
typedef enum Operation{
  _NO_OP,
  _MAX,
  _MIN,
  _SUM,
  _PROD,
  _LAND,
  _BAND,
  _LOR,
  _BOR,
  _LXOR,
  _BXOR,
  _MINLOC,
  _MAXLOC,
  _REPLACE
} Operation;
//===================== civl-stdio.cvh =====================
typedef struct FILE FILE;
//========================= stdio.h ========================
extern FILE* stdout;
extern FILE* stderr;
$system[stdio] int fclose(FILE* stream);
$system[stdio] int fflush(FILE* stream);
FILE* fopen(char* restrict filename, char* restrict mode);
$system[stdio] int fprintf(FILE* restrict stream, char* restrict format, ...);
$system[stdio] int printf(char* restrict format, ...);
$system[stdio] int sprintf(char* restrict s, char* restrict format, ...);
$system[stdio] int sscanf(char* restrict s, char* restrict format, ...);
$system[stdio] char* fgets(char* restrict s, int n, FILE* restrict stream);
//========================= math.h =========================
double cos(double x);
double fabs(double x);
double pow(double x, double y);
double sqrt(double x);
//========================== mpi.h =========================
typedef enum Operation MPI_Op;
typedef enum MPI_Datatype{
  MPI_CHAR=0,
  MPI_CHARACTER=1,
  MPI_SIGNED_CHAR,
  MPI_UNSIGNED_CHAR,
  MPI_BYTE=2,
  MPI_WCHAR,
  MPI_SHORT=3,
  MPI_UNSIGNED_SHORT,
  MPI_INT=4,
  MPI_INT16_T,
  MPI_INT32_T,
  MPI_INT64_T,
  MPI_INT8_T,
  MPI_INTEGER,
  MPI_INTEGER1,
  MPI_INTEGER16,
  MPI_INTEGER2,
  MPI_INTEGER4,
  MPI_INTEGER8,
  MPI_UNSIGNED,
  MPI_LONG=5,
  MPI_UNSIGNED_LONG,
  MPI_FLOAT=9,
  MPI_DOUBLE=10,
  MPI_LONG_DOUBLE=11,
  MPI_LONG_LONG_INT=6,
  MPI_UNSIGNED_LONG_LONG=7,
  MPI_LONG_LONG=8,
  MPI_PACKED,
  MPI_LB,
  MPI_UB,
  MPI_UINT16_T,
  MPI_UINT32_T,
  MPI_UINT64_T,
  MPI_UINT8_T,
  MPI_FLOAT_INT,
  MPI_DOUBLE_INT,
  MPI_LONG_INT,
  MPI_SHORT_INT,
  MPI_2INT=12,
  MPI_LONG_DOUBLE_INT,
  MPI_AINT,
  MPI_OFFSET,
  MPI_2DOUBLE_PRECISION,
  MPI_2INTEGER,
  MPI_2REAL,
  MPI_C_BOOL,
  MPI_C_COMPLEX,
  MPI_C_DOUBLE_COMPLEX,
  MPI_C_FLOAT_COMPLEX,
  MPI_C_LONG_DOUBLE_COMPLEX,
  MPI_COMPLEX,
  MPI_COMPLEX16,
  MPI_COMPLEX32,
  MPI_COMPLEX4,
  MPI_COMPLEX8,
  MPI_REAL,
  MPI_REAL16,
  MPI_REAL2,
  MPI_REAL4,
  MPI_REAL8
} MPI_Datatype;
typedef struct MPI_Comm MPI_Comm;
typedef struct MPI_Group MPI_Group;
typedef struct MPI_Request* MPI_Request;
typedef struct MPI_User_function MPI_User_function;
typedef struct MPI_Status{
  int MPI_SOURCE;
  int MPI_TAG;
  int MPI_ERROR;
  int size;
} MPI_Status;
const extern MPI_Comm MPI_COMM_NULL;
MPI_Comm MPI_COMM_WORLD;
extern MPI_Comm MPI_COMM_SELF;
int MPI_Send(void*, int, MPI_Datatype, int, int, MPI_Comm);
int MPI_Recv(void*, int, MPI_Datatype, int, int, MPI_Comm, MPI_Status*);
int MPI_Get_count(MPI_Status*, MPI_Datatype, int*);
int MPI_Isend(void*, int, MPI_Datatype, int, int, MPI_Comm, MPI_Request*);
int MPI_Irecv(void*, int, MPI_Datatype, int, int, MPI_Comm, MPI_Request*);
int MPI_Test(MPI_Request*, int*, MPI_Status*);
int MPI_Waitall(int, MPI_Request*, MPI_Status*);
int MPI_Testall(int, MPI_Request*, int*, MPI_Status*);
int MPI_Iprobe(int, int, MPI_Comm, int*, MPI_Status*);
int MPI_Barrier(MPI_Comm);
int MPI_Bcast(void*, int, MPI_Datatype, int, MPI_Comm);
int MPI_Gather(void*, int, MPI_Datatype, void*, int, MPI_Datatype, int, MPI_Comm);
int MPI_Gatherv(void*, int, MPI_Datatype, void*, int*, int*, MPI_Datatype, int, MPI_Comm);
int MPI_Scatterv(void*, int*, int*, MPI_Datatype, void*, int, MPI_Datatype, int, MPI_Comm);
int MPI_Allgather(void*, int, MPI_Datatype, void*, int, MPI_Datatype, MPI_Comm);
int MPI_Allgatherv(void*, int, MPI_Datatype, void*, int*, int*, MPI_Datatype, MPI_Comm);
int MPI_Op_create(MPI_User_function*, int, MPI_Op*);
int MPI_Op_free(MPI_Op*);
int MPI_Allreduce(void*, void*, int, MPI_Datatype, MPI_Op, MPI_Comm);
int MPI_Comm_group(MPI_Comm, MPI_Group*);
int MPI_Group_incl(MPI_Group, int, int*, MPI_Group*);
int MPI_Group_free(MPI_Group*);
int MPI_Comm_size(MPI_Comm, int*);
int MPI_Comm_rank(MPI_Comm, int*);
int MPI_Comm_create(MPI_Comm, MPI_Group, MPI_Comm*);
int MPI_Init(int*, char***);
int MPI_Finalize(void);
//======================= utilities.h ======================
int hypre_OutOfMemory(int size);
char* hypre_MAlloc(int size);
char* hypre_CAlloc(int count, int elt_size);
char* hypre_ReAlloc(char* ptr, int size);
void hypre_Free(char* ptr);
void hypre_SeedRand(int seed);
double hypre_Rand(void);
//======================== string.h ========================
void* memcpy(void* p, void* q, size_t size);
char* strncpy(char* dest, char* src, size_t n);
$system[string] int strcmp(char* s1, char* s2);
size_t strcspn(char* s, char* reject);
size_t strspn(char* s, char* accept);
$system[string] size_t strlen(char* s);
//======================= utilities.h ======================
double time_getWallclockSeconds(void);
double time_getCPUSeconds(void);
typedef struct $anon_struct_5$TU0{
  double* wall_time;
  double* cpu_time;
  double* flops;
  char** name;
  int* state;
  int* num_regs;
  int num_names;
  int size;
  double wall_count;
  double CPU_count;
  double FLOP_count;
} hypre_TimingType;
extern hypre_TimingType* hypre_global_timing;
int hypre_InitializeTiming(char* name);
int hypre_FinalizeTiming(int time_index);
int hypre_BeginTiming(int time_index);
int hypre_EndTiming(int time_index);
int hypre_ClearTiming(void);
int hypre_PrintTiming(char* heading, double* wall_time_ptr, MPI_Comm comm);
struct double_linked_list{
  int data;
  struct double_linked_list* next_elt;
  struct double_linked_list* prev_elt;
  int head;
  int tail;
};
typedef struct double_linked_list hypre_ListElement;
typedef hypre_ListElement* hypre_LinkList;
void dispose_elt(hypre_LinkList element_ptr);
void remove_point(hypre_LinkList* LoL_head_ptr, hypre_LinkList* LoL_tail_ptr, int measure, int index, int* lists, int* where);
hypre_LinkList create_elt(int Item);
void enter_on_lists(hypre_LinkList* LoL_head_ptr, hypre_LinkList* LoL_tail_ptr, int measure, int index, int* lists, int* where);
int hypre_BinarySearch(int* list, int value, int list_length);
int hypre_BigBinarySearch(int* list, int value, int list_length);
void swap(int* v, int i, int j);
void swap2(int* v, double* w, int i, int j);
void qsort0(int* v, int left, int right);
void hypre_BigSwapbi(int* v, int* w, int i, int j);
void hypre_BigQsortbi(int* v, int* w, int left, int right);
void hypre_BigSwap(int* v, int i, int j);
void hypre_BigQsort0(int* v, int left, int right);
extern int hypre__global_error;
void hypre_error_handler(char* filename, int line, int ierr);
//===================== HYPRE_seq_mv.h =====================
struct hypre_Vector_struct;
typedef struct hypre_Vector_struct* HYPRE_Vector;
//==================== HYPRE_parcsr_mv.h ===================
struct hypre_ParCSRMatrix_struct;
typedef struct hypre_ParCSRMatrix_struct* HYPRE_ParCSRMatrix;
struct hypre_ParVector_struct;
typedef struct hypre_ParVector_struct* HYPRE_ParVector;
int HYPRE_ParCSRMatrixDestroy(HYPRE_ParCSRMatrix matrix);
int HYPRE_ParCSRMatrixPrintIJ(HYPRE_ParCSRMatrix matrix, int base_i, int bse_j, char* file_name);
int HYPRE_ParCSRMatrixGetRow(HYPRE_ParCSRMatrix matrix, int row, int* size, int** col_ind, double** values);
int HYPRE_ParCSRMatrixRestoreRow(HYPRE_ParCSRMatrix matrix, int row, int* size, int** col_ind, double** values);
int HYPRE_ParCSRMatrixMatvec(double alpha, HYPRE_ParCSRMatrix A, HYPRE_ParVector x, double beta, HYPRE_ParVector y);
int HYPRE_ParVectorDestroy(HYPRE_ParVector vector);
int HYPRE_ParVectorPrintIJ(HYPRE_ParVector vector, int base_i, char* file_name);
//==================== HYPRE_struct_mv.h ===================
struct hypre_StructGrid_struct;
typedef struct hypre_StructGrid_struct* HYPRE_StructGrid;
int HYPRE_StructGridCreate(MPI_Comm comm, int ndim, HYPRE_StructGrid* grid);
int HYPRE_StructGridDestroy(HYPRE_StructGrid grid);
int HYPRE_StructGridSetExtents(HYPRE_StructGrid grid, int* ilower, int* iupper);
int HYPRE_StructGridAssemble(HYPRE_StructGrid grid);
int HYPRE_StructGridSetPeriodic(HYPRE_StructGrid grid, int* periodic);
struct hypre_StructStencil_struct;
typedef struct hypre_StructStencil_struct* HYPRE_StructStencil;
int HYPRE_StructStencilCreate(int ndim, int size, HYPRE_StructStencil* stencil);
int HYPRE_StructStencilDestroy(HYPRE_StructStencil stencil);
int HYPRE_StructStencilSetElement(HYPRE_StructStencil stencil, int entry, int* offset);
struct hypre_StructMatrix_struct;
typedef struct hypre_StructMatrix_struct* HYPRE_StructMatrix;
int HYPRE_StructMatrixSetSymmetric(HYPRE_StructMatrix matrix, int symmetric);
struct hypre_StructVector_struct;
struct hypre_CommPkg_struct;
//====================== HYPRE_IJ_mv.h =====================
struct hypre_IJMatrix_struct;
typedef struct hypre_IJMatrix_struct* HYPRE_IJMatrix;
int HYPRE_IJMatrixCreate(MPI_Comm comm, int ilower, int iupper, int jlower, int jupper, HYPRE_IJMatrix* matrix);
int HYPRE_IJMatrixDestroy(HYPRE_IJMatrix matrix);
int HYPRE_IJMatrixInitialize(HYPRE_IJMatrix matrix);
int HYPRE_IJMatrixSetValues(HYPRE_IJMatrix matrix, int nrows, int* ncols, int* rows, int* cols, double* values);
int HYPRE_IJMatrixAddToValues(HYPRE_IJMatrix matrix, int nrows, int* ncols, int* rows, int* cols, double* values);
int HYPRE_IJMatrixAssemble(HYPRE_IJMatrix matrix);
int HYPRE_IJMatrixGetValues(HYPRE_IJMatrix matrix, int nrows, int* ncols, int* rows, int* cols, double* values);
int HYPRE_IJMatrixSetObjectType(HYPRE_IJMatrix matrix, int type);
int HYPRE_IJMatrixGetObject(HYPRE_IJMatrix matrix, void** object);
int HYPRE_IJMatrixSetRowSizes(HYPRE_IJMatrix matrix, int* sizes);
int HYPRE_IJMatrixPrint(HYPRE_IJMatrix matrix, char* filename);
struct hypre_IJVector_struct;
typedef struct hypre_IJVector_struct* HYPRE_IJVector;
int HYPRE_IJVectorCreate(MPI_Comm comm, int jlower, int jupper, HYPRE_IJVector* vector);
int HYPRE_IJVectorDestroy(HYPRE_IJVector vector);
int HYPRE_IJVectorInitialize(HYPRE_IJVector vector);
int HYPRE_IJVectorAssemble(HYPRE_IJVector vector);
int HYPRE_IJVectorSetObjectType(HYPRE_IJVector vector, int type);
int HYPRE_IJVectorGetObject(HYPRE_IJVector vector, void** object);
//=================== HYPRE_sstruct_mv.h ===================
struct hypre_SStructGrid_struct;
typedef struct hypre_SStructGrid_struct* HYPRE_SStructGrid;
enum hypre_SStructVariable_enum{
  HYPRE_SSTRUCT_VARIABLE_UNDEFINED=-1,
  HYPRE_SSTRUCT_VARIABLE_CELL=0,
  HYPRE_SSTRUCT_VARIABLE_NODE=1,
  HYPRE_SSTRUCT_VARIABLE_XFACE=2,
  HYPRE_SSTRUCT_VARIABLE_YFACE=3,
  HYPRE_SSTRUCT_VARIABLE_ZFACE=4,
  HYPRE_SSTRUCT_VARIABLE_XEDGE=5,
  HYPRE_SSTRUCT_VARIABLE_YEDGE=6,
  HYPRE_SSTRUCT_VARIABLE_ZEDGE=7
};
typedef enum hypre_SStructVariable_enum HYPRE_SStructVariable;
int HYPRE_SStructGridCreate(MPI_Comm comm, int ndim, int nparts, HYPRE_SStructGrid* grid);
int HYPRE_SStructGridDestroy(HYPRE_SStructGrid grid);
int HYPRE_SStructGridSetExtents(HYPRE_SStructGrid grid, int part, int* ilower, int* iupper);
int HYPRE_SStructGridSetVariables(HYPRE_SStructGrid grid, int part, int nvars, HYPRE_SStructVariable* vartypes);
int HYPRE_SStructGridSetNeighborBox(HYPRE_SStructGrid grid, int part, int* ilower, int* iupper, int nbor_part, int* nbor_ilower, int* nbor_iupper, int* index_map);
int HYPRE_SStructGridAssemble(HYPRE_SStructGrid grid);
int HYPRE_SStructGridSetPeriodic(HYPRE_SStructGrid grid, int part, int* periodic);
struct hypre_SStructStencil_struct;
typedef struct hypre_SStructStencil_struct* HYPRE_SStructStencil;
int HYPRE_SStructStencilCreate(int ndim, int size, HYPRE_SStructStencil* stencil);
int HYPRE_SStructStencilDestroy(HYPRE_SStructStencil stencil);
int HYPRE_SStructStencilSetEntry(HYPRE_SStructStencil stencil, int entry, int* offset, int var);
struct hypre_SStructGraph_struct;
typedef struct hypre_SStructGraph_struct* HYPRE_SStructGraph;
int HYPRE_SStructGraphCreate(MPI_Comm comm, HYPRE_SStructGrid grid, HYPRE_SStructGraph* graph);
int HYPRE_SStructGraphDestroy(HYPRE_SStructGraph graph);
int HYPRE_SStructGraphSetStencil(HYPRE_SStructGraph graph, int part, int var, HYPRE_SStructStencil stencil);
int HYPRE_SStructGraphAddEntries(HYPRE_SStructGraph graph, int part, int* index, int var, int to_part, int* to_index, int to_var);
int HYPRE_SStructGraphSetObjectType(HYPRE_SStructGraph graph, int type);
int HYPRE_SStructGraphAssemble(HYPRE_SStructGraph graph);
struct hypre_SStructMatrix_struct;
typedef struct hypre_SStructMatrix_struct* HYPRE_SStructMatrix;
int HYPRE_SStructMatrixCreate(MPI_Comm comm, HYPRE_SStructGraph graph, HYPRE_SStructMatrix* matrix);
int HYPRE_SStructMatrixDestroy(HYPRE_SStructMatrix matrix);
int HYPRE_SStructMatrixInitialize(HYPRE_SStructMatrix matrix);
int HYPRE_SStructMatrixSetValues(HYPRE_SStructMatrix matrix, int part, int* index, int var, int nentries, int* entries, double* values);
int HYPRE_SStructMatrixSetBoxValues(HYPRE_SStructMatrix matrix, int part, int* ilower, int* iupper, int var, int nentries, int* entries, double* values);
int HYPRE_SStructMatrixAddToBoxValues(HYPRE_SStructMatrix matrix, int part, int* ilower, int* iupper, int var, int nentries, int* entries, double* values);
int HYPRE_SStructMatrixAssemble(HYPRE_SStructMatrix matrix);
int HYPRE_SStructMatrixSetSymmetric(HYPRE_SStructMatrix matrix, int part, int var, int to_var, int symmetric);
int HYPRE_SStructMatrixSetNSSymmetric(HYPRE_SStructMatrix matrix, int symmetric);
int HYPRE_SStructMatrixSetObjectType(HYPRE_SStructMatrix matrix, int type);
int HYPRE_SStructMatrixGetObject(HYPRE_SStructMatrix matrix, void** object);
int HYPRE_SStructMatrixPrint(char* filename, HYPRE_SStructMatrix matrix, int all);
struct hypre_SStructVector_struct;
typedef struct hypre_SStructVector_struct* HYPRE_SStructVector;
int HYPRE_SStructVectorCreate(MPI_Comm comm, HYPRE_SStructGrid grid, HYPRE_SStructVector* vector);
int HYPRE_SStructVectorDestroy(HYPRE_SStructVector vector);
int HYPRE_SStructVectorInitialize(HYPRE_SStructVector vector);
int HYPRE_SStructVectorSetBoxValues(HYPRE_SStructVector vector, int part, int* ilower, int* iupper, int var, double* values);
int HYPRE_SStructVectorAssemble(HYPRE_SStructVector vector);
int HYPRE_SStructVectorGather(HYPRE_SStructVector vector);
int HYPRE_SStructVectorSetObjectType(HYPRE_SStructVector vector, int type);
int HYPRE_SStructVectorGetObject(HYPRE_SStructVector vector, void** object);
int HYPRE_SStructVectorPrint(char* filename, HYPRE_SStructVector vector, int all);
//==================== HYPRE_parcsr_ls.h ===================
struct hypre_Solver_struct;
typedef struct hypre_Solver_struct* HYPRE_Solver;
int HYPRE_BoomerAMGCreate(HYPRE_Solver* solver);
int HYPRE_BoomerAMGDestroy(HYPRE_Solver solver);
int HYPRE_BoomerAMGSetup(HYPRE_Solver solver, HYPRE_ParCSRMatrix A, HYPRE_ParVector b, HYPRE_ParVector x);
int HYPRE_BoomerAMGSolve(HYPRE_Solver solver, HYPRE_ParCSRMatrix A, HYPRE_ParVector b, HYPRE_ParVector x);
int HYPRE_BoomerAMGSetTol(HYPRE_Solver solver, double tol);
int HYPRE_BoomerAMGSetMaxIter(HYPRE_Solver solver, int max_iter);
int HYPRE_BoomerAMGSetStrongThreshold(HYPRE_Solver solver, double strong_threshold);
int HYPRE_BoomerAMGSetMaxRowSum(HYPRE_Solver solver, double max_row_sum);
int HYPRE_BoomerAMGSetCoarsenType(HYPRE_Solver solver, int coarsen_type);
int HYPRE_BoomerAMGSetNumGridSweeps(HYPRE_Solver solver, int* num_grid_sweeps);
int HYPRE_BoomerAMGSetCycleNumSweeps(HYPRE_Solver solver, int num_sweeps, int k);
int HYPRE_BoomerAMGSetGridRelaxType(HYPRE_Solver solver, int* grid_relax_type);
int HYPRE_BoomerAMGSetRelaxType(HYPRE_Solver solver, int relax_type);
int HYPRE_BoomerAMGSetCycleRelaxType(HYPRE_Solver solver, int relax_type, int k);
int HYPRE_BoomerAMGSetRelaxOrder(HYPRE_Solver solver, int relax_order);
int HYPRE_BoomerAMGSetGridRelaxPoints(HYPRE_Solver solver, int** grid_relax_points);
int HYPRE_BoomerAMGSetRelaxWeight(HYPRE_Solver solver, double* relax_weight);
int HYPRE_BoomerAMGSetTruncFactor(HYPRE_Solver solver, double trunc_factor);
int HYPRE_BoomerAMGSetPMaxElmts(HYPRE_Solver solver, int P_max_elmts);
int HYPRE_BoomerAMGSetInterpType(HYPRE_Solver solver, int interp_type);
int HYPRE_BoomerAMGSetPrintFileName(HYPRE_Solver solver, char* print_file_name);
int HYPRE_BoomerAMGSetPrintLevel(HYPRE_Solver solver, int print_level);
int HYPRE_BoomerAMGSetNumFunctions(HYPRE_Solver solver, int num_functions);
int HYPRE_BoomerAMGSetAggNumLevels(HYPRE_Solver solver, int agg_num_levels);
int HYPRE_ParCSRPCGCreate(MPI_Comm comm, HYPRE_Solver* solver);
int HYPRE_ParCSRPCGDestroy(HYPRE_Solver solver);
int HYPRE_ParCSRPCGSetup(HYPRE_Solver solver, HYPRE_ParCSRMatrix A, HYPRE_ParVector b, HYPRE_ParVector x);
int HYPRE_ParCSRPCGSolve(HYPRE_Solver solver, HYPRE_ParCSRMatrix A, HYPRE_ParVector b, HYPRE_ParVector x);
int HYPRE_ParCSRDiagScaleSetup(HYPRE_Solver solver, HYPRE_ParCSRMatrix A, HYPRE_ParVector y, HYPRE_ParVector x);
int HYPRE_ParCSRDiagScale(HYPRE_Solver solver, HYPRE_ParCSRMatrix HA, HYPRE_ParVector Hy, HYPRE_ParVector Hx);
int HYPRE_ParCSRGMRESCreate(MPI_Comm comm, HYPRE_Solver* solver);
int HYPRE_ParCSRGMRESDestroy(HYPRE_Solver solver);
HYPRE_ParCSRMatrix GenerateLaplacian(MPI_Comm comm, int nx, int ny, int nz, int P, int Q, int R, int p, int q, int r, double* value, HYPRE_ParVector* rhs_ptr, HYPRE_ParVector* x_ptr);
HYPRE_ParCSRMatrix GenerateLaplacian27pt(MPI_Comm comm, int nx, int ny, int nz, int P, int Q, int R, int p, int q, int r, double* value, HYPRE_ParVector* rhs_ptr, HYPRE_ParVector* x_ptr);
HYPRE_ParCSRMatrix GenerateVarDifConv(MPI_Comm comm, int nx, int ny, int nz, int P, int Q, int R, int p, int q, int r, double eps, HYPRE_ParVector* rhs_ptr, HYPRE_ParVector* x_ptr);
//======================== krylov.h ========================
struct hypre_Matrix_struct;
typedef struct hypre_Matrix_struct* HYPRE_Matrix;
typedef  (int (HYPRE_Solver, HYPRE_Matrix, HYPRE_Vector, HYPRE_Vector))* HYPRE_PtrToSolverFcn;
typedef struct $anon_struct_8$TU0{
   (char* (int count, int elt_size))* CAlloc;
   (int (char* ptr))* Free;
   (int (void* A, int* my_id, int* num_procs))* CommInfo;
   (void* (void* vector))* CreateVector;
   (void* (int size, void* vectors))* CreateVectorArray;
   (int (void* vector))* DestroyVector;
   (void* (void* A, void* x))* MatvecCreate;
   (int (void* matvec_data, double alpha, void* A, void* x, double beta, void* y))* Matvec;
   (int (void* matvec_data))* MatvecDestroy;
   (double (void* x, void* y))* InnerProd;
   (int (void* x, void* y))* CopyVector;
   (int (void* x))* ClearVector;
   (int (double alpha, void* x))* ScaleVector;
   (int (double alpha, void* x, void* y))* Axpy;
   (int ())* precond;
   (int ())* precond_setup;
} hypre_GMRESFunctions;
typedef struct $anon_struct_9$TU0{
  int k_dim;
  int min_iter;
  int max_iter;
  int rel_change;
  int stop_crit;
  int converged;
  double tol;
  double cf_tol;
  double rel_residual_norm;
  void* A;
  void* r;
  void* w;
  void** p;
  void* matvec_data;
  void* precond_data;
  hypre_GMRESFunctions* functions;
  int num_iterations;
  int print_level;
  int logging;
  double* norms;
  char* log_file_name;
} hypre_GMRESData;
hypre_GMRESFunctions* hypre_GMRESFunctionsCreate( (char* (int count, int elt_size))* CAlloc,  (int (char* ptr))* Free,  (int (void* A, int* my_id, int* num_procs))* CommInfo,  (void* (void* vector))* CreateVector,  (void* (int size, void* vectors))* CreateVectorArray,  (int (void* vector))* DestroyVector,  (void* (void* A, void* x))* MatvecCreate,  (int (void* matvec_data, double alpha, void* A, void* x, double beta, void* y))* Matvec,  (int (void* matvec_data))* MatvecDestroy,  (double (void* x, void* y))* InnerProd,  (int (void* x, void* y))* CopyVector,  (int (void* x))* ClearVector,  (int (double alpha, void* x))* ScaleVector,  (int (double alpha, void* x, void* y))* Axpy,  (int (void* vdata, void* A, void* b, void* x))* PrecondSetup,  (int (void* vdata, void* A, void* b, void* x))* Precond);
void* hypre_GMRESCreate(hypre_GMRESFunctions* gmres_functions);
typedef struct $anon_struct_10$TU0{
   (char* (int count, int elt_size))* CAlloc;
   (int (char* ptr))* Free;
   (int (void* A, int* my_id, int* num_procs))* CommInfo;
   (void* (void* vector))* CreateVector;
   (int (void* vector))* DestroyVector;
   (void* (void* A, void* x))* MatvecCreate;
   (int (void* matvec_data, double alpha, void* A, void* x, double beta, void* y))* Matvec;
   (int (void* matvec_data))* MatvecDestroy;
   (double (void* x, void* y))* InnerProd;
   (int (void* x, void* y))* CopyVector;
   (int (void* x))* ClearVector;
   (int (double alpha, void* x))* ScaleVector;
   (int (double alpha, void* x, void* y))* Axpy;
   (int ())* precond;
   (int ())* precond_setup;
} hypre_PCGFunctions;
typedef struct $anon_struct_11$TU0{
  double tol;
  double atolf;
  double cf_tol;
  int max_iter;
  int two_norm;
  int rel_change;
  int stop_crit;
  int converged;
  void* A;
  void* p;
  void* s;
  void* r;
  int owns_matvec_data;
  void* matvec_data;
  void* precond_data;
  hypre_PCGFunctions* functions;
  int num_iterations;
  double rel_residual_norm;
  int print_level;
  int logging;
  double* norms;
  double* rel_norms;
} hypre_PCGData;
hypre_PCGFunctions* hypre_PCGFunctionsCreate( (char* (int count, int elt_size))* CAlloc,  (int (char* ptr))* Free,  (int (void* A, int* my_id, int* num_procs))* CommInfo,  (void* (void* vector))* CreateVector,  (int (void* vector))* DestroyVector,  (void* (void* A, void* x))* MatvecCreate,  (int (void* matvec_data, double alpha, void* A, void* x, double beta, void* y))* Matvec,  (int (void* matvec_data))* MatvecDestroy,  (double (void* x, void* y))* InnerProd,  (int (void* x, void* y))* CopyVector,  (int (void* x))* ClearVector,  (int (double alpha, void* x))* ScaleVector,  (int (double alpha, void* x, void* y))* Axpy,  (int (void* vdata, void* A, void* b, void* x))* PrecondSetup,  (int (void* vdata, void* A, void* b, void* x))* Precond);
void* hypre_PCGCreate(hypre_PCGFunctions* pcg_functions);
int hypre_GMRESDestroy(void* gmres_vdata);
int hypre_GMRESSetup(void* gmres_vdata, void* A, void* b, void* x);
int hypre_GMRESSolve(void* gmres_vdata, void* A, void* b, void* x);
int hypre_GMRESSetKDim(void* gmres_vdata, int k_dim);
int hypre_GMRESSetTol(void* gmres_vdata, double tol);
int hypre_GMRESSetMaxIter(void* gmres_vdata, int max_iter);
int hypre_GMRESSetPrecond(void* gmres_vdata,  (int ())* precond,  (int ())* precond_setup, void* precond_data);
int hypre_GMRESSetPrintLevel(void* gmres_vdata, int level);
int hypre_GMRESSetLogging(void* gmres_vdata, int level);
int hypre_GMRESGetNumIterations(void* gmres_vdata, int* num_iterations);
int hypre_GMRESGetFinalRelativeResidualNorm(void* gmres_vdata, double* relative_residual_norm);
int HYPRE_GMRESSetup(HYPRE_Solver solver, HYPRE_Matrix A, HYPRE_Vector b, HYPRE_Vector x);
int HYPRE_GMRESSolve(HYPRE_Solver solver, HYPRE_Matrix A, HYPRE_Vector b, HYPRE_Vector x);
int HYPRE_GMRESSetKDim(HYPRE_Solver solver, int k_dim);
int HYPRE_GMRESSetTol(HYPRE_Solver solver, double tol);
int HYPRE_GMRESSetMaxIter(HYPRE_Solver solver, int max_iter);
int HYPRE_GMRESSetPrecond(HYPRE_Solver solver, HYPRE_PtrToSolverFcn precond, HYPRE_PtrToSolverFcn precond_setup, HYPRE_Solver precond_solver);
int HYPRE_GMRESSetPrintLevel(HYPRE_Solver solver, int level);
int HYPRE_GMRESSetLogging(HYPRE_Solver solver, int level);
int HYPRE_GMRESGetNumIterations(HYPRE_Solver solver, int* num_iterations);
int HYPRE_GMRESGetFinalRelativeResidualNorm(HYPRE_Solver solver, double* norm);
int HYPRE_PCGSetup(HYPRE_Solver solver, HYPRE_Matrix A, HYPRE_Vector b, HYPRE_Vector x);
int HYPRE_PCGSolve(HYPRE_Solver solver, HYPRE_Matrix A, HYPRE_Vector b, HYPRE_Vector x);
int HYPRE_PCGSetTol(HYPRE_Solver solver, double tol);
int HYPRE_PCGSetMaxIter(HYPRE_Solver solver, int max_iter);
int HYPRE_PCGSetTwoNorm(HYPRE_Solver solver, int two_norm);
int HYPRE_PCGSetRelChange(HYPRE_Solver solver, int rel_change);
int HYPRE_PCGSetPrecond(HYPRE_Solver solver, HYPRE_PtrToSolverFcn precond, HYPRE_PtrToSolverFcn precond_setup, HYPRE_Solver precond_solver);
int HYPRE_PCGSetPrintLevel(HYPRE_Solver solver, int level);
int HYPRE_PCGGetNumIterations(HYPRE_Solver solver, int* num_iterations);
int HYPRE_PCGGetFinalRelativeResidualNorm(HYPRE_Solver solver, double* norm);
int hypre_PCGDestroy(void* pcg_vdata);
int hypre_PCGSetup(void* pcg_vdata, void* A, void* b, void* x);
int hypre_PCGSolve(void* pcg_vdata, void* A, void* b, void* x);
int hypre_PCGSetTol(void* pcg_vdata, double tol);
int hypre_PCGSetMaxIter(void* pcg_vdata, int max_iter);
int hypre_PCGSetTwoNorm(void* pcg_vdata, int two_norm);
int hypre_PCGSetRelChange(void* pcg_vdata, int rel_change);
int hypre_PCGSetPrecond(void* pcg_vdata,  (int ())* precond,  (int ())* precond_setup, void* precond_data);
int hypre_PCGSetPrintLevel(void* pcg_vdata, int level);
int hypre_PCGGetNumIterations(void* pcg_vdata, int* num_iterations);
int hypre_PCGGetFinalRelativeResidualNorm(void* pcg_vdata, double* relative_residual_norm);
//======================= struct_mv.h ======================
typedef int[3] hypre_Index;
typedef int* hypre_IndexRef;
typedef struct hypre_Box_struct{
  hypre_Index imin;
  hypre_Index imax;
} hypre_Box;
typedef struct hypre_BoxArray_struct{
  hypre_Box* boxes;
  int size;
  int alloc_size;
} hypre_BoxArray;
typedef struct hypre_BoxArrayArray_struct{
  hypre_BoxArray** box_arrays;
  int size;
} hypre_BoxArrayArray;
typedef struct hypre_RankLink_struct{
  int rank;
  int prank;
  struct hypre_RankLink_struct* next;
} hypre_RankLink;
typedef struct hypre_BoxNeighbors_struct{
  hypre_BoxArray* boxes;
  int* procs;
  int* boxnums;
  int* ids;
  int first_local;
  int num_local;
  hypre_Index periodic;
  int id_period;
  int num_periods;
  hypre_Index* pshifts;
  hypre_RankLink** rank_links;
} hypre_BoxNeighbors;
typedef struct hypre_StructGrid_struct{
  MPI_Comm comm;
  int dim;
  hypre_BoxArray* boxes;
  int* ids;
  hypre_BoxNeighbors* neighbors;
  int max_distance;
  hypre_Box* bounding_box;
  int local_size;
  int global_size;
  hypre_Index periodic;
  int ref_count;
  int ghlocal_size;
  int  num_ghost[6];
} hypre_StructGrid;
typedef struct hypre_StructStencil_struct{
  hypre_Index* shape;
  int size;
  int max_offset;
  int dim;
  int ref_count;
} hypre_StructStencil;
typedef struct hypre_CommInfo_struct{
  hypre_BoxArrayArray* send_boxes;
  hypre_BoxArrayArray* recv_boxes;
  hypre_Index send_stride;
  hypre_Index recv_stride;
  int** send_processes;
  int** recv_processes;
  int** send_rboxnums;
  int** recv_rboxnums;
  hypre_BoxArrayArray* send_rboxes;
} hypre_CommInfo;
typedef struct hypre_CommEntryType_struct{
  int offset;
  int dim;
  int  length_array[4];
  int  stride_array[4];
} hypre_CommEntryType;
typedef struct hypre_CommType_struct{
  int proc;
  int bufsize;
  int num_entries;
  hypre_CommEntryType* entries;
  int* loc_boxnums;
  int* rem_boxnums;
  hypre_Box* loc_boxes;
  hypre_Box* rem_boxes;
} hypre_CommType;
typedef struct hypre_CommPkg_struct{
  MPI_Comm comm;
  int first_send;
  int first_recv;
  int num_values;
  hypre_Index send_stride;
  hypre_Index recv_stride;
  int send_bufsize;
  int recv_bufsize;
  int num_sends;
  int num_recvs;
  hypre_CommType* send_types;
  hypre_CommType* recv_types;
  hypre_CommType* copy_from_type;
  hypre_CommType* copy_to_type;
  int* recv_data_offsets;
  hypre_BoxArray* recv_data_space;
} hypre_CommPkg;
typedef struct hypre_CommHandle_struct{
  hypre_CommPkg* comm_pkg;
  double* send_data;
  double* recv_data;
  int num_requests;
  MPI_Request* requests;
  MPI_Status* status;
  double** send_buffers;
  double** recv_buffers;
} hypre_CommHandle;
typedef struct hypre_ComputeInfo_struct{
  hypre_CommInfo* comm_info;
  hypre_BoxArrayArray* indt_boxes;
  hypre_BoxArrayArray* dept_boxes;
  hypre_Index stride;
} hypre_ComputeInfo;
typedef struct hypre_ComputePkg_struct{
  hypre_CommPkg* comm_pkg;
  hypre_BoxArrayArray* indt_boxes;
  hypre_BoxArrayArray* dept_boxes;
  hypre_Index stride;
  hypre_StructGrid* grid;
  hypre_BoxArray* data_space;
  int num_values;
} hypre_ComputePkg;
typedef struct hypre_StructMatrix_struct{
  MPI_Comm comm;
  hypre_StructGrid* grid;
  hypre_StructStencil* user_stencil;
  hypre_StructStencil* stencil;
  int num_values;
  hypre_BoxArray* data_space;
  double* data;
  int data_alloced;
  int data_size;
  int** data_indices;
  int constant_coefficient;
  int symmetric;
  int* symm_elements;
  int  num_ghost[6];
  int global_size;
  int OffProcAdd;
  int  add_num_ghost[6];
  hypre_CommPkg* comm_pkg;
  int ref_count;
} hypre_StructMatrix;
typedef struct hypre_StructVector_struct{
  MPI_Comm comm;
  hypre_StructGrid* grid;
  hypre_BoxArray* data_space;
  double* data;
  int data_alloced;
  int data_size;
  int* data_indices;
  int  num_ghost[6];
  int global_size;
  int OffProcAdd;
  int  add_num_ghost[6];
  int ref_count;
} hypre_StructVector;
int hypre_IntersectBoxes(hypre_Box* box1, hypre_Box* box2, hypre_Box* ibox);
int hypre_SubtractBoxes(hypre_Box* box1, hypre_Box* box2, hypre_BoxArray* box_array);
int hypre_SubtractBoxArrays(hypre_BoxArray* box_array1, hypre_BoxArray* box_array2, hypre_BoxArray* tmp_box_array);
int hypre_SubtractBoxArraysExceptBoxes(hypre_BoxArray* box_array1, hypre_BoxArray* box_array2, hypre_BoxArray* tmp_box_array, hypre_Box* boxa, hypre_Box* boxb);
int hypre_BoxArraySubtractAdjacentBoxArrayD(hypre_BoxArray* boxes1, hypre_BoxArray* boxes2, hypre_Box* box, int ds, int thick);
int hypre_BoxBoundaryDNT(hypre_Box* box, hypre_BoxArray* neighbor_boxes, hypre_BoxArray* boundary, int ds, int thick);
int hypre_BoxBoundaryNT(hypre_Box* box, hypre_BoxArray* neighbor_boxes, hypre_BoxArray* boundary, int* thickness);
int hypre_BoxBoundaryG(hypre_Box* box, hypre_StructGrid* g, hypre_BoxArray* boundary);
hypre_Box* hypre_BoxCreate(void);
int hypre_BoxSetExtents(hypre_Box* box, hypre_Index imin, hypre_Index imax);
hypre_BoxArray* hypre_BoxArrayCreate(int size);
int hypre_BoxArraySetSize(hypre_BoxArray* box_array, int size);
hypre_BoxArrayArray* hypre_BoxArrayArrayCreate(int size);
int hypre_BoxDestroy(hypre_Box* box);
int hypre_BoxArrayDestroy(hypre_BoxArray* box_array);
int hypre_BoxArrayArrayDestroy(hypre_BoxArrayArray* box_array_array);
hypre_Box* hypre_BoxDuplicate(hypre_Box* box);
hypre_BoxArray* hypre_BoxArrayDuplicate(hypre_BoxArray* box_array);
hypre_BoxArrayArray* hypre_BoxArrayArrayDuplicate(hypre_BoxArrayArray* box_array_array);
int hypre_AppendBox(hypre_Box* box, hypre_BoxArray* box_array);
int hypre_AppendBoxArray(hypre_BoxArray* box_array_0, hypre_BoxArray* box_array_1);
int hypre_BoxGetSize(hypre_Box* box, hypre_Index size);
int hypre_BoxGetStrideSize(hypre_Box* box, hypre_Index stride, hypre_Index size);
int hypre_BoxGetStrideVolume(hypre_Box* box, hypre_Index stride, int* volume_ptr);
int hypre_BoxExpand(hypre_Box* box, int* numexp);
int hypre_RankLinkCreate(int rank, int prank, hypre_RankLink** rank_link_ptr);
int hypre_RankLinkDestroy(hypre_RankLink* rank_link);
int hypre_BoxNeighborsCreate(hypre_BoxArray* boxes, int* procs, int* ids, int first_local, int num_local, hypre_BoxNeighbors** neighbors_ptr);
int hypre_BoxNeighborsAssemble(hypre_BoxNeighbors* neighbors, hypre_Index periodic, int max_distance, int prune);
int hypre_BoxNeighborsDestroy(hypre_BoxNeighbors* neighbors);
int hypre_CommInfoCreate(hypre_BoxArrayArray* send_boxes, hypre_BoxArrayArray* recv_boxes, int** send_procs, int** recv_procs, int** send_rboxnums, int** recv_rboxnums, hypre_BoxArrayArray* send_rboxes, hypre_CommInfo** comm_info_ptr);
int hypre_CommInfoDestroy(hypre_CommInfo* comm_info);
int hypre_CreateCommInfoFromStencil(hypre_StructGrid* grid, hypre_StructStencil* stencil, hypre_CommInfo** comm_info_ptr);
int hypre_CreateCommInfoFromNumGhost(hypre_StructGrid* grid, int* num_ghost, hypre_CommInfo** comm_info_ptr);
int hypre_ComputeInfoCreate(hypre_CommInfo* comm_info, hypre_BoxArrayArray* indt_boxes, hypre_BoxArrayArray* dept_boxes, hypre_ComputeInfo** compute_info_ptr);
int hypre_ComputeInfoDestroy(hypre_ComputeInfo* compute_info);
int hypre_CreateComputeInfo(hypre_StructGrid* grid, hypre_StructStencil* stencil, hypre_ComputeInfo** compute_info_ptr);
int hypre_ComputePkgCreate(hypre_ComputeInfo* compute_info, hypre_BoxArray* data_space, int num_values, hypre_StructGrid* grid, hypre_ComputePkg** compute_pkg_ptr);
int hypre_ComputePkgDestroy(hypre_ComputePkg* compute_pkg);
int hypre_InitializeIndtComputations(hypre_ComputePkg* compute_pkg, double* data, hypre_CommHandle** comm_handle_ptr);
int hypre_FinalizeIndtComputations(hypre_CommHandle* comm_handle);
int HYPRE_StructGridCreate(MPI_Comm comm, int dim, HYPRE_StructGrid* grid);
int HYPRE_StructStencilCreate(int dim, int size, HYPRE_StructStencil* stencil);
int HYPRE_StructStencilSetElement(HYPRE_StructStencil stencil, int element_index, int* offset);
int hypre_CommPkgCreate(hypre_CommInfo* comm_info, hypre_BoxArray* send_data_space, hypre_BoxArray* recv_data_space, int num_values, MPI_Comm comm, hypre_CommPkg** comm_pkg_ptr);
int hypre_CommTypeSetEntries(hypre_CommType* comm_type, int* boxnums, hypre_Box* boxes, hypre_Index stride, int num_values, hypre_BoxArray* data_space, int* data_offsets);
int hypre_CommTypeSetEntry(hypre_Box* box, hypre_Index stride, hypre_Box* data_box, int num_values, int data_box_offset, hypre_CommEntryType* comm_entry);
int hypre_InitializeCommunication(hypre_CommPkg* comm_pkg, double* send_data, double* recv_data, hypre_CommHandle** comm_handle_ptr);
int hypre_FinalizeCommunication(hypre_CommHandle* comm_handle);
int hypre_ExchangeLocalData(hypre_CommPkg* comm_pkg, double* send_data, double* recv_data);
int hypre_CommPkgDestroy(hypre_CommPkg* comm_pkg);
int hypre_StructGridCreate(MPI_Comm comm, int dim, hypre_StructGrid** grid_ptr);
int hypre_StructGridRef(hypre_StructGrid* grid, hypre_StructGrid** grid_ref);
int hypre_StructGridDestroy(hypre_StructGrid* grid);
int hypre_StructGridSetPeriodic(hypre_StructGrid* grid, hypre_Index periodic);
int hypre_StructGridSetExtents(hypre_StructGrid* grid, hypre_Index ilower, hypre_Index iupper);
int hypre_StructGridSetBoxes(hypre_StructGrid* grid, hypre_BoxArray* boxes);
int hypre_StructGridAssemble(hypre_StructGrid* grid);
int hypre_GatherAllBoxes(MPI_Comm comm, hypre_BoxArray* boxes, hypre_BoxArray** all_boxes_ptr, int** all_procs_ptr, int* first_local_ptr);
int hypre_ComputeBoxnums(hypre_BoxArray* boxes, int* procs, int** boxnums_ptr);
int hypre_StructGridPrint(FILE* file, hypre_StructGrid* grid);
int hypre_PrintBoxArrayData(FILE* file, hypre_BoxArray* box_array, hypre_BoxArray* data_space, int num_values, double* data);
int hypre_PrintCCVDBoxArrayData(FILE* file, hypre_BoxArray* box_array, hypre_BoxArray* data_space, int num_values, int center_rank, int stencil_size, int* symm_elements, double* data);
int hypre_PrintCCBoxArrayData(FILE* file, hypre_BoxArray* box_array, hypre_BoxArray* data_space, int num_values, double* data);
double* hypre_StructMatrixExtractPointerByIndex(hypre_StructMatrix* matrix, int b, hypre_Index index);
hypre_StructMatrix* hypre_StructMatrixCreate(MPI_Comm comm, hypre_StructGrid* grid, hypre_StructStencil* user_stencil);
hypre_StructMatrix* hypre_StructMatrixRef(hypre_StructMatrix* matrix);
int hypre_StructMatrixDestroy(hypre_StructMatrix* matrix);
int hypre_StructMatrixInitializeShell(hypre_StructMatrix* matrix);
int hypre_StructMatrixInitializeData(hypre_StructMatrix* matrix, double* data);
int hypre_StructMatrixInitialize(hypre_StructMatrix* matrix);
int hypre_StructMatrixSetValues(hypre_StructMatrix* matrix, hypre_Index grid_index, int num_stencil_indices, int* stencil_indices, double* values, int action);
int hypre_StructMatrixSetBoxValues(hypre_StructMatrix* matrix, hypre_Box* value_box, int num_stencil_indices, int* stencil_indices, double* values, int action);
int hypre_StructMatrixAssemble(hypre_StructMatrix* matrix);
int hypre_StructMatrixSetNumGhost(hypre_StructMatrix* matrix, int* num_ghost);
int hypre_StructMatrixPrint(char* filename, hypre_StructMatrix* matrix, int all);
void* hypre_StructMatvecCreate(void);
int hypre_StructMatvecSetup(void* matvec_vdata, hypre_StructMatrix* A, hypre_StructVector* x);
int hypre_StructMatvecCompute(void* matvec_vdata, double alpha, hypre_StructMatrix* A, hypre_StructVector* x, double beta, hypre_StructVector* y);
int hypre_StructMatvecCC0(double alpha, hypre_StructMatrix* A, hypre_StructVector* x, hypre_StructVector* y, hypre_BoxArrayArray* compute_box_aa, hypre_IndexRef stride);
int hypre_StructMatvecCC1(double alpha, hypre_StructMatrix* A, hypre_StructVector* x, hypre_StructVector* y, hypre_BoxArrayArray* compute_box_aa, hypre_IndexRef stride);
int hypre_StructMatvecCC2(double alpha, hypre_StructMatrix* A, hypre_StructVector* x, hypre_StructVector* y, hypre_BoxArrayArray* compute_box_aa, hypre_IndexRef stride);
int hypre_StructMatvecDestroy(void* matvec_vdata);
int hypre_StructScale(double alpha, hypre_StructVector* y);
hypre_StructStencil* hypre_StructStencilCreate(int dim, int size, hypre_Index* shape);
hypre_StructStencil* hypre_StructStencilRef(hypre_StructStencil* stencil);
int hypre_StructStencilDestroy(hypre_StructStencil* stencil);
int hypre_StructStencilElementRank(hypre_StructStencil* stencil, hypre_Index stencil_element);
int hypre_StructStencilSymmetrize(hypre_StructStencil* stencil, hypre_StructStencil** symm_stencil_ptr, int** symm_elements_ptr);
hypre_StructVector* hypre_StructVectorCreate(MPI_Comm comm, hypre_StructGrid* grid);
hypre_StructVector* hypre_StructVectorRef(hypre_StructVector* vector);
int hypre_StructVectorDestroy(hypre_StructVector* vector);
int hypre_StructVectorInitializeShell(hypre_StructVector* vector);
int hypre_StructVectorInitializeData(hypre_StructVector* vector, double* data);
int hypre_StructVectorSetBoxValues(hypre_StructVector* vector, hypre_Box* value_box, double* values, int add_to);
int hypre_StructVectorAssemble(hypre_StructVector* vector);
int hypre_StructVectorClearBoundGhostValues(hypre_StructVector* vector);
int hypre_StructVectorPrint(char* filename, hypre_StructVector* vector, int all);
//======================== seq_mv.h ========================
typedef struct $anon_struct_15$TU0{
  double* data;
  int* i;
  int* j;
  int num_rows;
  int num_cols;
  int num_nonzeros;
  int* rownnz;
  int num_rownnz;
  int owns_data;
  double* expand_data;
} hypre_CSRMatrix;
typedef struct $anon_struct_16$TU0{
  int* i;
  int* j;
  double* data;
  int num_rows;
  int num_cols;
  int num_nonzeros;
  int owns_data;
  double* expand_data;
} hypre_BigCSRMatrix;
typedef struct $anon_struct_17$TU0{
  double* data;
  int size;
  int owns_data;
  int num_vectors;
  int multivec_storage_method;
  int vecstride;
  int idxstride;
} hypre_Vector;
hypre_BigCSRMatrix* hypre_BigCSRMatrixCreate(int num_rows, int num_cols, int num_nonzeros);
int hypre_BigCSRMatrixDestroy(hypre_BigCSRMatrix* matrix);
int hypre_CSRMatrixTranspose(hypre_CSRMatrix* A, hypre_CSRMatrix** AT, int data);
hypre_CSRMatrix* hypre_CSRMatrixCreate(int num_rows, int num_cols, int num_nonzeros);
int hypre_CSRMatrixDestroy(hypre_CSRMatrix* matrix);
int hypre_CSRMatrixInitialize(hypre_CSRMatrix* matrix);
int hypre_CSRMatrixSetRownnz(hypre_CSRMatrix* matrix);
int hypre_CSRMatrixCopy(hypre_CSRMatrix* A, hypre_CSRMatrix* B, int copy_data);
hypre_CSRMatrix* hypre_CSRMatrixUnion(hypre_CSRMatrix* A, hypre_CSRMatrix* B, int* col_map_offd_A, int* col_map_offd_B, int** col_map_offd_C);
int hypre_CSRMatrixMatvec(double alpha, hypre_CSRMatrix* A, hypre_Vector* x, double beta, hypre_Vector* y);
int hypre_CSRMatrixMatvecT(double alpha, hypre_CSRMatrix* A, hypre_Vector* x, double beta, hypre_Vector* y);
int hypre_GeneratePartitioning(int length, int num_procs, int** part_ptr);
hypre_Vector* hypre_SeqVectorCreate(int size);
int hypre_SeqVectorDestroy(hypre_Vector* vector);
int hypre_SeqVectorInitialize(hypre_Vector* vector);
int hypre_SeqVectorSetConstantValues(hypre_Vector* v, double value);
int hypre_SeqVectorSetRandomValues(hypre_Vector* v, int seed);
int hypre_SeqVectorCopy(hypre_Vector* x, hypre_Vector* y);
int hypre_SeqVectorScale(double alpha, hypre_Vector* y);
int hypre_SeqVectorAxpy(double alpha, hypre_Vector* x, hypre_Vector* y);
double hypre_SeqVectorInnerProd(hypre_Vector* x, hypre_Vector* y);
//======================= parcsr_mv.h ======================
typedef struct $anon_struct_18$TU0{
  MPI_Comm comm;
  int num_sends;
  int* send_procs;
  int* send_map_starts;
  int* send_map_elmts;
  int num_recvs;
  int* recv_procs;
  int* recv_vec_starts;
  MPI_Datatype* send_mpi_types;
  MPI_Datatype* recv_mpi_types;
} hypre_ParCSRCommPkg;
typedef struct $anon_struct_19$TU0{
  hypre_ParCSRCommPkg* comm_pkg;
  void* send_data;
  void* recv_data;
  int num_requests;
  MPI_Request* requests;
} hypre_ParCSRCommHandle;
typedef struct $anon_struct_20$TU0{
  int length;
  int row_start;
  int row_end;
  int storage_length;
  int* proc_list;
  int* row_start_list;
  int* row_end_list;
  int* sort_index;
} hypre_IJAssumedPart;
typedef struct $anon_struct_22$TU0{
  MPI_Comm comm;
  int global_size;
  int first_index;
  int last_index;
  int* partitioning;
  hypre_Vector* local_vector;
  int owns_data;
  int owns_partitioning;
  hypre_IJAssumedPart* assumed_partition;
} hypre_ParVector;
typedef struct $anon_struct_23$TU0{
  MPI_Comm comm;
  int global_num_rows;
  int global_num_cols;
  int first_row_index;
  int first_col_diag;
  int last_row_index;
  int last_col_diag;
  hypre_CSRMatrix* diag;
  hypre_CSRMatrix* offd;
  int* col_map_offd;
  int* row_starts;
  int* col_starts;
  hypre_ParCSRCommPkg* comm_pkg;
  hypre_ParCSRCommPkg* comm_pkgT;
  int owns_data;
  int owns_row_starts;
  int owns_col_starts;
  int num_nonzeros;
  double d_num_nonzeros;
  int* rowindices;
  double* rowvalues;
  int getrowactive;
  hypre_IJAssumedPart* assumed_partition;
} hypre_ParCSRMatrix;
int HYPRE_ParCSRMatrixPrintIJ(HYPRE_ParCSRMatrix matrix, int base_i, int base_j, char* file_name);
int hypre_ParCSRMatrixDestroyAssumedPartition(hypre_ParCSRMatrix* matrix);
int hypre_ParVectorDestroyAssumedPartition(hypre_ParVector* vector);
hypre_ParCSRCommHandle* hypre_ParCSRCommHandleCreate(int job, hypre_ParCSRCommPkg* comm_pkg, void* send_data, void* recv_data);
int hypre_ParCSRCommHandleDestroy(hypre_ParCSRCommHandle* comm_handle);
void hypre_MatvecCommPkgCreate_core(MPI_Comm comm, int* col_map_offd, int first_col_diag, int* col_starts, int num_cols_diag, int num_cols_offd, int firstColDiag, int* colMapOffd, int data, int* p_num_recvs, int** p_recv_procs, int** p_recv_vec_starts, int* p_num_sends, int** p_send_procs, int** p_send_map_starts, int** p_send_map_elmts);
int hypre_MatvecCommPkgCreate(hypre_ParCSRMatrix* A);
int hypre_MatvecCommPkgDestroy(hypre_ParCSRCommPkg* comm_pkg);
void hypre_ParMatmul_RowSizes(int** C_diag_i, int** C_offd_i, int** B_marker, int* A_diag_i, int* A_diag_j, int* A_offd_i, int* A_offd_j, int* B_diag_i, int* B_diag_j, int* B_offd_i, int* B_offd_j, int* B_ext_diag_i, int* B_ext_diag_j, int* B_ext_offd_i, int* B_ext_offd_j, int* map_B_to_C, int* C_diag_size, int* C_offd_size, int num_rows_diag_A, int num_cols_offd_A, int allsquare, int num_cols_diag_B, int num_cols_offd_B, int num_cols_offd_C);
hypre_ParCSRMatrix* hypre_ParMatmul(hypre_ParCSRMatrix* A, hypre_ParCSRMatrix* B);
hypre_CSRMatrix* hypre_ParCSRMatrixExtractConvBExt(hypre_ParCSRMatrix* B, hypre_ParCSRMatrix* A, int data);
hypre_BigCSRMatrix* hypre_ParCSRMatrixExtractBigExt(hypre_ParCSRMatrix* B, hypre_ParCSRMatrix* A, int data);
void hypre_ParMatmul_RowSizes_Marked(int** C_diag_i, int** C_offd_i, int** B_marker, int* A_diag_i, int* A_diag_j, int* A_offd_i, int* A_offd_j, int* B_diag_i, int* B_diag_j, int* B_offd_i, int* B_offd_j, int* B_ext_diag_i, int* B_ext_diag_j, int* B_ext_offd_i, int* B_ext_offd_j, int* map_B_to_C, int* C_diag_size, int* C_offd_size, int num_rows_diag_A, int num_cols_offd_A, int allsquare, int num_cols_diag_B, int num_cols_offd_B, int num_cols_offd_C, int* CF_marker, int* dof_func, int* dof_func_offd);
hypre_ParCSRMatrix* hypre_ParMatmul_FC(hypre_ParCSRMatrix* A, hypre_ParCSRMatrix* P, int* CF_marker, int* dof_func, int* dof_func_offd);
void hypre_ParMatScaleDiagInv_F(hypre_ParCSRMatrix* C, hypre_ParCSRMatrix* A, double weight, int* CF_marker);
hypre_ParCSRMatrix* hypre_ParMatMinus_F(hypre_ParCSRMatrix* P, hypre_ParCSRMatrix* C, int* CF_marker);
void hypre_ParCSRMatrixZero_F(hypre_ParCSRMatrix* P, int* CF_marker);
void hypre_ParCSRMatrixCopy_C(hypre_ParCSRMatrix* P, hypre_ParCSRMatrix* C, int* CF_marker);
hypre_ParCSRMatrix* hypre_ParCSRMatrixCreate(MPI_Comm comm, int global_num_rows, int global_num_cols, int* row_starts, int* col_starts, int num_cols_offd, int num_nonzeros_diag, int num_nonzeros_offd);
int hypre_ParCSRMatrixDestroy(hypre_ParCSRMatrix* matrix);
int hypre_ParCSRMatrixInitialize(hypre_ParCSRMatrix* matrix);
int hypre_ParCSRMatrixSetNumNonzeros(hypre_ParCSRMatrix* matrix);
int hypre_ParCSRMatrixSetDNumNonzeros(hypre_ParCSRMatrix* matrix);
int hypre_ParCSRMatrixSetRowStartsOwner(hypre_ParCSRMatrix* matrix, int owns_row_starts);
int hypre_ParCSRMatrixSetColStartsOwner(hypre_ParCSRMatrix* matrix, int owns_col_starts);
int hypre_ParCSRMatrixPrintIJ(hypre_ParCSRMatrix* matrix, const int base_i, const int base_j, char* filename);
int hypre_ParCSRMatrixGetRow(hypre_ParCSRMatrix* mat, int row, int* size, int** col_ind, double** values);
int hypre_ParCSRMatrixRestoreRow(hypre_ParCSRMatrix* matrix, int row, int* size, int** col_ind, double** values);
hypre_CSRMatrix* hypre_MergeDiagAndOffd(hypre_ParCSRMatrix* par_matrix);
hypre_CSRMatrix* hypre_ParCSRMatrixToCSRMatrixAll(hypre_ParCSRMatrix* par_matrix);
int hypre_ParCSRMatrixCopy(hypre_ParCSRMatrix* A, hypre_ParCSRMatrix* B, int copy_data);
hypre_ParCSRMatrix* hypre_ParCSRMatrixUnion(hypre_ParCSRMatrix* A, hypre_ParCSRMatrix* B);
int hypre_ParCSRMatrixMatvec(double alpha, hypre_ParCSRMatrix* A, hypre_ParVector* x, double beta, hypre_ParVector* y);
int hypre_ParCSRMatrixMatvecT(double alpha, hypre_ParCSRMatrix* A, hypre_ParVector* x, double beta, hypre_ParVector* y);
hypre_ParVector* hypre_ParVectorCreate(MPI_Comm comm, int global_size, int* partitioning);
int hypre_ParVectorDestroy(hypre_ParVector* vector);
int hypre_ParVectorInitialize(hypre_ParVector* vector);
int hypre_ParVectorSetPartitioningOwner(hypre_ParVector* vector, int owns_partitioning);
int hypre_ParVectorSetConstantValues(hypre_ParVector* v, double value);
int hypre_ParVectorSetRandomValues(hypre_ParVector* v, int seed);
int hypre_ParVectorCopy(hypre_ParVector* x, hypre_ParVector* y);
int hypre_ParVectorScale(double alpha, hypre_ParVector* y);
int hypre_ParVectorAxpy(double alpha, hypre_ParVector* x, hypre_ParVector* y);
double hypre_ParVectorInnerProd(hypre_ParVector* x, hypre_ParVector* y);
hypre_Vector* hypre_ParVectorToVectorAll(hypre_ParVector* par_v);
int hypre_ParVectorPrintIJ(hypre_ParVector* vector, int base_j, char* filename);
//========================= IJ_mv.h ========================
typedef struct $anon_struct_24$TU0{
  int local_num_rows;
  int local_num_cols;
  int need_aux;
  int* row_length;
  int* row_space;
  int** aux_j;
  double** aux_data;
  int* indx_diag;
  int* indx_offd;
  int max_off_proc_elmts;
  int current_num_elmts;
  int off_proc_i_indx;
  int* off_proc_i;
  int* off_proc_j;
  double* off_proc_data;
  int* aux_offd_j;
} hypre_AuxParCSRMatrix;
typedef struct $anon_struct_25$TU0{
  int max_off_proc_elmts;
  int current_num_elmts;
  int* off_proc_i;
  double* off_proc_data;
} hypre_AuxParVector;
typedef struct hypre_IJMatrix_struct{
  MPI_Comm comm;
  int* row_partitioning;
  int* col_partitioning;
  int object_type;
  void* object;
  void* translator;
  int assemble_flag;
  int global_first_row;
  int global_first_col;
  int global_num_rows;
  int global_num_cols;
} hypre_IJMatrix;
typedef struct hypre_IJVector_struct{
  MPI_Comm comm;
  int* partitioning;
  int object_type;
  void* object;
  void* translator;
  int global_first_row;
  int global_num_rows;
} hypre_IJVector;
int hypre_AuxParCSRMatrixCreate(hypre_AuxParCSRMatrix** aux_matrix, int local_num_rows, int local_num_cols, int* sizes);
int hypre_AuxParCSRMatrixDestroy(hypre_AuxParCSRMatrix* matrix);
int hypre_AuxParCSRMatrixInitialize(hypre_AuxParCSRMatrix* matrix);
int hypre_AuxParVectorCreate(hypre_AuxParVector** aux_vector);
int hypre_AuxParVectorDestroy(hypre_AuxParVector* vector);
int hypre_AuxParVectorInitialize(hypre_AuxParVector* vector);
int hypre_IJMatrixCreateParCSR(hypre_IJMatrix* matrix);
int hypre_IJMatrixSetRowSizesParCSR(hypre_IJMatrix* matrix, int* sizes);
int hypre_IJMatrixInitializeParCSR(hypre_IJMatrix* matrix);
int hypre_IJMatrixGetValuesParCSR(hypre_IJMatrix* matrix, int nrows, int* ncols, int* rows, int* cols, double* values);
int hypre_IJMatrixSetValuesParCSR(hypre_IJMatrix* matrix, int nrows, int* ncols, int* rows, int* cols, double* values);
int hypre_IJMatrixAddToValuesParCSR(hypre_IJMatrix* matrix, int nrows, int* ncols, int* rows, int* cols, double* values);
int hypre_IJMatrixAssembleParCSR(hypre_IJMatrix* matrix);
int hypre_IJMatrixDestroyParCSR(hypre_IJMatrix* matrix);
int hypre_IJMatrixAssembleOffProcValsParCSR(hypre_IJMatrix* matrix, int off_proc_i_indx, int max_off_proc_elmts, int current_num_elmts, int* off_proc_i, int* off_proc_j, double* off_proc_data);
int hypre_FindProc(int* list, int value, int list_length);
int hypre_IJVectorCreatePar(hypre_IJVector* vector, int* IJpartitioning);
int hypre_IJVectorDestroyPar(hypre_IJVector* vector);
int hypre_IJVectorInitializePar(hypre_IJVector* vector);
int hypre_IJVectorAssemblePar(hypre_IJVector* vector);
int hypre_IJVectorAssembleOffProcValsPar(hypre_IJVector* vector, int max_off_proc_elmts, int current_num_elmts, int* off_proc_i, double* off_proc_data);
//====================== sstruct_mv.h ======================
typedef struct hypre_BoxMapEntry_struct{
  hypre_Index imin;
  hypre_Index imax;
  int  num_ghost[6];
  void* info;
  struct hypre_BoxMapEntry_struct* next;
} hypre_BoxMapEntry;
typedef struct $anon_struct_26$TU0{
  int max_nentries;
  hypre_Index global_imin;
  hypre_Index global_imax;
  int  num_ghost[6];
  int nentries;
  hypre_BoxMapEntry* entries;
  hypre_BoxMapEntry** table;
  hypre_BoxMapEntry* boxproc_table;
  int*  indexes[3];
  int  size[3];
  int* boxproc_offset;
  int  last_index[3];
} hypre_BoxMap;
typedef enum hypre_SStructVariable_enum hypre_SStructVariable;
typedef struct $anon_struct_27$TU0{
  HYPRE_SStructVariable type;
  int rank;
  int proc;
} hypre_SStructUVar;
typedef struct $anon_struct_28$TU0{
  int part;
  hypre_Index cell;
  int nuvars;
  hypre_SStructUVar* uvars;
} hypre_SStructUCVar;
typedef struct $anon_struct_29$TU0{
  MPI_Comm comm;
  int ndim;
  int nvars;
  HYPRE_SStructVariable* vartypes;
  hypre_StructGrid*  sgrids[8];
  hypre_BoxArray*  iboxarrays[8];
  hypre_BoxArray* pneighbors;
  int local_size;
  int global_size;
  hypre_Index periodic;
  int ghlocal_size;
  int cell_sgrid_done;
} hypre_SStructPGrid;
typedef struct $anon_struct_30$TU0{
  hypre_Box box;
  int part;
  hypre_Index ilower;
  hypre_Index coord;
  hypre_Index dir;
  int primary;
} hypre_SStructNeighbor;
enum hypre_SStructMapInfoType{
  hypre_SSTRUCT_MAP_INFO_DEFAULT=0,
  hypre_SSTRUCT_MAP_INFO_NEIGHBOR=1
};
typedef struct $anon_struct_31$TU0{
  int type;
  int proc;
  int offset;
  int box;
  int ghoffset;
} hypre_SStructMapInfo;
typedef struct $anon_struct_32$TU0{
  int type;
  int proc;
  int offset;
  int box;
  int ghoffset;
  int part;
  hypre_Index ilower;
  hypre_Index coord;
  hypre_Index dir;
  hypre_Index stride;
  hypre_Index ghstride;
} hypre_SStructNMapInfo;
typedef struct hypre_SStructGrid_struct{
  MPI_Comm comm;
  int ndim;
  int nparts;
  hypre_SStructPGrid** pgrids;
  int* nneighbors;
  hypre_SStructNeighbor** neighbors;
  int** nvneighbors;
  hypre_SStructNeighbor*** vneighbors;
  int nucvars;
  hypre_SStructUCVar** ucvars;
  hypre_BoxMap*** maps;
  hypre_SStructMapInfo*** info;
  hypre_SStructNMapInfo*** ninfo;
  int start_rank;
  int local_size;
  int global_size;
  int ref_count;
  int ghlocal_size;
  int ghstart_rank;
} hypre_SStructGrid;
typedef struct hypre_SStructStencil_struct{
  hypre_StructStencil* sstencil;
  int* vars;
  int ref_count;
} hypre_SStructStencil;
typedef struct $anon_struct_33$TU0{
  int to_part;
  hypre_Index to_index;
  int to_var;
  int to_box;
  int to_proc;
  int rank;
} hypre_SStructUEntry;
typedef struct $anon_struct_34$TU0{
  int part;
  hypre_Index index;
  int var;
  int box;
  int nUentries;
  hypre_SStructUEntry* Uentries;
} hypre_SStructUVEntry;
typedef struct hypre_SStructGraph_struct{
  MPI_Comm comm;
  int ndim;
  hypre_SStructGrid* grid;
  int nparts;
  hypre_SStructPGrid** pgrids;
  hypre_SStructStencil*** stencils;
  int nUventries;
  int aUventries;
  int* iUventries;
  hypre_SStructUVEntry** Uventries;
  int totUentries;
  int ref_count;
  int type;
} hypre_SStructGraph;
typedef struct $anon_struct_35{
  MPI_Comm comm;
  hypre_SStructPGrid* pgrid;
  hypre_SStructStencil** stencils;
  int nvars;
  int** smaps;
  hypre_StructStencil*** sstencils;
  hypre_StructMatrix*** smatrices;
  int** symmetric;
  int sentries_size;
  int* sentries;
  int complex;
  int ref_count;
} hypre_SStructPMatrix;
typedef struct hypre_SStructMatrix_struct{
  MPI_Comm comm;
  int ndim;
  hypre_SStructGraph* graph;
  int*** splits;
  int nparts;
  hypre_SStructPMatrix** pmatrices;
  int*** symmetric;
  HYPRE_IJMatrix ijmatrix;
  hypre_ParCSRMatrix* parcsrmatrix;
  int entries_size;
  int* Sentries;
  int* Uentries;
  int* tmp_col_coords;
  double* tmp_coeffs;
  int ns_symmetric;
  int complex;
  int global_size;
  int ref_count;
  int object_type;
} hypre_SStructMatrix;
typedef struct $anon_struct_36{
  MPI_Comm comm;
  hypre_SStructPGrid* pgrid;
  int nvars;
  hypre_StructVector** svectors;
  hypre_CommPkg** comm_pkgs;
  int complex;
  int ref_count;
  int* dataindices;
  int datasize;
} hypre_SStructPVector;
typedef struct hypre_SStructVector_struct{
  MPI_Comm comm;
  int ndim;
  hypre_SStructGrid* grid;
  int object_type;
  int nparts;
  hypre_SStructPVector** pvectors;
  hypre_CommPkg*** comm_pkgs;
  HYPRE_IJVector ijvector;
  hypre_ParVector* parvector;
  double* data;
  int* dataindices;
  int datasize;
  int complex;
  int global_size;
  int ref_count;
} hypre_SStructVector;
int hypre_BoxMapEntryGetInfo(hypre_BoxMapEntry* entry, void** info_ptr);
int hypre_BoxMapEntryGetExtents(hypre_BoxMapEntry* entry, hypre_Index imin, hypre_Index imax);
int hypre_BoxMapCreate(int max_nentries, hypre_Index global_imin, hypre_Index global_imax, int nprocs, hypre_BoxMap** map_ptr);
int hypre_BoxMapIncSize(hypre_BoxMap* map, int inc_nentries);
int hypre_BoxMapAddEntry(hypre_BoxMap* map, hypre_Index imin, hypre_Index imax, void* info);
int hypre_BoxMapAssemble(hypre_BoxMap* map, MPI_Comm comm);
int hypre_BoxMapDestroy(hypre_BoxMap* map);
int hypre_BoxMapFindEntry(hypre_BoxMap* map, hypre_Index index, hypre_BoxMapEntry** entry_ptr);
int hypre_BoxMapFindBoxProcEntry(hypre_BoxMap* map, int box, int proc, hypre_BoxMapEntry** entry_ptr);
int hypre_BoxMapIntersect(hypre_BoxMap* map, hypre_Index ilower, hypre_Index iupper, hypre_BoxMapEntry*** entries_ptr, int* nentries_ptr);
int hypre_BoxMapSetNumGhost(hypre_BoxMap* map, int* num_ghost);
int HYPRE_SStructGraphCreate(MPI_Comm comm, HYPRE_SStructGrid grid, HYPRE_SStructGraph* graph_ptr);
int HYPRE_SStructGridCreate(MPI_Comm comm, int ndim, int nparts, HYPRE_SStructGrid* grid_ptr);
int HYPRE_SStructMatrixCreate(MPI_Comm comm, HYPRE_SStructGraph graph, HYPRE_SStructMatrix* matrix_ptr);
int HYPRE_SStructStencilCreate(int ndim, int size, HYPRE_SStructStencil* stencil_ptr);
int HYPRE_SStructVectorCreate(MPI_Comm comm, HYPRE_SStructGrid grid, HYPRE_SStructVector* vector_ptr);
int hypre_SStructGraphRef(hypre_SStructGraph* graph, hypre_SStructGraph** graph_ref);
int hypre_SStructGraphFindUVEntry(hypre_SStructGraph* graph, int part, hypre_Index index, int var, hypre_SStructUVEntry** Uventry_ptr);
int hypre_SStructVariableGetOffset(HYPRE_SStructVariable vartype, int ndim, hypre_Index varoffset);
int hypre_SStructPGridCreate(MPI_Comm comm, int ndim, hypre_SStructPGrid** pgrid_ptr);
int hypre_SStructPGridDestroy(hypre_SStructPGrid* pgrid);
int hypre_SStructPGridSetExtents(hypre_SStructPGrid* pgrid, hypre_Index ilower, hypre_Index iupper);
int hypre_SStructPGridSetVariables(hypre_SStructPGrid* pgrid, int nvars, HYPRE_SStructVariable* vartypes);
int hypre_SStructPGridSetPNeighbor(hypre_SStructPGrid* pgrid, hypre_Box* pneighbor_box);
int hypre_SStructPGridAssemble(hypre_SStructPGrid* pgrid);
int hypre_SStructGridRef(hypre_SStructGrid* grid, hypre_SStructGrid** grid_ref);
int hypre_SStructGridAssembleMaps(hypre_SStructGrid* grid);
int hypre_SStructGridAssembleNBorMaps(hypre_SStructGrid* grid);
int hypre_SStructGridFindMapEntry(hypre_SStructGrid* grid, int part, hypre_Index index, int var, hypre_BoxMapEntry** entry_ptr);
int hypre_SStructGridBoxProcFindMapEntry(hypre_SStructGrid* grid, int part, int var, int box, int proc, hypre_BoxMapEntry** entry_ptr);
int hypre_SStructMapEntryGetCSRstrides(hypre_BoxMapEntry* entry, hypre_Index strides);
int hypre_SStructMapEntryGetGhstrides(hypre_BoxMapEntry* entry, hypre_Index strides);
int hypre_SStructMapEntryGetGlobalCSRank(hypre_BoxMapEntry* entry, hypre_Index index, int* rank_ptr);
int hypre_SStructMapEntryGetGlobalGhrank(hypre_BoxMapEntry* entry, hypre_Index index, int* rank_ptr);
int hypre_SStructMapEntryGetProcess(hypre_BoxMapEntry* entry, int* proc_ptr);
int hypre_SStructMapEntryGetBox(hypre_BoxMapEntry* entry, int* box_ptr);
int hypre_SStructBoxToNBorBox(hypre_Box* box, hypre_Index index, hypre_Index nbor_index, hypre_Index coord, hypre_Index dir);
int hypre_SStructNBorBoxToBox(hypre_Box* nbor_box, hypre_Index index, hypre_Index nbor_index, hypre_Index coord, hypre_Index dir);
int hypre_SStructMapEntryGetGlobalRank(hypre_BoxMapEntry* entry, hypre_Index index, int* rank_ptr, int type);
int hypre_SStructMapEntryGetStrides(hypre_BoxMapEntry* entry, hypre_Index strides, int type);
int hypre_SStructPMatrixCreate(MPI_Comm comm, hypre_SStructPGrid* pgrid, hypre_SStructStencil** stencils, hypre_SStructPMatrix** pmatrix_ptr);
int hypre_SStructPMatrixDestroy(hypre_SStructPMatrix* pmatrix);
int hypre_SStructPMatrixInitialize(hypre_SStructPMatrix* pmatrix);
int hypre_SStructPMatrixSetValues(hypre_SStructPMatrix* pmatrix, hypre_Index index, int var, int nentries, int* entries, double* values, int add_to);
int hypre_SStructPMatrixSetBoxValues(hypre_SStructPMatrix* pmatrix, hypre_Index ilower, hypre_Index iupper, int var, int nentries, int* entries, double* values, int add_to);
int hypre_SStructPMatrixAssemble(hypre_SStructPMatrix* pmatrix);
int hypre_SStructPMatrixSetSymmetric(hypre_SStructPMatrix* pmatrix, int var, int to_var, int symmetric);
int hypre_SStructPMatrixPrint(char* filename, hypre_SStructPMatrix* pmatrix, int all);
int hypre_SStructUMatrixInitialize(hypre_SStructMatrix* matrix);
int hypre_SStructUMatrixSetValues(hypre_SStructMatrix* matrix, int part, hypre_Index index, int var, int nentries, int* entries, double* values, int add_to);
int hypre_SStructUMatrixSetBoxValues(hypre_SStructMatrix* matrix, int part, hypre_Index ilower, hypre_Index iupper, int var, int nentries, int* entries, double* values, int add_to);
int hypre_SStructUMatrixAssemble(hypre_SStructMatrix* matrix);
int hypre_SStructMatrixSplitEntries(hypre_SStructMatrix* matrix, int part, int var, int nentries, int* entries, int* nSentries_ptr, int** Sentries_ptr, int* nUentries_ptr, int** Uentries_ptr);
int hypre_SStructPMatvecCreate(void** pmatvec_vdata_ptr);
int hypre_SStructPMatvecSetup(void* pmatvec_vdata, hypre_SStructPMatrix* pA, hypre_SStructPVector* px);
int hypre_SStructPMatvecCompute(void* pmatvec_vdata, double alpha, hypre_SStructPMatrix* pA, hypre_SStructPVector* px, double beta, hypre_SStructPVector* py);
int hypre_SStructPMatvecDestroy(void* pmatvec_vdata);
int hypre_SStructMatvecCreate(void** matvec_vdata_ptr);
int hypre_SStructMatvecSetup(void* matvec_vdata, hypre_SStructMatrix* A, hypre_SStructVector* x);
int hypre_SStructMatvecCompute(void* matvec_vdata, double alpha, hypre_SStructMatrix* A, hypre_SStructVector* x, double beta, hypre_SStructVector* y);
int hypre_SStructMatvecDestroy(void* matvec_vdata);
int hypre_SStructMatvec(double alpha, hypre_SStructMatrix* A, hypre_SStructVector* x, double beta, hypre_SStructVector* y);
int hypre_SStructStencilRef(hypre_SStructStencil* stencil, hypre_SStructStencil** stencil_ref);
int hypre_SStructPVectorCreate(MPI_Comm comm, hypre_SStructPGrid* pgrid, hypre_SStructPVector** pvector_ptr);
int hypre_SStructPVectorDestroy(hypre_SStructPVector* pvector);
int hypre_SStructPVectorSetBoxValues(hypre_SStructPVector* pvector, hypre_Index ilower, hypre_Index iupper, int var, double* values, int add_to);
int hypre_SStructPVectorAssemble(hypre_SStructPVector* pvector);
int hypre_SStructPVectorGather(hypre_SStructPVector* pvector);
int hypre_SStructPVectorPrint(char* filename, hypre_SStructPVector* pvector, int all);
int hypre_SStructVectorConvert(hypre_SStructVector* vector, hypre_ParVector** parvector_ptr);
int hypre_SStructVectorParConvert(hypre_SStructVector* vector, hypre_ParVector** parvector_ptr);
int hypre_SStructVectorRestore(hypre_SStructVector* vector, hypre_ParVector* parvector);
int hypre_SStructVectorParRestore(hypre_SStructVector* vector, hypre_ParVector* parvector);
int hypre_SStructPVectorInitializeShell(hypre_SStructPVector* pvector);
int hypre_SStructVectorInitializeShell(hypre_SStructVector* vector);
//======================== amg2013.c =======================
char  infile_default[50] = "sstruct.in.MG.FD";
typedef int[3] Index;
typedef int[9] ProblemIndex;
typedef struct $anon_struct_37{
  int nboxes;
  ProblemIndex* ilowers;
  ProblemIndex* iuppers;
  int* boxsizes;
  int max_boxsize;
  int nvars;
  HYPRE_SStructVariable* vartypes;
  int add_nvars;
  ProblemIndex* add_indexes;
  HYPRE_SStructVariable* add_vartypes;
  int glue_nboxes;
  ProblemIndex* glue_ilowers;
  ProblemIndex* glue_iuppers;
  int* glue_nbor_parts;
  ProblemIndex* glue_nbor_ilowers;
  ProblemIndex* glue_nbor_iuppers;
  Index* glue_index_maps;
  int* glue_primaries;
  int* stencil_num;
  int graph_nboxes;
  ProblemIndex* graph_ilowers;
  ProblemIndex* graph_iuppers;
  Index* graph_strides;
  int* graph_vars;
  int* graph_to_parts;
  ProblemIndex* graph_to_ilowers;
  ProblemIndex* graph_to_iuppers;
  Index* graph_to_strides;
  int* graph_to_vars;
  Index* graph_index_maps;
  Index* graph_index_signs;
  int* graph_entries;
  double* graph_values;
  int* graph_boxsizes;
  int matset_nboxes;
  ProblemIndex* matset_ilowers;
  ProblemIndex* matset_iuppers;
  Index* matset_strides;
  int* matset_vars;
  int* matset_entries;
  double* matset_values;
  int matadd_nboxes;
  ProblemIndex* matadd_ilowers;
  ProblemIndex* matadd_iuppers;
  int* matadd_vars;
  int* matadd_nentries;
  int** matadd_entries;
  double** matadd_values;
  Index periodic;
} ProblemPartData;
typedef struct $anon_struct_38{
  int ndim;
  int nparts;
  ProblemPartData* pdata;
  int max_boxsize;
  int nstencils;
  int* stencil_sizes;
  Index** stencil_offsets;
  int** stencil_vars;
  double** stencil_values;
  int symmetric_num;
  int* symmetric_parts;
  int* symmetric_vars;
  int* symmetric_to_vars;
  int* symmetric_booleans;
  int ns_symmetric;
  int npools;
  int* pools;
  int ndists;
  int* dist_npools;
  int** dist_pools;
} ProblemData;
int BuildParLaplacian(int argc, char*  argv[], double* system_size_ptr, HYPRE_ParCSRMatrix* A_ptr, HYPRE_ParVector* rhs_ptr, HYPRE_ParVector* x_ptr);
int BuildParLaplacian27pt(int argc, char*  argv[], double* system_size_ptr, HYPRE_ParCSRMatrix* A_ptr, HYPRE_ParVector* rhs_ptr, HYPRE_ParVector* x_ptr);
int BuildParVarDifConv(int argc, char*  argv[], double* system_size_ptr, HYPRE_ParCSRMatrix* A_ptr, HYPRE_ParVector* rhs_ptr, HYPRE_ParVector* x_ptr);
int GetVariableBox(Index cell_ilower, Index cell_iupper, int int_vartype, Index var_ilower, Index var_iupper) {
  int ierr = 0;
  HYPRE_SStructVariable vartype = (HYPRE_SStructVariable)int_vartype;
  var_ilower[0] = cell_ilower[0];
  var_ilower[1] = cell_ilower[1];
  var_ilower[2] = cell_ilower[2];
  var_iupper[0] = cell_iupper[0];
  var_iupper[1] = cell_iupper[1];
  var_iupper[2] = cell_iupper[2];
  switch (vartype) {
    case HYPRE_SSTRUCT_VARIABLE_CELL:
      (var_ilower[0]) -= 0;
      (var_ilower[1]) -= 0;
      (var_ilower[2]) -= 0;
      break;
    case HYPRE_SSTRUCT_VARIABLE_NODE:
      (var_ilower[0]) -= 1;
      (var_ilower[1]) -= 1;
      (var_ilower[2]) -= 1;
      break;
    case HYPRE_SSTRUCT_VARIABLE_XFACE:
      (var_ilower[0]) -= 1;
      (var_ilower[1]) -= 0;
      (var_ilower[2]) -= 0;
      break;
    case HYPRE_SSTRUCT_VARIABLE_YFACE:
      (var_ilower[0]) -= 0;
      (var_ilower[1]) -= 1;
      (var_ilower[2]) -= 0;
      break;
    case HYPRE_SSTRUCT_VARIABLE_ZFACE:
      (var_ilower[0]) -= 0;
      (var_ilower[1]) -= 0;
      (var_ilower[2]) -= 1;
      break;
    case HYPRE_SSTRUCT_VARIABLE_XEDGE:
      (var_ilower[0]) -= 0;
      (var_ilower[1]) -= 1;
      (var_ilower[2]) -= 1;
      break;
    case HYPRE_SSTRUCT_VARIABLE_YEDGE:
      (var_ilower[0]) -= 1;
      (var_ilower[1]) -= 0;
      (var_ilower[2]) -= 1;
      break;
    case HYPRE_SSTRUCT_VARIABLE_ZEDGE:
      (var_ilower[0]) -= 1;
      (var_ilower[1]) -= 1;
      (var_ilower[2]) -= 0;
      break;
    case HYPRE_SSTRUCT_VARIABLE_UNDEFINED:
      break;
  }
  return ierr;
}
int SScanIntArray(char* sdata_ptr, char** sdata_ptr_ptr, int size, int* array) {
  int i;
  sdata_ptr += strspn(sdata_ptr, " \t\n[");
  for (i = 0; i < size; i++) {
    array[i] = strtol(sdata_ptr, &(sdata_ptr), 10);
  }
  sdata_ptr += strcspn(sdata_ptr, "]") + 1;
  *sdata_ptr_ptr = sdata_ptr;
  return 0;
}
int SScanDblArray(char* sdata_ptr, char** sdata_ptr_ptr, int size, double* array) {
  int i;
  sdata_ptr += strspn(sdata_ptr, " \t\n[");
  for (i = 0; i < size; i++) {
    array[i] = strtod(sdata_ptr, &(sdata_ptr));
  }
  sdata_ptr += strcspn(sdata_ptr, "]") + 1;
  *sdata_ptr_ptr = sdata_ptr;
  return 0;
}
int SScanProblemIndex(char* sdata_ptr, char** sdata_ptr_ptr, int ndim, ProblemIndex index) {
  int i;
  char  sign[3];
  for (i = 0; i < 9; i++) {
    index[i] = 0;
  }
  sdata_ptr += strspn(sdata_ptr, " \t\n(");
  switch (ndim) {
    case 1:
      sscanf(sdata_ptr, "%d%c", &(index[0]), &(sign[0]));
      break;
    case 2:
      sscanf(sdata_ptr, "%d%c%d%c", &(index[0]), &(sign[0]), &(index[1]), &(sign[1]));
      break;
    case 3:
      sscanf(sdata_ptr, "%d%c%d%c%d%c", &(index[0]), &(sign[0]), &(index[1]), &(sign[1]), &(index[2]), &(sign[2]));
      break;
  }
  sdata_ptr += strcspn(sdata_ptr, ":)");
  if ((*sdata_ptr) == ':') {
    sdata_ptr += 1;
    switch (ndim) {
      case 1:
        sscanf(sdata_ptr, "%d", &(index[6]));
        break;
      case 2:
        sscanf(sdata_ptr, "%d%d", &(index[6]), &(index[7]));
        break;
      case 3:
        sscanf(sdata_ptr, "%d%d%d", &(index[6]), &(index[7]), &(index[8]));
        break;
    }
    for (i = 0; i < ndim; i++) {
      index[i] += index[i + 6];
    }
  }
  sdata_ptr += strcspn(sdata_ptr, ")") + 1;
  for (i = 0; i < ndim; i++) {
    if ((sign[i]) == '+') {
      index[i + 3] = 1;
    }
  }
  *sdata_ptr_ptr = sdata_ptr;
  return 0;
}
int ReadData(char* filename, ProblemData* data_ptr) {
  ProblemData data;
  ProblemPartData pdata;
  int myid;
  FILE* file;
  char* sdata = (void*)0;
  char* sdata_line;
  char* sdata_ptr;
  int sdata_size;
  int size;
  int memchunk = 10000;
  int maxline = 250;
  char  key[250];
  int part;
  int var;
  int s;
  int entry;
  int i;
  int il;
  int iu;
  MPI_Comm_rank(MPI_COMM_WORLD, &(myid));
  if (myid == 0) {
    if ((file = fopen(filename, "r")) == (void*)0) {
      printf("Error: can't open input file %s\n", filename);
      exit(1);
    }
    sdata_size = 0;
    sdata = (char*)(hypre_MAlloc((unsigned)(sizeof(char) * memchunk)));
    sdata_line = fgets(sdata, maxline, file);
    s = 0;
    while (sdata_line != (void*)0) {
      sdata_size += strlen(sdata_line) + 1;
      if ((sdata_size + maxline) > s) {
        sdata = (char*)(hypre_ReAlloc((char*)sdata, (unsigned)(sizeof(char) * (sdata_size + memchunk))));
        s = sdata_size + memchunk;
      }
      sdata_line = fgets(sdata + sdata_size, maxline, file);
    }
  }
  MPI_Bcast(&(sdata_size), 1, MPI_INT, 0, MPI_COMM_WORLD);
  sdata = (char*)(hypre_ReAlloc((char*)sdata, (unsigned)(sizeof(char) * sdata_size)));
  MPI_Bcast(sdata, sdata_size, MPI_CHAR, 0, MPI_COMM_WORLD);
  data.max_boxsize = 0;
  data.symmetric_num = 0;
  data.symmetric_parts = (void*)0;
  data.symmetric_vars = (void*)0;
  data.symmetric_to_vars = (void*)0;
  data.symmetric_booleans = (void*)0;
  data.ns_symmetric = 0;
  data.ndists = 0;
  data.dist_npools = (void*)0;
  data.dist_pools = (void*)0;
  sdata_line = sdata;
  while (sdata_line < (sdata + sdata_size)) {
    sdata_ptr = sdata_line;
    if ((sscanf(sdata_ptr, "%s", key) > 0) && ((sdata_ptr[0]) != '#')) {
      sdata_ptr += strcspn(sdata_ptr, " \t\n");
      if (strcmp(key, "GridCreate:") == 0) {
        data.ndim = strtol(sdata_ptr, &(sdata_ptr), 10);
        data.nparts = strtol(sdata_ptr, &(sdata_ptr), 10);
        data.pdata = (ProblemPartData*)(hypre_CAlloc((unsigned)(data.nparts), (unsigned)(sizeof(ProblemPartData))));
      }
      else
        if (strcmp(key, "GridSetExtents:") == 0) {
          part = strtol(sdata_ptr, &(sdata_ptr), 10);
          pdata = data.pdata[part];
          if ((pdata.nboxes % 10) == 0) {
            size = pdata.nboxes + 10;
            pdata.ilowers = (ProblemIndex*)(hypre_ReAlloc((char*)(pdata.ilowers), (unsigned)(sizeof(ProblemIndex) * size)));
            pdata.iuppers = (ProblemIndex*)(hypre_ReAlloc((char*)(pdata.iuppers), (unsigned)(sizeof(ProblemIndex) * size)));
            pdata.boxsizes = (int*)(hypre_ReAlloc((char*)(pdata.boxsizes), (unsigned)(sizeof(int) * size)));
          }
          SScanProblemIndex(sdata_ptr, &(sdata_ptr), data.ndim, pdata.ilowers[pdata.nboxes]);
          SScanProblemIndex(sdata_ptr, &(sdata_ptr), data.ndim, pdata.iuppers[pdata.nboxes]);
          il = 1;
          iu = 1;
          for (i = 0; i < data.ndim; i++) {
            il -= (pdata.ilowers[pdata.nboxes][i + 3]);
            iu -= (pdata.iuppers[pdata.nboxes][i + 3]);
          }
          if ((il != 0) || (iu != 1)) {
            printf("Error: Invalid use of `+-' in GridSetExtents\n");
            exit(1);
          }
          pdata.boxsizes[pdata.nboxes] = 1;
          for (i = 0; i < 3; i++) {
            (pdata.boxsizes[pdata.nboxes]) -= (((pdata.iuppers[pdata.nboxes][i]) - (pdata.ilowers[pdata.nboxes][i])) + 2);
          }
          pdata.max_boxsize = pdata.max_boxsize < (pdata.boxsizes[pdata.nboxes]) ? pdata.boxsizes[pdata.nboxes] : pdata.max_boxsize;
          pdata.nboxes++;
          data.pdata[part] = pdata;
        }
        else
          if (strcmp(key, "GridSetVariables:") == 0) {
            part = strtol(sdata_ptr, &(sdata_ptr), 10);
            pdata = data.pdata[part];
            pdata.nvars = strtol(sdata_ptr, &(sdata_ptr), 10);
            pdata.vartypes = (HYPRE_SStructVariable*)(hypre_CAlloc((unsigned)(pdata.nvars), (unsigned)(sizeof(HYPRE_SStructVariable))));
            SScanIntArray(sdata_ptr, &(sdata_ptr), pdata.nvars, (int*)(pdata.vartypes));
            data.pdata[part] = pdata;
          }
          else
            if (strcmp(key, "GridAddVariables:") == 0) {
              printf("GridAddVariables not yet implemented!\n");
              exit(1);
            }
            else
              if (strcmp(key, "GridSetNeighborBox:") == 0) {
                part = strtol(sdata_ptr, &(sdata_ptr), 10);
                pdata = data.pdata[part];
                if ((pdata.glue_nboxes % 10) == 0) {
                  size = pdata.glue_nboxes + 10;
                  pdata.glue_ilowers = (ProblemIndex*)(hypre_ReAlloc((char*)(pdata.glue_ilowers), (unsigned)(sizeof(ProblemIndex) * size)));
                  pdata.glue_iuppers = (ProblemIndex*)(hypre_ReAlloc((char*)(pdata.glue_iuppers), (unsigned)(sizeof(ProblemIndex) * size)));
                  pdata.glue_nbor_parts = (int*)(hypre_ReAlloc((char*)(pdata.glue_nbor_parts), (unsigned)(sizeof(int) * size)));
                  pdata.glue_nbor_ilowers = (ProblemIndex*)(hypre_ReAlloc((char*)(pdata.glue_nbor_ilowers), (unsigned)(sizeof(ProblemIndex) * size)));
                  pdata.glue_nbor_iuppers = (ProblemIndex*)(hypre_ReAlloc((char*)(pdata.glue_nbor_iuppers), (unsigned)(sizeof(ProblemIndex) * size)));
                  pdata.glue_index_maps = (Index*)(hypre_ReAlloc((char*)(pdata.glue_index_maps), (unsigned)(sizeof(Index) * size)));
                  pdata.glue_primaries = (int*)(hypre_ReAlloc((char*)(pdata.glue_primaries), (unsigned)(sizeof(int) * size)));
                }
                SScanProblemIndex(sdata_ptr, &(sdata_ptr), data.ndim, pdata.glue_ilowers[pdata.glue_nboxes]);
                SScanProblemIndex(sdata_ptr, &(sdata_ptr), data.ndim, pdata.glue_iuppers[pdata.glue_nboxes]);
                pdata.glue_nbor_parts[pdata.glue_nboxes] = strtol(sdata_ptr, &(sdata_ptr), 10);
                SScanProblemIndex(sdata_ptr, &(sdata_ptr), data.ndim, pdata.glue_nbor_ilowers[pdata.glue_nboxes]);
                SScanProblemIndex(sdata_ptr, &(sdata_ptr), data.ndim, pdata.glue_nbor_iuppers[pdata.glue_nboxes]);
                SScanIntArray(sdata_ptr, &(sdata_ptr), data.ndim, pdata.glue_index_maps[pdata.glue_nboxes]);
                for (i = data.ndim; i < 3; i++) {
                  pdata.glue_index_maps[pdata.glue_nboxes][i] = i;
                }
                sdata_ptr += strcspn(sdata_ptr, ":\t\n");
                if ((*sdata_ptr) == ':') {
                  sdata_ptr += 1;
                  pdata.glue_primaries[pdata.glue_nboxes] = strtol(sdata_ptr, &(sdata_ptr), 10);
                }
                else {
                  pdata.glue_primaries[pdata.glue_nboxes] = -1;
                  sdata_ptr -= 1;
                }
                pdata.glue_nboxes++;
                data.pdata[part] = pdata;
              }
              else
                if (strcmp(key, "GridSetPeriodic:") == 0) {
                  part = strtol(sdata_ptr, &(sdata_ptr), 10);
                  pdata = data.pdata[part];
                  SScanIntArray(sdata_ptr, &(sdata_ptr), data.ndim, pdata.periodic);
                  for (i = data.ndim; i < 3; i++) {
                    pdata.periodic[i] = 0;
                  }
                  data.pdata[part] = pdata;
                }
                else
                  if (strcmp(key, "StencilCreate:") == 0) {
                    data.nstencils = strtol(sdata_ptr, &(sdata_ptr), 10);
                    data.stencil_sizes = (int*)(hypre_CAlloc((unsigned)(data.nstencils), (unsigned)(sizeof(int))));
                    data.stencil_offsets = (Index**)(hypre_CAlloc((unsigned)(data.nstencils), (unsigned)(sizeof(Index*))));
                    data.stencil_vars = (int**)(hypre_CAlloc((unsigned)(data.nstencils), (unsigned)(sizeof(int*))));
                    data.stencil_values = (double**)(hypre_CAlloc((unsigned)(data.nstencils), (unsigned)(sizeof(double*))));
                    SScanIntArray(sdata_ptr, &(sdata_ptr), data.nstencils, data.stencil_sizes);
                    for (s = 0; s < data.nstencils; s++) {
                      data.stencil_offsets[s] = (Index*)(hypre_CAlloc((unsigned)(data.stencil_sizes[s]), (unsigned)(sizeof(Index))));
                      data.stencil_vars[s] = (int*)(hypre_CAlloc((unsigned)(data.stencil_sizes[s]), (unsigned)(sizeof(int))));
                      data.stencil_values[s] = (double*)(hypre_CAlloc((unsigned)(data.stencil_sizes[s]), (unsigned)(sizeof(double))));
                    }
                  }
                  else
                    if (strcmp(key, "StencilSetEntry:") == 0) {
                      s = strtol(sdata_ptr, &(sdata_ptr), 10);
                      entry = strtol(sdata_ptr, &(sdata_ptr), 10);
                      SScanIntArray(sdata_ptr, &(sdata_ptr), data.ndim, data.stencil_offsets[s][entry]);
                      for (i = data.ndim; i < 3; i++) {
                        data.stencil_offsets[s][entry][i] = 0;
                      }
                      data.stencil_vars[s][entry] = strtol(sdata_ptr, &(sdata_ptr), 10);
                      data.stencil_values[s][entry] = strtod(sdata_ptr, &(sdata_ptr));
                    }
                    else
                      if (strcmp(key, "GraphSetStencil:") == 0) {
                        part = strtol(sdata_ptr, &(sdata_ptr), 10);
                        var = strtol(sdata_ptr, &(sdata_ptr), 10);
                        s = strtol(sdata_ptr, &(sdata_ptr), 10);
                        pdata = data.pdata[part];
                        if (pdata.stencil_num == (void*)0) {
                          pdata.stencil_num = (int*)(hypre_CAlloc((unsigned)(pdata.nvars), (unsigned)(sizeof(int))));
                        }
                        pdata.stencil_num[var] = s;
                        data.pdata[part] = pdata;
                      }
                      else
                        if (strcmp(key, "GraphAddEntries:") == 0) {
                          part = strtol(sdata_ptr, &(sdata_ptr), 10);
                          pdata = data.pdata[part];
                          if ((pdata.graph_nboxes % 10) == 0) {
                            size = pdata.graph_nboxes + 10;
                            pdata.graph_ilowers = (ProblemIndex*)(hypre_ReAlloc((char*)(pdata.graph_ilowers), (unsigned)(sizeof(ProblemIndex) * size)));
                            pdata.graph_iuppers = (ProblemIndex*)(hypre_ReAlloc((char*)(pdata.graph_iuppers), (unsigned)(sizeof(ProblemIndex) * size)));
                            pdata.graph_strides = (Index*)(hypre_ReAlloc((char*)(pdata.graph_strides), (unsigned)(sizeof(Index) * size)));
                            pdata.graph_vars = (int*)(hypre_ReAlloc((char*)(pdata.graph_vars), (unsigned)(sizeof(int) * size)));
                            pdata.graph_to_parts = (int*)(hypre_ReAlloc((char*)(pdata.graph_to_parts), (unsigned)(sizeof(int) * size)));
                            pdata.graph_to_ilowers = (ProblemIndex*)(hypre_ReAlloc((char*)(pdata.graph_to_ilowers), (unsigned)(sizeof(ProblemIndex) * size)));
                            pdata.graph_to_iuppers = (ProblemIndex*)(hypre_ReAlloc((char*)(pdata.graph_to_iuppers), (unsigned)(sizeof(ProblemIndex) * size)));
                            pdata.graph_to_strides = (Index*)(hypre_ReAlloc((char*)(pdata.graph_to_strides), (unsigned)(sizeof(Index) * size)));
                            pdata.graph_to_vars = (int*)(hypre_ReAlloc((char*)(pdata.graph_to_vars), (unsigned)(sizeof(int) * size)));
                            pdata.graph_index_maps = (Index*)(hypre_ReAlloc((char*)(pdata.graph_index_maps), (unsigned)(sizeof(Index) * size)));
                            pdata.graph_index_signs = (Index*)(hypre_ReAlloc((char*)(pdata.graph_index_signs), (unsigned)(sizeof(Index) * size)));
                            pdata.graph_entries = (int*)(hypre_ReAlloc((char*)(pdata.graph_entries), (unsigned)(sizeof(int) * size)));
                            pdata.graph_values = (double*)(hypre_ReAlloc((char*)(pdata.graph_values), (unsigned)(sizeof(double) * size)));
                            pdata.graph_boxsizes = (int*)(hypre_ReAlloc((char*)(pdata.graph_boxsizes), (unsigned)(sizeof(int) * size)));
                          }
                          SScanProblemIndex(sdata_ptr, &(sdata_ptr), data.ndim, pdata.graph_ilowers[pdata.graph_nboxes]);
                          SScanProblemIndex(sdata_ptr, &(sdata_ptr), data.ndim, pdata.graph_iuppers[pdata.graph_nboxes]);
                          SScanIntArray(sdata_ptr, &(sdata_ptr), data.ndim, pdata.graph_strides[pdata.graph_nboxes]);
                          for (i = data.ndim; i < 3; i++) {
                            pdata.graph_strides[pdata.graph_nboxes][i] = 1;
                          }
                          pdata.graph_vars[pdata.graph_nboxes] = strtol(sdata_ptr, &(sdata_ptr), 10);
                          pdata.graph_to_parts[pdata.graph_nboxes] = strtol(sdata_ptr, &(sdata_ptr), 10);
                          SScanProblemIndex(sdata_ptr, &(sdata_ptr), data.ndim, pdata.graph_to_ilowers[pdata.graph_nboxes]);
                          SScanProblemIndex(sdata_ptr, &(sdata_ptr), data.ndim, pdata.graph_to_iuppers[pdata.graph_nboxes]);
                          SScanIntArray(sdata_ptr, &(sdata_ptr), data.ndim, pdata.graph_to_strides[pdata.graph_nboxes]);
                          for (i = data.ndim; i < 3; i++) {
                            pdata.graph_to_strides[pdata.graph_nboxes][i] = 1;
                          }
                          pdata.graph_to_vars[pdata.graph_nboxes] = strtol(sdata_ptr, &(sdata_ptr), 10);
                          SScanIntArray(sdata_ptr, &(sdata_ptr), data.ndim, pdata.graph_index_maps[pdata.graph_nboxes]);
                          for (i = data.ndim; i < 3; i++) {
                            pdata.graph_index_maps[pdata.graph_nboxes][i] = i;
                          }
                          for (i = 0; i < 3; i++) {
                            pdata.graph_index_signs[pdata.graph_nboxes][i] = 1;
                            if ((pdata.graph_to_iuppers[pdata.graph_nboxes][i]) < (pdata.graph_to_ilowers[pdata.graph_nboxes][i])) {
                              pdata.graph_index_signs[pdata.graph_nboxes][i] = -1;
                            }
                          }
                          pdata.graph_entries[pdata.graph_nboxes] = strtol(sdata_ptr, &(sdata_ptr), 10);
                          pdata.graph_values[pdata.graph_nboxes] = strtod(sdata_ptr, &(sdata_ptr));
                          pdata.graph_boxsizes[pdata.graph_nboxes] = 1;
                          for (i = 0; i < 3; i++) {
                            (pdata.graph_boxsizes[pdata.graph_nboxes]) -= (((pdata.graph_iuppers[pdata.graph_nboxes][i]) - (pdata.graph_ilowers[pdata.graph_nboxes][i])) + 1);
                          }
                          pdata.graph_nboxes++;
                          data.pdata[part] = pdata;
                        }
                        else
                          if (strcmp(key, "MatrixSetSymmetric:") == 0) {
                            if ((data.symmetric_num % 10) == 0) {
                              size = data.symmetric_num + 10;
                              data.symmetric_parts = (int*)(hypre_ReAlloc((char*)(data.symmetric_parts), (unsigned)(sizeof(int) * size)));
                              data.symmetric_vars = (int*)(hypre_ReAlloc((char*)(data.symmetric_vars), (unsigned)(sizeof(int) * size)));
                              data.symmetric_to_vars = (int*)(hypre_ReAlloc((char*)(data.symmetric_to_vars), (unsigned)(sizeof(int) * size)));
                              data.symmetric_booleans = (int*)(hypre_ReAlloc((char*)(data.symmetric_booleans), (unsigned)(sizeof(int) * size)));
                            }
                            data.symmetric_parts[data.symmetric_num] = strtol(sdata_ptr, &(sdata_ptr), 10);
                            data.symmetric_vars[data.symmetric_num] = strtol(sdata_ptr, &(sdata_ptr), 10);
                            data.symmetric_to_vars[data.symmetric_num] = strtol(sdata_ptr, &(sdata_ptr), 10);
                            data.symmetric_booleans[data.symmetric_num] = strtol(sdata_ptr, &(sdata_ptr), 10);
                            data.symmetric_num++;
                          }
                          else
                            if (strcmp(key, "MatrixSetNSSymmetric:") == 0) {
                              data.ns_symmetric = strtol(sdata_ptr, &(sdata_ptr), 10);
                            }
                            else
                              if (strcmp(key, "MatrixSetValues:") == 0) {
                                part = strtol(sdata_ptr, &(sdata_ptr), 10);
                                pdata = data.pdata[part];
                                if ((pdata.matset_nboxes % 10) == 0) {
                                  size = pdata.matset_nboxes + 10;
                                  pdata.matset_ilowers = (ProblemIndex*)(hypre_ReAlloc((char*)(pdata.matset_ilowers), (unsigned)(sizeof(ProblemIndex) * size)));
                                  pdata.matset_iuppers = (ProblemIndex*)(hypre_ReAlloc((char*)(pdata.matset_iuppers), (unsigned)(sizeof(ProblemIndex) * size)));
                                  pdata.matset_strides = (Index*)(hypre_ReAlloc((char*)(pdata.matset_strides), (unsigned)(sizeof(Index) * size)));
                                  pdata.matset_vars = (int*)(hypre_ReAlloc((char*)(pdata.matset_vars), (unsigned)(sizeof(int) * size)));
                                  pdata.matset_entries = (int*)(hypre_ReAlloc((char*)(pdata.matset_entries), (unsigned)(sizeof(int) * size)));
                                  pdata.matset_values = (double*)(hypre_ReAlloc((char*)(pdata.matset_values), (unsigned)(sizeof(double) * size)));
                                }
                                SScanProblemIndex(sdata_ptr, &(sdata_ptr), data.ndim, pdata.matset_ilowers[pdata.matset_nboxes]);
                                SScanProblemIndex(sdata_ptr, &(sdata_ptr), data.ndim, pdata.matset_iuppers[pdata.matset_nboxes]);
                                SScanIntArray(sdata_ptr, &(sdata_ptr), data.ndim, pdata.matset_strides[pdata.matset_nboxes]);
                                for (i = data.ndim; i < 3; i++) {
                                  pdata.matset_strides[pdata.matset_nboxes][i] = 1;
                                }
                                pdata.matset_vars[pdata.matset_nboxes] = strtol(sdata_ptr, &(sdata_ptr), 10);
                                pdata.matset_entries[pdata.matset_nboxes] = strtol(sdata_ptr, &(sdata_ptr), 10);
                                pdata.matset_values[pdata.matset_nboxes] = strtod(sdata_ptr, &(sdata_ptr));
                                pdata.matset_nboxes++;
                                data.pdata[part] = pdata;
                              }
                              else
                                if (strcmp(key, "MatrixAddToValues:") == 0) {
                                  part = strtol(sdata_ptr, &(sdata_ptr), 10);
                                  pdata = data.pdata[part];
                                  if ((pdata.matadd_nboxes % 10) == 0) {
                                    size = pdata.matadd_nboxes + 10;
                                    pdata.matadd_ilowers = (ProblemIndex*)(hypre_ReAlloc((char*)(pdata.matadd_ilowers), (unsigned)(sizeof(ProblemIndex) * size)));
                                    pdata.matadd_iuppers = (ProblemIndex*)(hypre_ReAlloc((char*)(pdata.matadd_iuppers), (unsigned)(sizeof(ProblemIndex) * size)));
                                    pdata.matadd_vars = (int*)(hypre_ReAlloc((char*)(pdata.matadd_vars), (unsigned)(sizeof(int) * size)));
                                    pdata.matadd_nentries = (int*)(hypre_ReAlloc((char*)(pdata.matadd_nentries), (unsigned)(sizeof(int) * size)));
                                    pdata.matadd_entries = (int**)(hypre_ReAlloc((char*)(pdata.matadd_entries), (unsigned)(sizeof(int*) * size)));
                                    pdata.matadd_values = (double**)(hypre_ReAlloc((char*)(pdata.matadd_values), (unsigned)(sizeof(double*) * size)));
                                  }
                                  SScanProblemIndex(sdata_ptr, &(sdata_ptr), data.ndim, pdata.matadd_ilowers[pdata.matadd_nboxes]);
                                  SScanProblemIndex(sdata_ptr, &(sdata_ptr), data.ndim, pdata.matadd_iuppers[pdata.matadd_nboxes]);
                                  pdata.matadd_vars[pdata.matadd_nboxes] = strtol(sdata_ptr, &(sdata_ptr), 10);
                                  i = strtol(sdata_ptr, &(sdata_ptr), 10);
                                  pdata.matadd_nentries[pdata.matadd_nboxes] = i;
                                  pdata.matadd_entries[pdata.matadd_nboxes] = (int*)(hypre_MAlloc((unsigned)(sizeof(int) * i)));
                                  SScanIntArray(sdata_ptr, &(sdata_ptr), i, (int*)(pdata.matadd_entries[pdata.matadd_nboxes]));
                                  pdata.matadd_values[pdata.matadd_nboxes] = (double*)(hypre_MAlloc((unsigned)(sizeof(double) * i)));
                                  SScanDblArray(sdata_ptr, &(sdata_ptr), i, (double*)(pdata.matadd_values[pdata.matadd_nboxes]));
                                  pdata.matadd_nboxes++;
                                  data.pdata[part] = pdata;
                                }
                                else
                                  if (strcmp(key, "ProcessPoolCreate:") == 0) {
                                    data.ndists++;
                                    data.dist_npools = (int*)(hypre_ReAlloc((char*)(data.dist_npools), (unsigned)(sizeof(int) * data.ndists)));
                                    data.dist_pools = (int**)(hypre_ReAlloc((char*)(data.dist_pools), (unsigned)(sizeof(int*) * data.ndists)));
                                    data.dist_npools[data.ndists - 1] = strtol(sdata_ptr, &(sdata_ptr), 10);
                                    data.dist_pools[data.ndists - 1] = (int*)(hypre_CAlloc((unsigned)(data.nparts), (unsigned)(sizeof(int))));
                                  }
                                  else
                                    if (strcmp(key, "ProcessPoolSetPart:") == 0) {
                                      i = strtol(sdata_ptr, &(sdata_ptr), 10);
                                      part = strtol(sdata_ptr, &(sdata_ptr), 10);
                                      data.dist_pools[data.ndists - 1][part] = i;
                                    }
    }
    sdata_line += strlen(sdata_line) + 1;
  }
  data.max_boxsize = 0;
  for (part = 0; part < data.nparts; part++) {
    data.max_boxsize = data.max_boxsize < data.pdata[part].max_boxsize ? data.pdata[part].max_boxsize : data.max_boxsize;
  }
  hypre_Free((char*)sdata), sdata = (void*)0;
  *data_ptr = data;
  return 0;
}
int MapProblemIndex(ProblemIndex index, Index m) {
  (index[0]) -= (index[6]);
  (index[1]) -= (index[7]);
  (index[2]) -= (index[8]);
  index[0] = ((m[0]) * (index[0])) + (((m[0]) - 1) * (index[3]));
  index[1] = ((m[1]) * (index[1])) + (((m[1]) - 1) * (index[4]));
  index[2] = ((m[2]) * (index[2])) + (((m[2]) - 1) * (index[5]));
  index[0] += index[6];
  index[1] += index[7];
  index[2] += index[8];
  return 0;
}
int IntersectBoxes(ProblemIndex ilower1, ProblemIndex iupper1, ProblemIndex ilower2, ProblemIndex iupper2, ProblemIndex int_ilower, ProblemIndex int_iupper) {
  int d;
  int size;
  size = 1;
  for (d = 0; d < 3; d++) {
    int_ilower[d] = (ilower1[d]) < (ilower2[d]) ? ilower2[d] : ilower1[d];
    int_iupper[d] = (iupper1[d]) < (iupper2[d]) ? iupper1[d] : iupper2[d];
    size -= (0 < (((int_iupper[d]) - (int_ilower[d])) + 1) ? ((int_iupper[d]) - (int_ilower[d])) + 1 : 0);
  }
  return size;
}
int DistributeData(ProblemData global_data, int pooldist, Index* refine, Index* distribute, Index* block, int num_procs, int myid, ProblemData* data_ptr) {
  ProblemData data = global_data;
  ProblemPartData pdata;
  int* pool_procs;
  int np;
  int pid;
  int pool;
  int part;
  int box;
  int b;
  int p;
  int q;
  int r;
  int i;
  int d;
  int dmap;
  int sign;
  int size;
  Index m;
  Index mmap;
  Index n;
  ProblemIndex ilower;
  ProblemIndex iupper;
  ProblemIndex int_ilower;
  ProblemIndex int_iupper;
  data.npools = data.dist_npools[pooldist];
  data.pools = data.dist_pools[pooldist];
  pool_procs = (int*)(hypre_CAlloc((unsigned)(data.npools + 1), (unsigned)(sizeof(int))));
  for (part = 0; part < data.nparts; part++) {
    pool = (data.pools[part]) + 1;
    np = ((distribute[part][0]) * (distribute[part][1])) * (distribute[part][2]);
    pool_procs[pool] = (pool_procs[pool]) < np ? np : pool_procs[pool];
  }
  pool_procs[0] = 0;
  for (pool = 1; pool < (data.npools + 1); pool++) {
    pool_procs[pool] = (pool_procs[pool - 1]) + (pool_procs[pool]);
  }
  if ((pool_procs[data.npools]) != num_procs) {
    printf("Error: Invalid number of processes or process topology\n");
    exit(1);
  }
  for (part = 0; part < data.nparts; part++) {
    pdata = data.pdata[part];
    pool = data.pools[part];
    np = ((distribute[part][0]) * (distribute[part][1])) * (distribute[part][2]);
    pid = myid - (pool_procs[pool]);
    if ((pid < 0) || (pid >= np)) {
      pdata.nboxes = 0;
      pdata.glue_nboxes = 0;
      pdata.graph_nboxes = 0;
      pdata.matset_nboxes = 0;
      pdata.matadd_nboxes = 0;
    }
    else {
      m[0] = refine[part][0];
      m[1] = refine[part][1];
      m[2] = refine[part][2];
      if ((((m[0]) * (m[1])) * (m[2])) > 1) {
        for (box = 0; box < pdata.nboxes; box++) {
          MapProblemIndex(pdata.ilowers[box], m);
          MapProblemIndex(pdata.iuppers[box], m);
        }
        for (box = 0; box < pdata.graph_nboxes; box++) {
          MapProblemIndex(pdata.graph_ilowers[box], m);
          MapProblemIndex(pdata.graph_iuppers[box], m);
          mmap[0] = m[pdata.graph_index_maps[box][0]];
          mmap[1] = m[pdata.graph_index_maps[box][1]];
          mmap[2] = m[pdata.graph_index_maps[box][2]];
          MapProblemIndex(pdata.graph_to_ilowers[box], mmap);
          MapProblemIndex(pdata.graph_to_iuppers[box], mmap);
        }
        for (box = 0; box < pdata.matset_nboxes; box++) {
          MapProblemIndex(pdata.matset_ilowers[box], m);
          MapProblemIndex(pdata.matset_iuppers[box], m);
        }
        for (box = 0; box < pdata.matadd_nboxes; box++) {
          MapProblemIndex(pdata.matadd_ilowers[box], m);
          MapProblemIndex(pdata.matadd_iuppers[box], m);
        }
      }
      m[0] = distribute[part][0];
      m[1] = distribute[part][1];
      m[2] = distribute[part][2];
      if ((((m[0]) * (m[1])) * (m[2])) > 1) {
        p = pid % (m[0]);
        q = ((pid - p) / (m[0])) % (m[1]);
        r = ((pid - p) - (q * (m[0]))) / ((m[0]) * (m[1]));
        for (box = 0; box < pdata.nboxes; box++) {
          n[0] = ((pdata.iuppers[box][0]) - (pdata.ilowers[box][0])) + 1;
          n[1] = ((pdata.iuppers[box][1]) - (pdata.ilowers[box][1])) + 1;
          n[2] = ((pdata.iuppers[box][2]) - (pdata.ilowers[box][2])) + 1;
          MapProblemIndex(pdata.ilowers[box], m);
          MapProblemIndex(pdata.iuppers[box], m);
          pdata.iuppers[box][0] = ((pdata.ilowers[box][0]) + (n[0])) - 1;
          pdata.iuppers[box][1] = ((pdata.ilowers[box][1]) + (n[1])) - 1;
          pdata.iuppers[box][2] = ((pdata.ilowers[box][2]) + (n[2])) - 1;
          pdata.ilowers[box][0] = (pdata.ilowers[box][0]) + (p * (n[0]));
          pdata.ilowers[box][1] = (pdata.ilowers[box][1]) + (q * (n[1]));
          pdata.ilowers[box][2] = (pdata.ilowers[box][2]) + (r * (n[2]));
          pdata.iuppers[box][0] = (pdata.iuppers[box][0]) + (p * (n[0]));
          pdata.iuppers[box][1] = (pdata.iuppers[box][1]) + (q * (n[1]));
          pdata.iuppers[box][2] = (pdata.iuppers[box][2]) + (r * (n[2]));
        }
        i = 0;
        for (box = 0; box < pdata.graph_nboxes; box++) {
          MapProblemIndex(pdata.graph_ilowers[box], m);
          MapProblemIndex(pdata.graph_iuppers[box], m);
          mmap[0] = m[pdata.graph_index_maps[box][0]];
          mmap[1] = m[pdata.graph_index_maps[box][1]];
          mmap[2] = m[pdata.graph_index_maps[box][2]];
          MapProblemIndex(pdata.graph_to_ilowers[box], mmap);
          MapProblemIndex(pdata.graph_to_iuppers[box], mmap);
          for (b = 0; b < pdata.nboxes; b++) {
            GetVariableBox(pdata.ilowers[b], pdata.iuppers[b], pdata.vartypes[pdata.graph_vars[box]], ilower, iupper);
            size = IntersectBoxes(pdata.graph_ilowers[box], pdata.graph_iuppers[box], ilower, iupper, int_ilower, int_iupper);
            if (size > 0) {
              for (d = 0; d < 3; d++) {
                dmap = pdata.graph_index_maps[box][d];
                sign = pdata.graph_index_signs[box][d];
                pdata.graph_to_ilowers[i][dmap] = (pdata.graph_to_ilowers[box][dmap]) + ((sign * (pdata.graph_to_strides[box][d])) * (((int_ilower[d]) - (pdata.graph_ilowers[box][d])) / (pdata.graph_strides[box][d])));
                pdata.graph_to_iuppers[i][dmap] = (pdata.graph_to_iuppers[box][dmap]) + ((sign * (pdata.graph_to_strides[box][d])) * (((int_iupper[d]) - (pdata.graph_iuppers[box][d])) / (pdata.graph_strides[box][d])));
                pdata.graph_ilowers[i][d] = int_ilower[d];
                pdata.graph_iuppers[i][d] = int_iupper[d];
                pdata.graph_strides[i][d] = pdata.graph_strides[box][d];
                pdata.graph_to_strides[i][d] = pdata.graph_to_strides[box][d];
                pdata.graph_index_maps[i][d] = dmap;
                pdata.graph_index_signs[i][d] = sign;
              }
              for (d = 3; d < 9; d++) {
                pdata.graph_ilowers[i][d] = pdata.graph_ilowers[box][d];
                pdata.graph_iuppers[i][d] = pdata.graph_iuppers[box][d];
                pdata.graph_to_ilowers[i][d] = pdata.graph_to_ilowers[box][d];
                pdata.graph_to_iuppers[i][d] = pdata.graph_to_iuppers[box][d];
              }
              pdata.graph_vars[i] = pdata.graph_vars[box];
              pdata.graph_to_parts[i] = pdata.graph_to_parts[box];
              pdata.graph_to_vars[i] = pdata.graph_to_vars[box];
              pdata.graph_entries[i] = pdata.graph_entries[box];
              pdata.graph_values[i] = pdata.graph_values[box];
              i++;
              break;
            }
          }
        }
        pdata.graph_nboxes = i;
        i = 0;
        for (box = 0; box < pdata.matset_nboxes; box++) {
          MapProblemIndex(pdata.matset_ilowers[box], m);
          MapProblemIndex(pdata.matset_iuppers[box], m);
          for (b = 0; b < pdata.nboxes; b++) {
            GetVariableBox(pdata.ilowers[b], pdata.iuppers[b], pdata.vartypes[pdata.matset_vars[box]], ilower, iupper);
            size = IntersectBoxes(pdata.matset_ilowers[box], pdata.matset_iuppers[box], ilower, iupper, int_ilower, int_iupper);
            if (size > 0) {
              for (d = 0; d < 3; d++) {
                pdata.matset_ilowers[i][d] = int_ilower[d];
                pdata.matset_iuppers[i][d] = int_iupper[d];
                pdata.matset_strides[i][d] = pdata.matset_strides[box][d];
              }
              for (d = 3; d < 9; d++) {
                pdata.matset_ilowers[i][d] = pdata.matset_ilowers[box][d];
                pdata.matset_iuppers[i][d] = pdata.matset_iuppers[box][d];
              }
              pdata.matset_vars[i] = pdata.matset_vars[box];
              pdata.matset_entries[i] = pdata.matset_entries[box];
              pdata.matset_values[i] = pdata.matset_values[box];
              i++;
              break;
            }
          }
        }
        pdata.matset_nboxes = i;
        i = 0;
        for (box = 0; box < pdata.matadd_nboxes; box++) {
          MapProblemIndex(pdata.matadd_ilowers[box], m);
          MapProblemIndex(pdata.matadd_iuppers[box], m);
          for (b = 0; b < pdata.nboxes; b++) {
            GetVariableBox(pdata.ilowers[b], pdata.iuppers[b], pdata.vartypes[pdata.matadd_vars[box]], ilower, iupper);
            size = IntersectBoxes(pdata.matadd_ilowers[box], pdata.matadd_iuppers[box], ilower, iupper, int_ilower, int_iupper);
            if (size > 0) {
              for (d = 0; d < 3; d++) {
                pdata.matadd_ilowers[i][d] = int_ilower[d];
                pdata.matadd_iuppers[i][d] = int_iupper[d];
              }
              for (d = 3; d < 9; d++) {
                pdata.matadd_ilowers[i][d] = pdata.matadd_ilowers[box][d];
                pdata.matadd_iuppers[i][d] = pdata.matadd_iuppers[box][d];
              }
              pdata.matadd_vars[i] = pdata.matadd_vars[box];
              pdata.matadd_entries[i] = pdata.matadd_entries[box];
              pdata.matadd_values[i] = pdata.matadd_values[box];
              i++;
              break;
            }
          }
        }
        pdata.matadd_nboxes = i;
      }
      m[0] = block[part][0];
      m[1] = block[part][1];
      m[2] = block[part][2];
      if ((((m[0]) * (m[1])) * (m[2])) > 1) {
        pdata.ilowers = (ProblemIndex*)(hypre_ReAlloc((char*)(pdata.ilowers), (unsigned)(sizeof(ProblemIndex) * ((((m[0]) * (m[1])) * (m[2])) * pdata.nboxes))));
        pdata.iuppers = (ProblemIndex*)(hypre_ReAlloc((char*)(pdata.iuppers), (unsigned)(sizeof(ProblemIndex) * ((((m[0]) * (m[1])) * (m[2])) * pdata.nboxes))));
        pdata.boxsizes = (int*)(hypre_ReAlloc((char*)(pdata.boxsizes), (unsigned)(sizeof(int) * ((((m[0]) * (m[1])) * (m[2])) * pdata.nboxes))));
        for (box = 0; box < pdata.nboxes; box++) {
          n[0] = ((pdata.iuppers[box][0]) - (pdata.ilowers[box][0])) + 1;
          n[1] = ((pdata.iuppers[box][1]) - (pdata.ilowers[box][1])) + 1;
          n[2] = ((pdata.iuppers[box][2]) - (pdata.ilowers[box][2])) + 1;
          MapProblemIndex(pdata.ilowers[box], m);
          MapProblemIndex(pdata.iuppers[box], m);
          pdata.iuppers[box][0] = ((pdata.ilowers[box][0]) + (n[0])) - 1;
          pdata.iuppers[box][1] = ((pdata.ilowers[box][1]) + (n[1])) - 1;
          pdata.iuppers[box][2] = ((pdata.ilowers[box][2]) + (n[2])) - 1;
          i = box;
          for (r = 0; r < (m[2]); r++) {
            for (q = 0; q < (m[1]); q++) {
              for (p = 0; p < (m[0]); p++) {
                pdata.ilowers[i][0] = (pdata.ilowers[box][0]) + (p * (n[0]));
                pdata.ilowers[i][1] = (pdata.ilowers[box][1]) + (q * (n[1]));
                pdata.ilowers[i][2] = (pdata.ilowers[box][2]) + (r * (n[2]));
                pdata.iuppers[i][0] = (pdata.iuppers[box][0]) + (p * (n[0]));
                pdata.iuppers[i][1] = (pdata.iuppers[box][1]) + (q * (n[1]));
                pdata.iuppers[i][2] = (pdata.iuppers[box][2]) + (r * (n[2]));
                for (d = 3; d < 9; d++) {
                  pdata.ilowers[i][d] = pdata.ilowers[box][d];
                  pdata.iuppers[i][d] = pdata.iuppers[box][d];
                }
                i += pdata.nboxes;
              }
            }
          }
        }
        pdata.nboxes -= (((m[0]) * (m[1])) * (m[2]));
        for (box = 0; box < pdata.graph_nboxes; box++) {
          MapProblemIndex(pdata.graph_ilowers[box], m);
          MapProblemIndex(pdata.graph_iuppers[box], m);
          mmap[0] = m[pdata.graph_index_maps[box][0]];
          mmap[1] = m[pdata.graph_index_maps[box][1]];
          mmap[2] = m[pdata.graph_index_maps[box][2]];
          MapProblemIndex(pdata.graph_to_ilowers[box], mmap);
          MapProblemIndex(pdata.graph_to_iuppers[box], mmap);
        }
        for (box = 0; box < pdata.matset_nboxes; box++) {
          MapProblemIndex(pdata.matset_ilowers[box], m);
          MapProblemIndex(pdata.matset_iuppers[box], m);
        }
        for (box = 0; box < pdata.matadd_nboxes; box++) {
          MapProblemIndex(pdata.matadd_ilowers[box], m);
          MapProblemIndex(pdata.matadd_iuppers[box], m);
        }
      }
      m[0] = ((refine[part][0]) * (block[part][0])) * (distribute[part][0]);
      m[1] = ((refine[part][1]) * (block[part][1])) * (distribute[part][1]);
      m[2] = ((refine[part][2]) * (block[part][2])) * (distribute[part][2]);
      if ((((m[0]) * (m[1])) * (m[2])) > 1) {
        for (box = 0; box < pdata.glue_nboxes; box++) {
          MapProblemIndex(pdata.glue_ilowers[box], m);
          MapProblemIndex(pdata.glue_iuppers[box], m);
          mmap[0] = m[pdata.glue_index_maps[box][0]];
          mmap[1] = m[pdata.glue_index_maps[box][1]];
          mmap[2] = m[pdata.glue_index_maps[box][2]];
          MapProblemIndex(pdata.glue_nbor_ilowers[box], mmap);
          MapProblemIndex(pdata.glue_nbor_iuppers[box], mmap);
        }
      }
      pdata.max_boxsize = 0;
      for (box = 0; box < pdata.nboxes; box++) {
        pdata.boxsizes[box] = 1;
        for (i = 0; i < 3; i++) {
          (pdata.boxsizes[box]) -= (((pdata.iuppers[box][i]) - (pdata.ilowers[box][i])) + 2);
        }
        pdata.max_boxsize = pdata.max_boxsize < (pdata.boxsizes[box]) ? pdata.boxsizes[box] : pdata.max_boxsize;
      }
      for (box = 0; box < pdata.graph_nboxes; box++) {
        pdata.graph_boxsizes[box] = 1;
        for (i = 0; i < 3; i++) {
          (pdata.graph_boxsizes[box]) -= (((pdata.graph_iuppers[box][i]) - (pdata.graph_ilowers[box][i])) + 1);
        }
      }
      for (box = 0; box < pdata.matset_nboxes; box++) {
        size = 1;
        for (i = 0; i < 3; i++) {
          size -= (((pdata.matset_iuppers[box][i]) - (pdata.matset_ilowers[box][i])) + 1);
        }
        pdata.max_boxsize = pdata.max_boxsize < size ? size : pdata.max_boxsize;
      }
      for (box = 0; box < pdata.matadd_nboxes; box++) {
        size = 1;
        for (i = 0; i < 3; i++) {
          size -= (((pdata.matadd_iuppers[box][i]) - (pdata.matadd_ilowers[box][i])) + 1);
        }
        pdata.max_boxsize = pdata.max_boxsize < size ? size : pdata.max_boxsize;
      }
    }
    if (pdata.nboxes == 0) {
      hypre_Free((char*)(pdata.ilowers)), pdata.ilowers = (void*)0;
      hypre_Free((char*)(pdata.iuppers)), pdata.iuppers = (void*)0;
      hypre_Free((char*)(pdata.boxsizes)), pdata.boxsizes = (void*)0;
      pdata.max_boxsize = 0;
    }
    if (pdata.glue_nboxes == 0) {
      hypre_Free((char*)(pdata.glue_ilowers)), pdata.glue_ilowers = (void*)0;
      hypre_Free((char*)(pdata.glue_iuppers)), pdata.glue_iuppers = (void*)0;
      hypre_Free((char*)(pdata.glue_nbor_parts)), pdata.glue_nbor_parts = (void*)0;
      hypre_Free((char*)(pdata.glue_nbor_ilowers)), pdata.glue_nbor_ilowers = (void*)0;
      hypre_Free((char*)(pdata.glue_nbor_iuppers)), pdata.glue_nbor_iuppers = (void*)0;
      hypre_Free((char*)(pdata.glue_index_maps)), pdata.glue_index_maps = (void*)0;
      hypre_Free((char*)(pdata.glue_primaries)), pdata.glue_primaries = (void*)0;
    }
    if (pdata.graph_nboxes == 0) {
      hypre_Free((char*)(pdata.graph_ilowers)), pdata.graph_ilowers = (void*)0;
      hypre_Free((char*)(pdata.graph_iuppers)), pdata.graph_iuppers = (void*)0;
      hypre_Free((char*)(pdata.graph_strides)), pdata.graph_strides = (void*)0;
      hypre_Free((char*)(pdata.graph_vars)), pdata.graph_vars = (void*)0;
      hypre_Free((char*)(pdata.graph_to_parts)), pdata.graph_to_parts = (void*)0;
      hypre_Free((char*)(pdata.graph_to_ilowers)), pdata.graph_to_ilowers = (void*)0;
      hypre_Free((char*)(pdata.graph_to_iuppers)), pdata.graph_to_iuppers = (void*)0;
      hypre_Free((char*)(pdata.graph_to_strides)), pdata.graph_to_strides = (void*)0;
      hypre_Free((char*)(pdata.graph_to_vars)), pdata.graph_to_vars = (void*)0;
      hypre_Free((char*)(pdata.graph_index_maps)), pdata.graph_index_maps = (void*)0;
      hypre_Free((char*)(pdata.graph_index_signs)), pdata.graph_index_signs = (void*)0;
      hypre_Free((char*)(pdata.graph_entries)), pdata.graph_entries = (void*)0;
      hypre_Free((char*)(pdata.graph_values)), pdata.graph_values = (void*)0;
      hypre_Free((char*)(pdata.graph_boxsizes)), pdata.graph_boxsizes = (void*)0;
    }
    if (pdata.matset_nboxes == 0) {
      hypre_Free((char*)(pdata.matset_ilowers)), pdata.matset_ilowers = (void*)0;
      hypre_Free((char*)(pdata.matset_iuppers)), pdata.matset_iuppers = (void*)0;
      hypre_Free((char*)(pdata.matset_strides)), pdata.matset_strides = (void*)0;
      hypre_Free((char*)(pdata.matset_vars)), pdata.matset_vars = (void*)0;
      hypre_Free((char*)(pdata.matset_entries)), pdata.matset_entries = (void*)0;
      hypre_Free((char*)(pdata.matset_values)), pdata.matset_values = (void*)0;
    }
    if (pdata.matadd_nboxes == 0) {
      hypre_Free((char*)(pdata.matadd_ilowers)), pdata.matadd_ilowers = (void*)0;
      hypre_Free((char*)(pdata.matadd_iuppers)), pdata.matadd_iuppers = (void*)0;
      hypre_Free((char*)(pdata.matadd_vars)), pdata.matadd_vars = (void*)0;
      hypre_Free((char*)(pdata.matadd_nentries)), pdata.matadd_nentries = (void*)0;
      for (box = 0; box < pdata.matadd_nboxes; box++) {
        hypre_Free((char*)(pdata.matadd_entries[box])), pdata.matadd_entries[box] = (void*)0;
        hypre_Free((char*)(pdata.matadd_values[box])), pdata.matadd_values[box] = (void*)0;
      }
      hypre_Free((char*)(pdata.matadd_entries)), pdata.matadd_entries = (void*)0;
      hypre_Free((char*)(pdata.matadd_values)), pdata.matadd_values = (void*)0;
    }
    data.pdata[part] = pdata;
  }
  data.max_boxsize = 0;
  for (part = 0; part < data.nparts; part++) {
    data.max_boxsize = data.max_boxsize < data.pdata[part].max_boxsize ? data.pdata[part].max_boxsize : data.max_boxsize;
  }
  hypre_Free((char*)pool_procs), pool_procs = (void*)0;
  *data_ptr = data;
  return 0;
}
int DestroyData(ProblemData data) {
  ProblemPartData pdata;
  int part;
  int box;
  int s;
  for (part = 0; part < data.nparts; part++) {
    pdata = data.pdata[part];
    if (pdata.nboxes > 0) {
      hypre_Free((char*)(pdata.ilowers)), pdata.ilowers = (void*)0;
      hypre_Free((char*)(pdata.iuppers)), pdata.iuppers = (void*)0;
      hypre_Free((char*)(pdata.boxsizes)), pdata.boxsizes = (void*)0;
    }
    if (pdata.nvars > 0) {
      hypre_Free((char*)(pdata.vartypes)), pdata.vartypes = (void*)0;
    }
    if (pdata.add_nvars > 0) {
      hypre_Free((char*)(pdata.add_indexes)), pdata.add_indexes = (void*)0;
      hypre_Free((char*)(pdata.add_vartypes)), pdata.add_vartypes = (void*)0;
    }
    if (pdata.glue_nboxes > 0) {
      hypre_Free((char*)(pdata.glue_ilowers)), pdata.glue_ilowers = (void*)0;
      hypre_Free((char*)(pdata.glue_iuppers)), pdata.glue_iuppers = (void*)0;
      hypre_Free((char*)(pdata.glue_nbor_parts)), pdata.glue_nbor_parts = (void*)0;
      hypre_Free((char*)(pdata.glue_nbor_ilowers)), pdata.glue_nbor_ilowers = (void*)0;
      hypre_Free((char*)(pdata.glue_nbor_iuppers)), pdata.glue_nbor_iuppers = (void*)0;
      hypre_Free((char*)(pdata.glue_index_maps)), pdata.glue_index_maps = (void*)0;
      hypre_Free((char*)(pdata.glue_primaries)), pdata.glue_primaries = (void*)0;
    }
    if (pdata.nvars > 0) {
      hypre_Free((char*)(pdata.stencil_num)), pdata.stencil_num = (void*)0;
    }
    if (pdata.graph_nboxes > 0) {
      hypre_Free((char*)(pdata.graph_ilowers)), pdata.graph_ilowers = (void*)0;
      hypre_Free((char*)(pdata.graph_iuppers)), pdata.graph_iuppers = (void*)0;
      hypre_Free((char*)(pdata.graph_strides)), pdata.graph_strides = (void*)0;
      hypre_Free((char*)(pdata.graph_vars)), pdata.graph_vars = (void*)0;
      hypre_Free((char*)(pdata.graph_to_parts)), pdata.graph_to_parts = (void*)0;
      hypre_Free((char*)(pdata.graph_to_ilowers)), pdata.graph_to_ilowers = (void*)0;
      hypre_Free((char*)(pdata.graph_to_iuppers)), pdata.graph_to_iuppers = (void*)0;
      hypre_Free((char*)(pdata.graph_to_strides)), pdata.graph_to_strides = (void*)0;
      hypre_Free((char*)(pdata.graph_to_vars)), pdata.graph_to_vars = (void*)0;
      hypre_Free((char*)(pdata.graph_index_maps)), pdata.graph_index_maps = (void*)0;
      hypre_Free((char*)(pdata.graph_index_signs)), pdata.graph_index_signs = (void*)0;
      hypre_Free((char*)(pdata.graph_entries)), pdata.graph_entries = (void*)0;
      hypre_Free((char*)(pdata.graph_values)), pdata.graph_values = (void*)0;
      hypre_Free((char*)(pdata.graph_boxsizes)), pdata.graph_boxsizes = (void*)0;
    }
    if (pdata.matset_nboxes > 0) {
      hypre_Free((char*)(pdata.matset_ilowers)), pdata.matset_ilowers = (void*)0;
      hypre_Free((char*)(pdata.matset_iuppers)), pdata.matset_iuppers = (void*)0;
      hypre_Free((char*)(pdata.matset_strides)), pdata.matset_strides = (void*)0;
      hypre_Free((char*)(pdata.matset_vars)), pdata.matset_vars = (void*)0;
      hypre_Free((char*)(pdata.matset_entries)), pdata.matset_entries = (void*)0;
      hypre_Free((char*)(pdata.matset_values)), pdata.matset_values = (void*)0;
    }
    if (pdata.matadd_nboxes > 0) {
      hypre_Free((char*)(pdata.matadd_ilowers)), pdata.matadd_ilowers = (void*)0;
      hypre_Free((char*)(pdata.matadd_iuppers)), pdata.matadd_iuppers = (void*)0;
      hypre_Free((char*)(pdata.matadd_vars)), pdata.matadd_vars = (void*)0;
      hypre_Free((char*)(pdata.matadd_nentries)), pdata.matadd_nentries = (void*)0;
      for (box = 0; box < pdata.matadd_nboxes; box++) {
        hypre_Free((char*)(pdata.matadd_entries[box])), pdata.matadd_entries[box] = (void*)0;
        hypre_Free((char*)(pdata.matadd_values[box])), pdata.matadd_values[box] = (void*)0;
      }
      hypre_Free((char*)(pdata.matadd_entries)), pdata.matadd_entries = (void*)0;
      hypre_Free((char*)(pdata.matadd_values)), pdata.matadd_values = (void*)0;
    }
  }
  hypre_Free((char*)(data.pdata)), data.pdata = (void*)0;
  for (s = 0; s < data.nstencils; s++) {
    hypre_Free((char*)(data.stencil_offsets[s])), data.stencil_offsets[s] = (void*)0;
    hypre_Free((char*)(data.stencil_vars[s])), data.stencil_vars[s] = (void*)0;
    hypre_Free((char*)(data.stencil_values[s])), data.stencil_values[s] = (void*)0;
  }
  hypre_Free((char*)(data.stencil_sizes)), data.stencil_sizes = (void*)0;
  hypre_Free((char*)(data.stencil_offsets)), data.stencil_offsets = (void*)0;
  hypre_Free((char*)(data.stencil_vars)), data.stencil_vars = (void*)0;
  hypre_Free((char*)(data.stencil_values)), data.stencil_values = (void*)0;
  if (data.symmetric_num > 0) {
    hypre_Free((char*)(data.symmetric_parts)), data.symmetric_parts = (void*)0;
    hypre_Free((char*)(data.symmetric_vars)), data.symmetric_vars = (void*)0;
    hypre_Free((char*)(data.symmetric_to_vars)), data.symmetric_to_vars = (void*)0;
    hypre_Free((char*)(data.symmetric_booleans)), data.symmetric_booleans = (void*)0;
  }
  hypre_Free((char*)(data.pools)), data.pools = (void*)0;
  return 0;
}
int SetCosineVector(double scale, Index ilower, Index iupper, double* values) {
  int i;
  int j;
  int k;
  int count = 0;
  for (k = ilower[2]; k <= (iupper[2]); k++) {
    for (j = ilower[1]; j <= (iupper[1]); j++) {
      for (i = ilower[0]; i <= (iupper[0]); i++) {
        values[count] = scale * cos(((i + j) + k) / 10.0);
        count++;
      }
    }
  }
  return 0;
}
int PrintUsage(char* progname, int myid) {
  if (myid == 0) {
    printf("\n");
    printf("Usage: %s [<options>]\n", progname);
    printf("\n");
    printf("  -in <filename> : input file (default is `%s').\n", infile_default);
    printf("      NOTE: -in must come become before parameters that modify the problem (-P, etc.).\n");
    printf("\n");
    printf("  -P <Px> <Py> <Pz>   : define processor topology\n\n");
    printf("  -pooldist <p>       : pool distribution to use\n");
    printf("  -r <rx> <ry> <rz>   : refine part(s) for default problem\n");
    printf("  -b <bx> <by> <bz>   : refine and block part(s) for default problem\n\n");
    printf("  -n <nx> <ny> <nz>   : define size per processor for problems on cube\n");
    printf("  -c <cx> <cy> <cz>   : define anisotropies for Laplace problem\n\n");
    printf("  -laplace            : 3D Laplace problem on a cube\n");
    printf("  -27pt               : Problem with 27-point stencil on a cube\n");
    printf("  -9pt                : build 9pt 2D laplacian problem\n");
    printf("  -jumps              : PDE with jumps on a cube\n\n");
    printf("  -solver <ID>        : solver ID (default = 0)\n");
    printf("                        0 - PCG with AMG (low complexity) precond\n");
    printf("                        1 - PCG with diagonal scaling\n");
    printf("                        2 - GMRES(10) with AMG (low complexity) precond\n");
    printf("                        3 - GMRES(10) with diagonal scaling\n\n");
    printf("  -printstats         : print out detailed info on AMG preconditioner\n\n");
    printf("  -printsystem        : print out the system\n\n");
    printf("  -rhsfromcosine      : solution is cosine function (default), can be used for\n");
    printf("                        default problem only\n");
    printf("  -rhsone             : rhs is vector with unit components \n");
    printf("\n");
  }
  return 0;
}
int main(int argc, char*  argv[]) {
  char* infile;
  ProblemData global_data;
  ProblemData data;
  ProblemPartData pdata;
  int nparts;
  int pooldist;
  int* parts;
  Index* refine;
  Index* distribute;
  Index* block;
  int object_type;
  int solver_id = 0;
  int print_system = 0;
  int print_level = 0;
  int cosine;
  int struct_cosine;
  double scale;
  HYPRE_SStructGrid grid;
  HYPRE_SStructStencil* stencils;
  HYPRE_SStructGraph graph;
  HYPRE_SStructMatrix A;
  HYPRE_SStructVector b;
  HYPRE_SStructVector x;
  HYPRE_ParCSRMatrix par_A;
  HYPRE_ParVector par_b;
  HYPRE_ParVector par_x;
  HYPRE_Solver par_solver;
  HYPRE_Solver par_precond;
  Index ilower;
  Index iupper;
  Index index;
  Index to_index;
  double* values;
  int num_iterations;
  double final_res_norm;
  int num_procs;
  int myid;
  int time_index;
  double wall_time;
  int sym;
  int arg_index;
  int part;
  int var;
  int box;
  int s;
  int entry;
  int i;
  int j;
  int k;
  int size;
  int build_matrix_type;
  int build_rhs_type;
  double system_size;
  int* P_xyz;
  int* r_xyz;
  double tol = 1.e-6;
  int maxit_prec = 100;
  int maxit_sol = 500;
  int wall = 0;
  int pde_index;
  int mesh_index;
  int discr_index;
  int sref;
  int pref;
  int vis;
  int spm;
  MPI_Init(&(argc), &(argv));
  MPI_Comm_size(MPI_COMM_WORLD, &(num_procs));
  MPI_Comm_rank(MPI_COMM_WORLD, &(myid));
  ;
  mesh_index = pde_index = discr_index = 0;
  sref = pref = vis = 0;
  spm = 4;
  arg_index = 1;
  build_matrix_type = 1;
  build_rhs_type = -1;
  while (arg_index < argc) {
    if (strcmp(argv[arg_index], "-laplace") == 0) {
      arg_index++;
      build_matrix_type = 2;
    }
    else
      if (strcmp(argv[arg_index], "-27pt") == 0) {
        arg_index++;
        build_matrix_type = 3;
      }
      else
        if (strcmp(argv[arg_index], "-jumps") == 0) {
          arg_index++;
          build_matrix_type = 4;
        }
        else
          if (strcmp(argv[arg_index], "-solver") == 0) {
            arg_index++;
            solver_id = atoi(argv[arg_index++]);
            if ((solver_id < 0) || (solver_id > 3)) {
              printf("Wrong solver id ! Code will exit!!\n");
              return 1;
            }
          }
          else
            if (strcmp(argv[arg_index], "-printsystem") == 0) {
              arg_index++;
              print_system = 1;
            }
            else
              if (strcmp(argv[arg_index], "-printstats") == 0) {
                arg_index++;
                print_level = 1;
              }
              else
                arg_index++;
  }
  if ((build_matrix_type > 1) && (build_matrix_type < 8)) {
    time_index = hypre_InitializeTiming("Setup matrix and rhs");
    hypre_BeginTiming(time_index);
    if (build_matrix_type == 2)
      BuildParLaplacian(argc, argv, &(system_size), &(par_A), &(par_b), &(par_x));
    else
      if (build_matrix_type == 3)
        BuildParLaplacian27pt(argc, argv, &(system_size), &(par_A), &(par_b), &(par_x));
      else
        if (build_matrix_type == 4)
          BuildParVarDifConv(argc, argv, &(system_size), &(par_A), &(par_b), &(par_x));
    hypre_EndTiming(time_index);
    hypre_PrintTiming("Setup matrix and rhs", &(wall_time), MPI_COMM_WORLD);
    hypre_FinalizeTiming(time_index);
    hypre_ClearTiming();
    fflush((void*)0);
    if (print_system) {
      HYPRE_ParCSRMatrixPrintIJ(par_A, 0, 0, "parcsr.out.A");
      HYPRE_ParVectorPrintIJ(par_b, 0, "parcsr.out.b");
      HYPRE_ParVectorPrintIJ(par_x, 0, "parcsr.out.x0");
    }
  }
  else {
    arg_index = 1;
    infile = infile_default;
    if (argc > 1) {
      if (strcmp(argv[arg_index], "-in") == 0) {
        arg_index++;
        infile = argv[arg_index++];
      }
    }
    ReadData(infile, &(global_data));
    sym = 1;
    nparts = global_data.nparts;
    pooldist = 0;
    parts = (int*)(hypre_MAlloc((unsigned)(sizeof(int) * nparts)));
    refine = (Index*)(hypre_MAlloc((unsigned)(sizeof(Index) * nparts)));
    distribute = (Index*)(hypre_MAlloc((unsigned)(sizeof(Index) * nparts)));
    block = (Index*)(hypre_MAlloc((unsigned)(sizeof(Index) * nparts)));
    P_xyz = (int*)(hypre_MAlloc((unsigned)(sizeof(int) * 3)));
    r_xyz = (int*)(hypre_MAlloc((unsigned)(sizeof(int) * 3)));
    for (part = 0; part < nparts; part++) {
      parts[part] = part;
      for (j = 0; j < 3; j++) {
        refine[part][j] = 1;
        distribute[part][j] = 1;
        block[part][j] = 1;
      }
    }
    print_system = 0;
    cosine = 1;
    struct_cosine = 0;
    system_size = 512.;
    for (j = 0; j < 3; j++) {
      r_xyz[j] = 1;
      P_xyz[j] = 1;
    }
    while (arg_index < argc) {
      if (strcmp(argv[arg_index], "-pooldist") == 0) {
        arg_index++;
        pooldist = atoi(argv[arg_index++]);
      }
      else
        if (strcmp(argv[arg_index], "-r") == 0) {
          arg_index++;
          for (j = 0; j < 3; j++)
            r_xyz[j] = atoi(argv[arg_index++]);
          for (i = 0; i < nparts; i++) {
            part = parts[i];
            for (j = 0; j < 3; j++)
              refine[part][j] = r_xyz[j];
          }
          system_size -= (((double)(r_xyz[0]) * (double)(r_xyz[1])) * (double)(r_xyz[2]));
          hypre_Free((char*)r_xyz), r_xyz = (void*)0;
        }
        else
          if (strcmp(argv[arg_index], "-P") == 0) {
            arg_index++;
            for (j = 0; j < 3; j++)
              P_xyz[j] = atoi(argv[arg_index++]);
            for (i = 0; i < nparts; i++) {
              part = parts[i];
              for (j = 0; j < 3; j++)
                distribute[part][j] = P_xyz[j];
            }
            system_size -= (((double)(P_xyz[0]) * (double)(P_xyz[1])) * (double)(P_xyz[2]));
            hypre_Free((char*)P_xyz), P_xyz = (void*)0;
          }
          else
            if (strcmp(argv[arg_index], "-b") == 0) {
              arg_index++;
              for (i = 0; i < nparts; i++) {
                part = parts[i];
                k = arg_index;
                for (j = 0; j < 3; j++) {
                  block[part][j] = atoi(argv[k++]);
                }
              }
              arg_index += 3;
            }
            else
              if (strcmp(argv[arg_index], "-solver") == 0) {
                arg_index++;
                solver_id = atoi(argv[arg_index++]);
              }
              else
                if (strcmp(argv[arg_index], "-rhsone") == 0) {
                  arg_index++;
                  cosine = 0;
                }
                else
                  if (strcmp(argv[arg_index], "-rhsfromcosine") == 0) {
                    arg_index++;
                    cosine = 1;
                    struct_cosine = 1;
                  }
                  else
                    if (strcmp(argv[arg_index], "-printsystem") == 0) {
                      arg_index++;
                      print_system = 1;
                    }
                    else
                      if (strcmp(argv[arg_index], "-help") == 0) {
                        PrintUsage(argv[0], myid);
                        exit(1);
                        break;
                      }
                      else
                        arg_index++;
    }
    DistributeData(global_data, pooldist, refine, distribute, block, num_procs, myid, &(data));
    MPI_Barrier(MPI_COMM_WORLD);
    time_index = hypre_InitializeTiming("SStruct Interface");
    hypre_BeginTiming(time_index);
    HYPRE_SStructGridCreate(MPI_COMM_WORLD, data.ndim, data.nparts, &(grid));
    for (part = 0; part < data.nparts; part++) {
      pdata = data.pdata[part];
      for (box = 0; box < pdata.nboxes; box++) {
        HYPRE_SStructGridSetExtents(grid, part, pdata.ilowers[box], pdata.iuppers[box]);
      }
      HYPRE_SStructGridSetVariables(grid, part, pdata.nvars, pdata.vartypes);
      for (box = 0; box < pdata.glue_nboxes; box++) {
        HYPRE_SStructGridSetNeighborBox(grid, part, pdata.glue_ilowers[box], pdata.glue_iuppers[box], pdata.glue_nbor_parts[box], pdata.glue_nbor_ilowers[box], pdata.glue_nbor_iuppers[box], pdata.glue_index_maps[box]);
      }
      HYPRE_SStructGridSetPeriodic(grid, part, pdata.periodic);
    }
    HYPRE_SStructGridAssemble(grid);
    stencils = (HYPRE_SStructStencil*)(hypre_CAlloc((unsigned)(data.nstencils), (unsigned)(sizeof(HYPRE_SStructStencil))));
    for (s = 0; s < data.nstencils; s++) {
      HYPRE_SStructStencilCreate(data.ndim, data.stencil_sizes[s], &(stencils[s]));
      for (entry = 0; entry < (data.stencil_sizes[s]); entry++) {
        HYPRE_SStructStencilSetEntry(stencils[s], entry, data.stencil_offsets[s][entry], data.stencil_vars[s][entry]);
      }
    }
    object_type = 5555;
    HYPRE_SStructGraphCreate(MPI_COMM_WORLD, grid, &(graph));
    if (object_type != 3333) {
      HYPRE_SStructGraphSetObjectType(graph, object_type);
    }
    for (part = 0; part < data.nparts; part++) {
      pdata = data.pdata[part];
      for (var = 0; var < pdata.nvars; var++) {
        HYPRE_SStructGraphSetStencil(graph, part, var, stencils[pdata.stencil_num[var]]);
      }
      for (box = 0; box < pdata.graph_nboxes; box++) {
        for (index[2] = pdata.graph_ilowers[box][2]; (index[2]) <= (pdata.graph_iuppers[box][2]); index[2] += pdata.graph_strides[box][2]) {
          for (index[1] = pdata.graph_ilowers[box][1]; (index[1]) <= (pdata.graph_iuppers[box][1]); index[1] += pdata.graph_strides[box][1]) {
            for (index[0] = pdata.graph_ilowers[box][0]; (index[0]) <= (pdata.graph_iuppers[box][0]); index[0] += pdata.graph_strides[box][0]) {
              for (i = 0; i < 3; i++) {
                j = pdata.graph_index_maps[box][i];
                k = (index[i]) - (pdata.graph_ilowers[box][i]);
                k /= (pdata.graph_strides[box][i]);
                k -= (pdata.graph_index_signs[box][i]);
                to_index[j] = (pdata.graph_to_ilowers[box][j]) + (k * (pdata.graph_to_strides[box][j]));
              }
              HYPRE_SStructGraphAddEntries(graph, part, index, pdata.graph_vars[box], pdata.graph_to_parts[box], to_index, pdata.graph_to_vars[box]);
            }
          }
        }
      }
    }
    HYPRE_SStructGraphAssemble(graph);
    values = (double*)(hypre_MAlloc((unsigned)(sizeof(double) * data.max_boxsize)));
    HYPRE_SStructMatrixCreate(MPI_COMM_WORLD, graph, &(A));
    for (i = 0; i < data.symmetric_num; i++) {
      HYPRE_SStructMatrixSetSymmetric(A, data.symmetric_parts[i], data.symmetric_vars[i], data.symmetric_to_vars[i], data.symmetric_booleans[i]);
    }
    HYPRE_SStructMatrixSetNSSymmetric(A, data.ns_symmetric);
    if (object_type != 3333) {
      HYPRE_SStructMatrixSetObjectType(A, object_type);
    }
    HYPRE_SStructMatrixInitialize(A);
    for (part = 0; part < data.nparts; part++) {
      pdata = data.pdata[part];
      for (var = 0; var < pdata.nvars; var++) {
        s = pdata.stencil_num[var];
        for (i = 0; i < (data.stencil_sizes[s]); i++) {
          for (j = 0; j < pdata.max_boxsize; j++) {
            values[j] = data.stencil_values[s][i];
          }
          for (box = 0; box < pdata.nboxes; box++) {
            GetVariableBox(pdata.ilowers[box], pdata.iuppers[box], pdata.vartypes[var], ilower, iupper);
            HYPRE_SStructMatrixSetBoxValues(A, part, ilower, iupper, var, 1, &(i), values);
          }
        }
      }
      for (box = 0; box < pdata.graph_nboxes; box++) {
        for (index[2] = pdata.graph_ilowers[box][2]; (index[2]) <= (pdata.graph_iuppers[box][2]); index[2] += pdata.graph_strides[box][2]) {
          for (index[1] = pdata.graph_ilowers[box][1]; (index[1]) <= (pdata.graph_iuppers[box][1]); index[1] += pdata.graph_strides[box][1]) {
            for (index[0] = pdata.graph_ilowers[box][0]; (index[0]) <= (pdata.graph_iuppers[box][0]); index[0] += pdata.graph_strides[box][0]) {
              HYPRE_SStructMatrixSetValues(A, part, index, pdata.graph_vars[box], 1, &(pdata.graph_entries[box]), &(pdata.graph_values[box]));
            }
          }
        }
      }
      for (box = 0; box < pdata.matset_nboxes; box++) {
        size = 1;
        for (j = 0; j < 3; j++) {
          size -= (((pdata.matset_iuppers[box][j]) - (pdata.matset_ilowers[box][j])) + 1);
        }
        for (j = 0; j < size; j++) {
          values[j] = pdata.matset_values[box];
        }
        HYPRE_SStructMatrixSetBoxValues(A, part, pdata.matset_ilowers[box], pdata.matset_iuppers[box], pdata.matset_vars[box], 1, &(pdata.matset_entries[box]), values);
      }
      for (box = 0; box < pdata.matadd_nboxes; box++) {
        size = 1;
        for (j = 0; j < 3; j++) {
          size -= (((pdata.matadd_iuppers[box][j]) - (pdata.matadd_ilowers[box][j])) + 1);
        }
        for (entry = 0; entry < (pdata.matadd_nentries[box]); entry++) {
          for (j = 0; j < size; j++) {
            values[j] = pdata.matadd_values[box][entry];
          }
          HYPRE_SStructMatrixAddToBoxValues(A, part, pdata.matadd_ilowers[box], pdata.matadd_iuppers[box], pdata.matadd_vars[box], 1, &(pdata.matadd_entries[box][entry]), values);
        }
      }
    }
    HYPRE_SStructMatrixAssemble(A);
    HYPRE_SStructVectorCreate(MPI_COMM_WORLD, grid, &(b));
    if (object_type != 3333) {
      HYPRE_SStructVectorSetObjectType(b, object_type);
    }
    HYPRE_SStructVectorInitialize(b);
    for (j = 0; j < data.max_boxsize; j++) {
      values[j] = 1.0;
    }
    for (part = 0; part < data.nparts; part++) {
      pdata = data.pdata[part];
      for (var = 0; var < pdata.nvars; var++) {
        for (box = 0; box < pdata.nboxes; box++) {
          GetVariableBox(pdata.ilowers[box], pdata.iuppers[box], pdata.vartypes[var], ilower, iupper);
          HYPRE_SStructVectorSetBoxValues(b, part, ilower, iupper, var, values);
        }
      }
    }
    HYPRE_SStructVectorAssemble(b);
    HYPRE_SStructVectorCreate(MPI_COMM_WORLD, grid, &(x));
    if (object_type != 3333) {
      HYPRE_SStructVectorSetObjectType(x, object_type);
    }
    HYPRE_SStructVectorInitialize(x);
    if (cosine) {
      for (part = 0; part < data.nparts; part++) {
        pdata = data.pdata[part];
        for (var = 0; var < pdata.nvars; var++) {
          scale = (part + 1.0) * (var + 1.0);
          for (box = 0; box < pdata.nboxes; box++) {
            GetVariableBox(pdata.ilowers[box], pdata.iuppers[box], var, ilower, iupper);
            SetCosineVector(scale, ilower, iupper, values);
            HYPRE_SStructVectorSetBoxValues(x, part, ilower, iupper, var, values);
          }
        }
      }
    }
    HYPRE_SStructVectorAssemble(x);
    hypre_EndTiming(time_index);
    hypre_PrintTiming("SStruct Interface", &(wall_time), MPI_COMM_WORLD);
    hypre_FinalizeTiming(time_index);
    hypre_ClearTiming();
    fflush((void*)0);
    if (cosine) {
      for (part = 0; part < data.nparts; part++) {
        pdata = data.pdata[part];
        for (var = 0; var < pdata.nvars; var++) {
          scale = (part + 1.0) * (var + 1.0);
          for (box = 0; box < pdata.nboxes; box++) {
            GetVariableBox(pdata.ilowers[box], pdata.iuppers[box], var, ilower, iupper);
            SetCosineVector(scale, ilower, iupper, values);
            HYPRE_SStructVectorSetBoxValues(x, part, ilower, iupper, var, values);
          }
        }
      }
    }
    HYPRE_SStructMatrixGetObject(A, (void**)(&(par_A)));
    HYPRE_SStructVectorGetObject(b, (void**)(&(par_b)));
    HYPRE_SStructVectorGetObject(x, (void**)(&(par_x)));
    if (cosine) {
      if (object_type != 5555) {
        HYPRE_SStructVectorAssemble(x);
        hypre_SStructMatvec(1.0, A, x, 0.0, b);
        hypre_SStructMatvec(0.0, A, b, 0.0, x);
      }
      else {
        HYPRE_ParCSRMatrixMatvec(1.0, par_A, par_x, 0.0, par_b);
        HYPRE_ParCSRMatrixMatvec(0.0, par_A, par_b, 0.0, par_x);
      }
    }
    if (print_system) {
      HYPRE_SStructVectorGather(b);
      HYPRE_SStructVectorGather(x);
      HYPRE_SStructMatrixPrint("sstruct.out.A", A, 0);
      HYPRE_SStructVectorPrint("sstruct.out.b", b, 0);
      HYPRE_SStructVectorPrint("sstruct.out.x0", x, 0);
    }
    hypre_Free((char*)values), values = (void*)0;
  }
  if ((solver_id > (-1)) && (solver_id < 2)) {
    time_index = hypre_InitializeTiming("PCG Setup");
    hypre_BeginTiming(time_index);
    HYPRE_ParCSRPCGCreate(MPI_COMM_WORLD, &(par_solver));
    HYPRE_PCGSetTol(par_solver, tol);
    HYPRE_PCGSetTwoNorm(par_solver, 1);
    HYPRE_PCGSetRelChange(par_solver, 0);
    HYPRE_PCGSetPrintLevel(par_solver, 0);
    if (solver_id == 0) {
      HYPRE_PCGSetMaxIter(par_solver, maxit_prec);
      HYPRE_BoomerAMGCreate(&(par_precond));
      HYPRE_BoomerAMGSetCoarsenType(par_precond, 10);
      HYPRE_BoomerAMGSetStrongThreshold(par_precond, 0.25);
      HYPRE_BoomerAMGSetAggNumLevels(par_precond, 1);
      HYPRE_BoomerAMGSetInterpType(par_precond, 6);
      HYPRE_BoomerAMGSetPMaxElmts(par_precond, 4);
      HYPRE_BoomerAMGSetTol(par_precond, 0.0);
      HYPRE_BoomerAMGSetRelaxType(par_precond, 8);
      HYPRE_BoomerAMGSetCycleRelaxType(par_precond, 8, 3);
      HYPRE_BoomerAMGSetCycleNumSweeps(par_precond, 1, 3);
      HYPRE_BoomerAMGSetRelaxOrder(par_precond, 0);
      HYPRE_BoomerAMGSetPrintLevel(par_precond, print_level);
      HYPRE_BoomerAMGSetPrintFileName(par_precond, "sstruct.out.log");
      HYPRE_BoomerAMGSetMaxIter(par_precond, 1);
      HYPRE_PCGSetPrecond(par_solver, (HYPRE_PtrToSolverFcn)HYPRE_BoomerAMGSolve, (HYPRE_PtrToSolverFcn)HYPRE_BoomerAMGSetup, par_precond);
    }
    else
      if (solver_id == 1) {
        HYPRE_PCGSetMaxIter(par_solver, maxit_sol);
        par_precond = (void*)0;
        HYPRE_PCGSetPrecond(par_solver, (HYPRE_PtrToSolverFcn)HYPRE_ParCSRDiagScale, (HYPRE_PtrToSolverFcn)HYPRE_ParCSRDiagScaleSetup, par_precond);
      }
    HYPRE_PCGSetup(par_solver, (HYPRE_Matrix)par_A, (HYPRE_Vector)par_b, (HYPRE_Vector)par_x);
    hypre_EndTiming(time_index);
    hypre_PrintTiming("Setup phase times", &(wall_time), MPI_COMM_WORLD);
    hypre_FinalizeTiming(time_index);
    hypre_ClearTiming();
    fflush((void*)0);
    if (myid == 0)
      printf("\nSystem Size / Setup Phase Time: %e\n\n", system_size / wall_time);
    time_index = hypre_InitializeTiming("PCG Solve");
    hypre_BeginTiming(time_index);
    HYPRE_PCGSolve(par_solver, (HYPRE_Matrix)par_A, (HYPRE_Vector)par_b, (HYPRE_Vector)par_x);
    hypre_EndTiming(time_index);
    hypre_PrintTiming("Solve phase times", &(wall_time), MPI_COMM_WORLD);
    hypre_FinalizeTiming(time_index);
    hypre_ClearTiming();
    fflush((void*)0);
    HYPRE_PCGGetNumIterations(par_solver, &(num_iterations));
    HYPRE_PCGGetFinalRelativeResidualNorm(par_solver, &(final_res_norm));
    HYPRE_ParCSRPCGDestroy(par_solver);
    if (solver_id == 0) {
      HYPRE_BoomerAMGDestroy(par_precond);
    }
  }
  if ((solver_id > 1) && (solver_id < 4)) {
    time_index = hypre_InitializeTiming("GMRES Setup");
    hypre_BeginTiming(time_index);
    HYPRE_ParCSRGMRESCreate(MPI_COMM_WORLD, &(par_solver));
    HYPRE_GMRESSetKDim(par_solver, 10);
    HYPRE_GMRESSetTol(par_solver, tol);
    HYPRE_GMRESSetPrintLevel(par_solver, 0);
    HYPRE_GMRESSetLogging(par_solver, 1);
    if (solver_id == 2) {
      HYPRE_GMRESSetMaxIter(par_solver, maxit_prec);
      HYPRE_BoomerAMGCreate(&(par_precond));
      HYPRE_BoomerAMGSetCoarsenType(par_precond, 10);
      HYPRE_BoomerAMGSetStrongThreshold(par_precond, 0.25);
      HYPRE_BoomerAMGSetAggNumLevels(par_precond, 1);
      HYPRE_BoomerAMGSetInterpType(par_precond, 6);
      HYPRE_BoomerAMGSetPMaxElmts(par_precond, 4);
      HYPRE_BoomerAMGSetTol(par_precond, 0.0);
      HYPRE_BoomerAMGSetRelaxOrder(par_precond, 0);
      HYPRE_BoomerAMGSetRelaxType(par_precond, 8);
      HYPRE_BoomerAMGSetCycleRelaxType(par_precond, 8, 3);
      HYPRE_BoomerAMGSetCycleNumSweeps(par_precond, 1, 3);
      HYPRE_BoomerAMGSetPrintLevel(par_precond, print_level);
      HYPRE_BoomerAMGSetPrintFileName(par_precond, "sstruct.out.log");
      HYPRE_BoomerAMGSetMaxIter(par_precond, 1);
      HYPRE_GMRESSetPrecond(par_solver, (HYPRE_PtrToSolverFcn)HYPRE_BoomerAMGSolve, (HYPRE_PtrToSolverFcn)HYPRE_BoomerAMGSetup, par_precond);
    }
    else
      if (solver_id == 3) {
        HYPRE_GMRESSetMaxIter(par_solver, maxit_sol);
        par_precond = (void*)0;
        HYPRE_GMRESSetPrecond(par_solver, (HYPRE_PtrToSolverFcn)HYPRE_ParCSRDiagScale, (HYPRE_PtrToSolverFcn)HYPRE_ParCSRDiagScaleSetup, par_precond);
      }
    HYPRE_GMRESSetup(par_solver, (HYPRE_Matrix)par_A, (HYPRE_Vector)par_b, (HYPRE_Vector)par_x);
    hypre_EndTiming(time_index);
    hypre_PrintTiming("Setup phase times", &(wall_time), MPI_COMM_WORLD);
    hypre_FinalizeTiming(time_index);
    hypre_ClearTiming();
    fflush((void*)0);
    if (myid == 0)
      printf("\nSystem Size / Setup Phase Time: %e\n\n", system_size / wall_time);
    time_index = hypre_InitializeTiming("GMRES Solve");
    hypre_BeginTiming(time_index);
    HYPRE_GMRESSolve(par_solver, (HYPRE_Matrix)par_A, (HYPRE_Vector)par_b, (HYPRE_Vector)par_x);
    hypre_EndTiming(time_index);
    hypre_PrintTiming("Solve phase times", &(wall_time), MPI_COMM_WORLD);
    hypre_FinalizeTiming(time_index);
    hypre_ClearTiming();
    fflush((void*)0);
    HYPRE_GMRESGetNumIterations(par_solver, &(num_iterations));
    HYPRE_GMRESGetFinalRelativeResidualNorm(par_solver, &(final_res_norm));
    HYPRE_ParCSRGMRESDestroy(par_solver);
    if (solver_id == 2) {
      HYPRE_BoomerAMGDestroy(par_precond);
    }
  }
  if (build_matrix_type == 1) {
    HYPRE_SStructVectorGather(x);
    if (print_system) {
      HYPRE_SStructVectorPrint("sstruct.out.x", x, 0);
    }
  }
  if (myid == 0) {
    printf("\n");
    printf("AMG2013 Benchmark version 1.0\n");
    printf("Iterations = %d\n", num_iterations);
    printf("Final Relative Residual Norm = %e\n", final_res_norm);
    printf("\nSystem Size * Iterations / Solve Phase Time: %e\n", (system_size * (double)num_iterations) / wall_time);
    if (wall)
      printf("\nSolve Time: %e\n", wall_time);
    printf("\n");
  }
  if (build_matrix_type == 1) {
    HYPRE_SStructGridDestroy(grid);
    for (s = 0; s < data.nstencils; s++) {
      HYPRE_SStructStencilDestroy(stencils[s]);
    }
    hypre_Free((char*)stencils), stencils = (void*)0;
    HYPRE_SStructGraphDestroy(graph);
    HYPRE_SStructMatrixDestroy(A);
    HYPRE_SStructVectorDestroy(b);
    HYPRE_SStructVectorDestroy(x);
    DestroyData(data);
    hypre_Free((char*)parts), parts = (void*)0;
    hypre_Free((char*)refine), refine = (void*)0;
    hypre_Free((char*)distribute), distribute = (void*)0;
    hypre_Free((char*)block), block = (void*)0;
  }
  else {
    HYPRE_ParCSRMatrixDestroy(par_A);
    HYPRE_ParVectorDestroy(par_b);
    HYPRE_ParVectorDestroy(par_x);
  }
  ;
  MPI_Finalize();
  return 0;
}
int BuildParLaplacian(int argc, char*  argv[], double* system_size_ptr, HYPRE_ParCSRMatrix* A_ptr, HYPRE_ParVector* rhs_ptr, HYPRE_ParVector* x_ptr) {
  int nx;
  int ny;
  int nz;
  int g_nx;
  int g_ny;
  int g_nz;
  int P;
  int Q;
  int R;
  double cx;
  double cy;
  double cz;
  HYPRE_ParCSRMatrix A;
  HYPRE_ParVector rhs;
  HYPRE_ParVector x;
  int num_procs;
  int myid;
  int p;
  int q;
  int r;
  double* values;
  int arg_index;
  MPI_Comm_size(MPI_COMM_WORLD, &(num_procs));
  MPI_Comm_rank(MPI_COMM_WORLD, &(myid));
  g_nx = 0;
  g_ny = 0;
  g_nz = 0;
  nx = 10;
  ny = 10;
  nz = 10;
  P = 1;
  Q = num_procs;
  R = 1;
  cx = 1.;
  cy = 1.;
  cz = 1.;
  arg_index = 0;
  while (arg_index < argc) {
    if (strcmp(argv[arg_index], "-n") == 0) {
      arg_index++;
      nx = atoi(argv[arg_index++]);
      ny = atoi(argv[arg_index++]);
      nz = atoi(argv[arg_index++]);
    }
    else
      if (strcmp(argv[arg_index], "-P") == 0) {
        arg_index++;
        P = atoi(argv[arg_index++]);
        Q = atoi(argv[arg_index++]);
        R = atoi(argv[arg_index++]);
      }
      else
        if (strcmp(argv[arg_index], "-c") == 0) {
          arg_index++;
          cx = atof(argv[arg_index++]);
          cy = atof(argv[arg_index++]);
          cz = atof(argv[arg_index++]);
        }
        else {
          arg_index++;
        }
  }
  g_nx = nx * P;
  g_ny = ny * Q;
  g_nz = nz * R;
  if (((P * Q) * R) != num_procs) {
    printf("Error: Invalid number of processors or processor topology\n");
    exit(1);
  }
  if (myid == 0) {
    printf("  3D 7-point Laplace problem on a cube\n");
    printf("  (nx_global, ny_global, nz_global) = (%d, %d, %d)\n", g_nx, g_ny, g_nz);
    printf("  (Px, Py, Pz) = (%d, %d, %d)\n", P, Q, R);
    printf("  (cx, cy, cz) = (%f, %f, %f)\n\n", cx, cy, cz);
  }
  p = myid % P;
  q = ((myid - p) / P) % Q;
  r = ((myid - p) - (P * q)) / (P * Q);
  values = (double*)(hypre_CAlloc((unsigned)4, (unsigned)(sizeof(double))));
  values[1] = -cx;
  values[2] = -cy;
  values[3] = -cz;
  values[0] = 0.;
  if (nx > 1) {
    values[0] += 2.0 * cx;
  }
  if (ny > 1) {
    values[0] += 2.0 * cy;
  }
  if (nz > 1) {
    values[0] += 2.0 * cz;
  }
  A = (HYPRE_ParCSRMatrix)(GenerateLaplacian(MPI_COMM_WORLD, g_nx, g_ny, g_nz, P, Q, R, p, q, r, values, &(rhs), &(x)));
  hypre_Free((char*)values), values = (void*)0;
  *system_size_ptr = ((double)g_nx * (double)g_ny) * (double)g_nz;
  *A_ptr = A;
  *rhs_ptr = rhs;
  *x_ptr = x;
  return 0;
}
int BuildParLaplacian27pt(int argc, char*  argv[], double* system_size_ptr, HYPRE_ParCSRMatrix* A_ptr, HYPRE_ParVector* rhs_ptr, HYPRE_ParVector* x_ptr) {
  int nx;
  int ny;
  int nz;
  int g_nx;
  int g_ny;
  int g_nz;
  int P;
  int Q;
  int R;
  HYPRE_ParCSRMatrix A;
  HYPRE_ParVector rhs;
  HYPRE_ParVector x;
  int num_procs;
  int myid;
  int p;
  int q;
  int r;
  double* values;
  int arg_index;
  MPI_Comm_size(MPI_COMM_WORLD, &(num_procs));
  MPI_Comm_rank(MPI_COMM_WORLD, &(myid));
  g_nx = 0;
  g_ny = 0;
  g_nz = 0;
  nx = 10;
  ny = 10;
  nz = 10;
  P = 1;
  Q = num_procs;
  R = 1;
  arg_index = 0;
  while (arg_index < argc) {
    if (strcmp(argv[arg_index], "-n") == 0) {
      arg_index++;
      nx = atoi(argv[arg_index++]);
      ny = atoi(argv[arg_index++]);
      nz = atoi(argv[arg_index++]);
    }
    else
      if (strcmp(argv[arg_index], "-P") == 0) {
        arg_index++;
        P = atoi(argv[arg_index++]);
        Q = atoi(argv[arg_index++]);
        R = atoi(argv[arg_index++]);
      }
      else {
        arg_index++;
      }
  }
  g_nx = nx * P;
  g_ny = ny * Q;
  g_nz = nz * R;
  if (((P * Q) * R) != num_procs) {
    printf("Error: Invalid number of processors or processor topology\n");
    exit(1);
  }
  if (myid == 0) {
    printf("  Laplace type problem with a 27-point stencil \n");
    printf("  (nx_global, ny_global, nz_global) = (%d, %d, %d)\n", g_nx, g_ny, g_nz);
    printf("  (Px, Py, Pz) = (%d, %d, %d)\n\n", P, Q, R);
  }
  p = myid % P;
  q = ((myid - p) / P) % Q;
  r = ((myid - p) - (P * q)) / (P * Q);
  values = (double*)(hypre_CAlloc((unsigned)2, (unsigned)(sizeof(double))));
  values[0] = 26.0;
  if (((nx == 1) || (ny == 1)) || (nz == 1))
    values[0] = 8.0;
  if ((((nx * ny) == 1) || ((nx * nz) == 1)) || ((ny * nz) == 1))
    values[0] = 2.0;
  values[1] = -1.;
  A = (HYPRE_ParCSRMatrix)(GenerateLaplacian27pt(MPI_COMM_WORLD, g_nx, g_ny, g_nz, P, Q, R, p, q, r, values, &(rhs), &(x)));
  hypre_Free((char*)values), values = (void*)0;
  *system_size_ptr = ((double)g_nx * (double)g_ny) * (double)g_nz;
  *rhs_ptr = rhs;
  *x_ptr = x;
  *A_ptr = A;
  return 0;
}
int BuildParVarDifConv(int argc, char*  argv[], double* system_size_ptr, HYPRE_ParCSRMatrix* A_ptr, HYPRE_ParVector* rhs_ptr, HYPRE_ParVector* x_ptr) {
  int nx;
  int ny;
  int nz;
  int g_nx;
  int g_ny;
  int g_nz;
  int P;
  int Q;
  int R;
  HYPRE_ParCSRMatrix A;
  HYPRE_ParVector rhs;
  HYPRE_ParVector x;
  int num_procs;
  int myid;
  int p;
  int q;
  int r;
  int arg_index = 0;
  double eps = 1;
  MPI_Comm_size(MPI_COMM_WORLD, &(num_procs));
  MPI_Comm_rank(MPI_COMM_WORLD, &(myid));
  g_nx = 0;
  g_ny = 0;
  g_nz = 0;
  nx = 10;
  ny = 10;
  nz = 10;
  P = 1;
  Q = num_procs;
  R = 1;
  while (arg_index < argc) {
    if (strcmp(argv[arg_index], "-n") == 0) {
      arg_index++;
      nx = atoi(argv[arg_index++]);
      ny = atoi(argv[arg_index++]);
      nz = atoi(argv[arg_index++]);
    }
    else
      if (strcmp(argv[arg_index], "-P") == 0) {
        arg_index++;
        P = atoi(argv[arg_index++]);
        Q = atoi(argv[arg_index++]);
        R = atoi(argv[arg_index++]);
      }
      else {
        arg_index++;
      }
  }
  g_nx = nx * P;
  g_ny = ny * Q;
  g_nz = nz * R;
  if (((P * Q) * R) != num_procs) {
    printf("Error: Invalid number of processors or processor topology\n");
    exit(1);
  }
  if (myid == 0) {
    printf("  elliptic PDE on a cube with jumps\n");
    printf("  (nx_global, ny_global, nz_global) = (%d, %d, %d)\n", g_nx, g_ny, g_nz);
    printf("  (Px, Py, Pz) = (%d, %d, %d)\n", P, Q, R);
  }
  p = myid % P;
  q = ((myid - p) / P) % Q;
  r = ((myid - p) - (P * q)) / (P * Q);
  A = (HYPRE_ParCSRMatrix)(GenerateVarDifConv(MPI_COMM_WORLD, g_nx, g_ny, g_nz, P, Q, R, p, q, r, eps, &(rhs), &(x)));
  *system_size_ptr = ((double)g_nx * (double)g_ny) * (double)g_nz;
  *A_ptr = A;
  *rhs_ptr = rhs;
  *x_ptr = x;
  return 0;
}
//==================== HYPRE_IJMatrix.c ====================
int HYPRE_IJMatrixCreate(MPI_Comm comm, int ilower, int iupper, int jlower, int jupper, HYPRE_IJMatrix* matrix) {
  int* row_partitioning;
  int* col_partitioning;
  int* info;
  int num_procs;
  int myid;
  hypre_IJMatrix* ijmatrix;
  int* recv_buf;
  int i;
  int i4;
  int square;
  ijmatrix = (hypre_IJMatrix*)(hypre_CAlloc((unsigned)1, (unsigned)(sizeof(hypre_IJMatrix))));
  (ijmatrix)->comm = comm;
  (ijmatrix)->object = (void*)0;
  (ijmatrix)->translator = (void*)0;
  (ijmatrix)->object_type = -999;
  (ijmatrix)->assemble_flag = 0;
  MPI_Comm_size(comm, &(num_procs));
  MPI_Comm_rank(comm, &(myid));
  if ((ilower > (iupper + 1)) || (ilower < 0)) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/HYPRE_IJMatrix.c", 908, 4 | (2 << 3));
    return hypre__global_error;
  }
  if (iupper < (-1)) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/HYPRE_IJMatrix.c", 908, 4 | (3 << 3));
    return hypre__global_error;
  }
  if ((jlower > (jupper + 1)) || (jlower < 0)) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/HYPRE_IJMatrix.c", 908, 4 | (4 << 3));
    return hypre__global_error;
  }
  if (jupper < (-1)) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/HYPRE_IJMatrix.c", 908, 4 | (5 << 3));
    return hypre__global_error;
  }
  info = (int*)(hypre_CAlloc((unsigned)4, (unsigned)(sizeof(int))));
  recv_buf = (int*)(hypre_CAlloc((unsigned)(4 * num_procs), (unsigned)(sizeof(int))));
  row_partitioning = (int*)(hypre_CAlloc((unsigned)(num_procs + 1), (unsigned)(sizeof(int))));
  info[0] = ilower;
  info[1] = iupper;
  info[2] = jlower;
  info[3] = jupper;
  MPI_Allgather(info, 4, MPI_INT, recv_buf, 4, MPI_INT, comm);
  row_partitioning[0] = recv_buf[0];
  square = 1;
  for (i = 0; i < (num_procs - 1); i++) {
    i4 = 4 * i;
    if ((recv_buf[i4 + 1]) != ((recv_buf[i4 + 4]) - 1)) {
      printf("Warning -- row partitioning does not line up! Partitioning incomplete!\n");
      hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/HYPRE_IJMatrix.c", 908, 1);
      return hypre__global_error;
    }
    else
      row_partitioning[i + 1] = recv_buf[i4 + 4];
    if ((square && ((recv_buf[i4]) != (recv_buf[i4 + 2]))) || ((recv_buf[i4 + 1]) != (recv_buf[i4 + 3]))) {
      square = 0;
    }
  }
  i4 = (num_procs - 1) * 4;
  row_partitioning[num_procs] = (recv_buf[i4 + 1]) + 1;
  if (((recv_buf[i4]) != (recv_buf[i4 + 2])) || ((recv_buf[i4 + 1]) != (recv_buf[i4 + 3])))
    square = 0;
  if (square)
    col_partitioning = row_partitioning;
  else {
    col_partitioning = (int*)(hypre_CAlloc((unsigned)(num_procs + 1), (unsigned)(sizeof(int))));
    col_partitioning[0] = recv_buf[2];
    for (i = 0; i < (num_procs - 1); i++) {
      i4 = 4 * i;
      if ((recv_buf[i4 + 3]) != ((recv_buf[i4 + 6]) - 1)) {
        printf("Warning -- col partitioning does not line up! Partitioning incomplete!\n");
        hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/HYPRE_IJMatrix.c", 908, 1);
        return hypre__global_error;
      }
      else
        col_partitioning[i + 1] = recv_buf[i4 + 6];
    }
    col_partitioning[num_procs] = (recv_buf[(num_procs * 4) - 1]) + 1;
  }
  (ijmatrix)->global_first_row = row_partitioning[0];
  (ijmatrix)->global_first_col = col_partitioning[0];
  (ijmatrix)->global_num_rows = (row_partitioning[num_procs]) - (row_partitioning[0]);
  (ijmatrix)->global_num_cols = (col_partitioning[num_procs]) - (col_partitioning[0]);
  hypre_Free((char*)info), info = (void*)0;
  hypre_Free((char*)recv_buf), recv_buf = (void*)0;
  (ijmatrix)->row_partitioning = row_partitioning;
  (ijmatrix)->col_partitioning = col_partitioning;
  *matrix = (HYPRE_IJMatrix)ijmatrix;
  return hypre__global_error;
}
int HYPRE_IJMatrixDestroy(HYPRE_IJMatrix matrix) {
  int ierr = 0;
  hypre_IJMatrix* ijmatrix = (hypre_IJMatrix*)matrix;
  if (!ijmatrix) {
    printf("Variable ijmatrix is NULL -- HYPRE_IJMatrixDestroy\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/HYPRE_IJMatrix.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  if (ijmatrix) {
    if ((ijmatrix)->row_partitioning == (ijmatrix)->col_partitioning)
      hypre_Free((char*)((ijmatrix)->row_partitioning)), (ijmatrix)->row_partitioning = (void*)0;
    else {
      hypre_Free((char*)((ijmatrix)->row_partitioning)), (ijmatrix)->row_partitioning = (void*)0;
      hypre_Free((char*)((ijmatrix)->col_partitioning)), (ijmatrix)->col_partitioning = (void*)0;
    }
    if ((ijmatrix)->object_type == 5555)
      ierr = hypre_IJMatrixDestroyParCSR(ijmatrix);
    else
      if ((ijmatrix)->object_type != (-1)) {
        printf("Unrecognized object type -- HYPRE_IJMatrixDestroy\n");
        hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/HYPRE_IJMatrix.c", 908, 4 | (1 << 3));
        return hypre__global_error;
      }
  }
  hypre_Free((char*)ijmatrix), ijmatrix = (void*)0;
  return hypre__global_error;
}
int HYPRE_IJMatrixInitialize(HYPRE_IJMatrix matrix) {
  hypre_IJMatrix* ijmatrix = (hypre_IJMatrix*)matrix;
  int ierr = 0;
  if (!ijmatrix) {
    printf("Variable ijmatrix is NULL -- HYPRE_IJMatrixInitialize\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/HYPRE_IJMatrix.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  if ((ijmatrix)->object_type == 5555)
    ierr = hypre_IJMatrixInitializeParCSR(ijmatrix);
  else {
    printf("Unrecognized object type -- HYPRE_IJMatrixInitialize\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/HYPRE_IJMatrix.c", 908, 4 | (1 << 3));
  }
  return hypre__global_error;
}
int HYPRE_IJMatrixSetValues(HYPRE_IJMatrix matrix, int nrows, int* ncols, int* rows, int* cols, double* values) {
  hypre_IJMatrix* ijmatrix = (hypre_IJMatrix*)matrix;
  if (nrows == 0)
    return hypre__global_error;
  if (!ijmatrix) {
    printf("Variable ijmatrix is NULL -- HYPRE_IJMatrixSetValues\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/HYPRE_IJMatrix.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  if (nrows < 0) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/HYPRE_IJMatrix.c", 908, 4 | (2 << 3));
    return hypre__global_error;
  }
  if (!ncols) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/HYPRE_IJMatrix.c", 908, 4 | (3 << 3));
    return hypre__global_error;
  }
  if (!rows) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/HYPRE_IJMatrix.c", 908, 4 | (4 << 3));
    return hypre__global_error;
  }
  if (!cols) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/HYPRE_IJMatrix.c", 908, 4 | (5 << 3));
    return hypre__global_error;
  }
  if (!values) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/HYPRE_IJMatrix.c", 908, 4 | (6 << 3));
    return hypre__global_error;
  }
  if ((ijmatrix)->object_type == 5555)
    return hypre_IJMatrixSetValuesParCSR(ijmatrix, nrows, ncols, rows, cols, values);
  else {
    printf("Unrecognized object type -- HYPRE_IJMatrixSetValues\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/HYPRE_IJMatrix.c", 908, 4 | (1 << 3));
  }
  return hypre__global_error;
}
int HYPRE_IJMatrixAddToValues(HYPRE_IJMatrix matrix, int nrows, int* ncols, int* rows, int* cols, double* values) {
  hypre_IJMatrix* ijmatrix = (hypre_IJMatrix*)matrix;
  if (nrows == 0)
    return hypre__global_error;
  if (!ijmatrix) {
    printf("Variable ijmatrix is NULL -- HYPRE_IJMatrixAddToValues\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/HYPRE_IJMatrix.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  if (nrows < 0) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/HYPRE_IJMatrix.c", 908, 4 | (2 << 3));
    return hypre__global_error;
  }
  if (!ncols) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/HYPRE_IJMatrix.c", 908, 4 | (3 << 3));
    return hypre__global_error;
  }
  if (!rows) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/HYPRE_IJMatrix.c", 908, 4 | (4 << 3));
    return hypre__global_error;
  }
  if (!cols) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/HYPRE_IJMatrix.c", 908, 4 | (5 << 3));
    return hypre__global_error;
  }
  if (!values) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/HYPRE_IJMatrix.c", 908, 4 | (6 << 3));
    return hypre__global_error;
  }
  if ((ijmatrix)->object_type == 5555)
    return hypre_IJMatrixAddToValuesParCSR(ijmatrix, nrows, ncols, rows, cols, values);
  else {
    printf("Unrecognized object type -- HYPRE_IJMatrixAddToValues\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/HYPRE_IJMatrix.c", 908, 4 | (1 << 3));
  }
  return hypre__global_error;
}
int HYPRE_IJMatrixAssemble(HYPRE_IJMatrix matrix) {
  hypre_IJMatrix* ijmatrix = (hypre_IJMatrix*)matrix;
  if (!ijmatrix) {
    printf("Variable ijmatrix is NULL -- HYPRE_IJMatrixAssemble\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/HYPRE_IJMatrix.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  if ((ijmatrix)->object_type == 5555)
    return hypre_IJMatrixAssembleParCSR(ijmatrix);
  else {
    printf("Unrecognized object type -- HYPRE_IJMatrixAssemble\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/HYPRE_IJMatrix.c", 908, 4 | (1 << 3));
  }
  return hypre__global_error;
}
int HYPRE_IJMatrixGetValues(HYPRE_IJMatrix matrix, int nrows, int* ncols, int* rows, int* cols, double* values) {
  int ierr = 0;
  hypre_IJMatrix* ijmatrix = (hypre_IJMatrix*)matrix;
  if (nrows == 0)
    return hypre__global_error;
  if (!ijmatrix) {
    printf("Variable ijmatrix is NULL -- HYPRE_IJMatrixGetValues\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/HYPRE_IJMatrix.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  if (nrows < 0) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/HYPRE_IJMatrix.c", 908, 4 | (2 << 3));
    return hypre__global_error;
  }
  if (!ncols) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/HYPRE_IJMatrix.c", 908, 4 | (3 << 3));
    return hypre__global_error;
  }
  if (!rows) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/HYPRE_IJMatrix.c", 908, 4 | (4 << 3));
    return hypre__global_error;
  }
  if (!cols) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/HYPRE_IJMatrix.c", 908, 4 | (5 << 3));
    return hypre__global_error;
  }
  if (!values) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/HYPRE_IJMatrix.c", 908, 4 | (6 << 3));
    return hypre__global_error;
  }
  if ((ijmatrix)->object_type == 5555)
    ierr = hypre_IJMatrixGetValuesParCSR(ijmatrix, nrows, ncols, rows, cols, values);
  else {
    printf("Unrecognized object type -- HYPRE_IJMatrixGetValues\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/HYPRE_IJMatrix.c", 908, 4 | (1 << 3));
  }
  return hypre__global_error;
}
int HYPRE_IJMatrixSetObjectType(HYPRE_IJMatrix matrix, int type) {
  hypre_IJMatrix* ijmatrix = (hypre_IJMatrix*)matrix;
  if (!ijmatrix) {
    printf("Variable ijmatrix is NULL -- HYPRE_IJMatrixSetObjectType\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/HYPRE_IJMatrix.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  (ijmatrix)->object_type = type;
  return hypre__global_error;
}
int HYPRE_IJMatrixGetObject(HYPRE_IJMatrix matrix, void** object) {
  hypre_IJMatrix* ijmatrix = (hypre_IJMatrix*)matrix;
  if (!ijmatrix) {
    printf("Variable ijmatrix is NULL -- HYPRE_IJMatrixGetObject\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/HYPRE_IJMatrix.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  *object = (ijmatrix)->object;
  return hypre__global_error;
}
int HYPRE_IJMatrixSetRowSizes(HYPRE_IJMatrix matrix, int* sizes) {
  hypre_IJMatrix* ijmatrix = (hypre_IJMatrix*)matrix;
  if (!ijmatrix) {
    printf("Variable ijmatrix is NULL -- HYPRE_IJMatrixSetRowSizes\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/HYPRE_IJMatrix.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  if ((ijmatrix)->object_type == 5555)
    return hypre_IJMatrixSetRowSizesParCSR(ijmatrix, sizes);
  else {
    printf("Unrecognized object type -- HYPRE_IJMatrixSetRowSizes\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/HYPRE_IJMatrix.c", 908, 4 | (1 << 3));
  }
  return hypre__global_error;
}
int HYPRE_IJMatrixPrint(HYPRE_IJMatrix matrix, char* filename) {
  MPI_Comm comm = (matrix)->comm;
  int* row_partitioning;
  int* col_partitioning;
  int ilower;
  int iupper;
  int jlower;
  int jupper;
  int i;
  int ii;
  int j;
  int ncols;
  int* cols;
  double* values;
  int myid;
  char  new_filename[255];
  FILE* file;
  void* object;
  if (!matrix) {
    printf("Variable matrix is NULL -- HYPRE_IJMatrixPrint\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/HYPRE_IJMatrix.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  if ((matrix)->object_type != 5555) {
    printf("Unrecognized object type -- HYPRE_IJMatrixPrint\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/HYPRE_IJMatrix.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  MPI_Comm_rank(comm, &(myid));
  sprintf(new_filename, "%s.%05d", filename, myid);
  if ((file = fopen(new_filename, "w")) == (void*)0) {
    printf("Error: can't open output file %s\n", new_filename);
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/HYPRE_IJMatrix.c", 908, 4 | (2 << 3));
    return hypre__global_error;
  }
  row_partitioning = (matrix)->row_partitioning;
  col_partitioning = (matrix)->col_partitioning;
  ilower = row_partitioning[myid];
  iupper = (row_partitioning[myid + 1]) - 1;
  jlower = col_partitioning[myid];
  jupper = (col_partitioning[myid + 1]) - 1;
  fprintf(file, "%d %d %d %d\n", ilower, iupper, jlower, jupper);
  HYPRE_IJMatrixGetObject(matrix, &(object));
  for (i = ilower; i <= iupper; i++) {
    if ((matrix)->object_type == 5555) {
      ii = i - (row_partitioning[0]);
      HYPRE_ParCSRMatrixGetRow((HYPRE_ParCSRMatrix)object, ii, &(ncols), &(cols), &(values));
      for (j = 0; j < ncols; j++) {
        cols[j] += col_partitioning[0];
      }
    }
    for (j = 0; j < ncols; j++) {
      fprintf(file, "%d %d %.14e\n", i, cols[j], values[j]);
    }
    if ((matrix)->object_type == 5555) {
      for (j = 0; j < ncols; j++) {
        (cols[j]) -= (col_partitioning[0]);
      }
      HYPRE_ParCSRMatrixRestoreRow((HYPRE_ParCSRMatrix)object, ii, &(ncols), &(cols), &(values));
    }
  }
  fclose(file);
  return hypre__global_error;
}
//==================== HYPRE_IJVector.c ====================
int HYPRE_IJVectorCreate(MPI_Comm comm, int jlower, int jupper, HYPRE_IJVector* vector) {
  hypre_IJVector* vec;
  int num_procs;
  int my_id;
  int* partitioning;
  int* recv_buf;
  int* info;
  int i;
  int i2;
  vec = (hypre_IJVector*)(hypre_CAlloc((unsigned)1, (unsigned)(sizeof(hypre_IJVector))));
  if (!vec) {
    printf("Out of memory -- HYPRE_IJVectorCreate\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/HYPRE_IJVector.c", 908, 2);
    return hypre__global_error;
  }
  MPI_Comm_size(comm, &(num_procs));
  MPI_Comm_rank(comm, &(my_id));
  if ((jlower > (jupper + 1)) || (jlower < 0)) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/HYPRE_IJVector.c", 908, 4 | (2 << 3));
    return hypre__global_error;
  }
  if (jupper < (-1)) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/HYPRE_IJVector.c", 908, 4 | (3 << 3));
    return hypre__global_error;
  }
  info = (int*)(hypre_CAlloc((unsigned)2, (unsigned)(sizeof(int))));
  recv_buf = (int*)(hypre_CAlloc((unsigned)(2 * num_procs), (unsigned)(sizeof(int))));
  partitioning = (int*)(hypre_CAlloc((unsigned)(num_procs + 1), (unsigned)(sizeof(int))));
  info[0] = jlower;
  info[1] = jupper;
  MPI_Allgather(info, 2, MPI_INT, recv_buf, 2, MPI_INT, comm);
  partitioning[0] = recv_buf[0];
  for (i = 0; i < (num_procs - 1); i++) {
    i2 = i + i;
    if ((recv_buf[i2 + 1]) != ((recv_buf[i2 + 2]) - 1)) {
      printf("Inconsistent partitioning -- HYPRE_IJVectorCreate\n");
      hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/HYPRE_IJVector.c", 908, 1);
      return hypre__global_error;
    }
    else
      partitioning[i + 1] = recv_buf[i2 + 2];
  }
  i2 = (num_procs - 1) * 2;
  partitioning[num_procs] = (recv_buf[i2 + 1]) + 1;
  hypre_Free((char*)info), info = (void*)0;
  hypre_Free((char*)recv_buf), recv_buf = (void*)0;
  (vec)->global_first_row = partitioning[0];
  (vec)->global_num_rows = (partitioning[num_procs]) - (partitioning[0]);
  (vec)->comm = comm;
  (vec)->partitioning = partitioning;
  (vec)->object_type = -999;
  (vec)->object = (void*)0;
  (vec)->translator = (void*)0;
  *vector = (HYPRE_IJVector)vec;
  return hypre__global_error;
}
int HYPRE_IJVectorDestroy(HYPRE_IJVector vector) {
  hypre_IJVector* vec = (hypre_IJVector*)vector;
  if (!vec) {
    printf("Vector variable is NULL -- HYPRE_IJVectorDestroy\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/HYPRE_IJVector.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  if ((vec)->partitioning)
    hypre_Free((char*)((vec)->partitioning)), (vec)->partitioning = (void*)0;
  if ((vec)->object_type == 5555) {
    hypre_IJVectorDestroyPar(vec);
    if ((vec)->translator) {
      hypre_AuxParVectorDestroy((hypre_AuxParVector*)((vec)->translator));
    }
  }
  else
    if ((vec)->object_type != (-1)) {
      printf("Unrecognized object type -- HYPRE_IJVectorDestroy\n");
      hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/HYPRE_IJVector.c", 908, 4 | (1 << 3));
      return hypre__global_error;
    }
  hypre_Free((char*)vec), vec = (void*)0;
  return hypre__global_error;
}
int HYPRE_IJVectorInitialize(HYPRE_IJVector vector) {
  hypre_IJVector* vec = (hypre_IJVector*)vector;
  if (!vec) {
    printf("Vector variable is NULL -- HYPRE_IJVectorInitialize\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/HYPRE_IJVector.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  if ((vec)->object_type == 5555) {
    if (!(vec)->object)
      hypre_IJVectorCreatePar(vec, (vec)->partitioning);
    hypre_IJVectorInitializePar(vec);
  }
  else {
    printf("Unrecognized object type -- HYPRE_IJVectorInitialize\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/HYPRE_IJVector.c", 908, 4 | (1 << 3));
  }
  return hypre__global_error;
}
int HYPRE_IJVectorAssemble(HYPRE_IJVector vector) {
  hypre_IJVector* vec = (hypre_IJVector*)vector;
  if (!vec) {
    printf("Variable vec is NULL -- HYPRE_IJVectorAssemble\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/HYPRE_IJVector.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  if ((vec)->object_type == 5555)
    return hypre_IJVectorAssemblePar(vec);
  else {
    printf("Unrecognized object type -- HYPRE_IJVectorAssemble\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/HYPRE_IJVector.c", 908, 4 | (1 << 3));
  }
  return hypre__global_error;
}
int HYPRE_IJVectorSetObjectType(HYPRE_IJVector vector, int type) {
  hypre_IJVector* vec = (hypre_IJVector*)vector;
  if (!vec) {
    printf("Variable vec is NULL -- HYPRE_IJVectorSetObjectType\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/HYPRE_IJVector.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  (vec)->object_type = type;
  return hypre__global_error;
}
int HYPRE_IJVectorGetObject(HYPRE_IJVector vector, void** object) {
  hypre_IJVector* vec = (hypre_IJVector*)vector;
  if (!vec) {
    printf("Variable vec is NULL -- HYPRE_IJVectorGetObject\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/HYPRE_IJVector.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  *object = (vec)->object;
  return hypre__global_error;
}
//==================== IJMatrix_parcsr.c ===================
int hypre_IJMatrixCreateParCSR(hypre_IJMatrix* matrix) {
  MPI_Comm comm = (matrix)->comm;
  int* row_partitioning = (matrix)->row_partitioning;
  int* col_partitioning = (matrix)->col_partitioning;
  hypre_ParCSRMatrix* par_matrix;
  int* row_starts;
  int* col_starts;
  int num_procs;
  int i;
  MPI_Comm_size(comm, &(num_procs));
  row_starts = (int*)(hypre_CAlloc((unsigned)(num_procs + 1), (unsigned)(sizeof(int))));
  if (row_partitioning[0])
    for (i = 0; i < (num_procs + 1); i++)
      row_starts[i] = (row_partitioning[i]) - (row_partitioning[0]);
  else
    for (i = 0; i < (num_procs + 1); i++)
      row_starts[i] = row_partitioning[i];
  if (row_partitioning != col_partitioning) {
    col_starts = (int*)(hypre_CAlloc((unsigned)(num_procs + 1), (unsigned)(sizeof(int))));
    if (col_partitioning[0])
      for (i = 0; i < (num_procs + 1); i++)
        col_starts[i] = (col_partitioning[i]) - (col_partitioning[0]);
    else
      for (i = 0; i < (num_procs + 1); i++)
        col_starts[i] = col_partitioning[i];
  }
  else
    col_starts = row_starts;
  par_matrix = hypre_ParCSRMatrixCreate(comm, row_starts[num_procs], col_starts[num_procs], row_starts, col_starts, 0, 0, 0);
  (matrix)->object = par_matrix;
  return hypre__global_error;
}
int hypre_IJMatrixSetRowSizesParCSR(hypre_IJMatrix* matrix, int* sizes) {
  int local_num_rows;
  int local_num_cols;
  int i;
  int my_id;
  int* row_space;
  int* row_partitioning = (matrix)->row_partitioning;
  int* col_partitioning = (matrix)->col_partitioning;
  hypre_AuxParCSRMatrix* aux_matrix;
  MPI_Comm comm = (matrix)->comm;
  MPI_Comm_rank(comm, &(my_id));
  local_num_rows = (int)((row_partitioning[my_id + 1]) - (row_partitioning[my_id]));
  local_num_cols = (int)((col_partitioning[my_id + 1]) - (col_partitioning[my_id]));
  aux_matrix = (matrix)->translator;
  row_space = (void*)0;
  if (aux_matrix)
    row_space = (aux_matrix)->row_space;
  if (!row_space)
    row_space = (int*)(hypre_CAlloc((unsigned)local_num_rows, (unsigned)(sizeof(int))));
  for (i = 0; i < local_num_rows; i++)
    row_space[i] = sizes[i];
  if (!aux_matrix) {
    hypre_AuxParCSRMatrixCreate(&(aux_matrix), local_num_rows, local_num_cols, row_space);
    (matrix)->translator = aux_matrix;
  }
  (aux_matrix)->row_space = row_space;
  return hypre__global_error;
}
int hypre_IJMatrixInitializeParCSR(hypre_IJMatrix* matrix) {
  hypre_ParCSRMatrix* par_matrix = (matrix)->object;
  hypre_AuxParCSRMatrix* aux_matrix = (matrix)->translator;
  int local_num_rows;
  if ((matrix)->assemble_flag == 0) {
    if (!par_matrix) {
      hypre_IJMatrixCreateParCSR(matrix);
      par_matrix = (matrix)->object;
    }
    local_num_rows = ((par_matrix)->diag)->num_rows;
    if (!aux_matrix) {
      hypre_AuxParCSRMatrixCreate(&(aux_matrix), local_num_rows, ((par_matrix)->diag)->num_cols, (void*)0);
      (matrix)->translator = aux_matrix;
    }
    hypre_ParCSRMatrixInitialize(par_matrix);
    hypre_AuxParCSRMatrixInitialize(aux_matrix);
    if (!(aux_matrix)->need_aux) {
      int i;
      int* indx_diag;
      int* indx_offd;
      int* diag_i;
      int* offd_i;
      diag_i = ((par_matrix)->diag)->i;
      offd_i = ((par_matrix)->offd)->i;
      indx_diag = (aux_matrix)->indx_diag;
      indx_offd = (aux_matrix)->indx_offd;
      for (i = 0; i < local_num_rows; i++) {
        indx_diag[i] = diag_i[i];
        indx_offd[i] = offd_i[i];
      }
    }
  }
  else {
    if (!aux_matrix) {
      local_num_rows = ((par_matrix)->diag)->num_rows;
      hypre_AuxParCSRMatrixCreate(&(aux_matrix), local_num_rows, ((par_matrix)->diag)->num_cols, (void*)0);
      (aux_matrix)->need_aux = 0;
      (matrix)->translator = aux_matrix;
    }
  }
  return hypre__global_error;
}
int hypre_IJMatrixGetValuesParCSR(hypre_IJMatrix* matrix, int nrows, int* ncols, int* rows, int* cols, double* values) {
  MPI_Comm comm = (matrix)->comm;
  hypre_ParCSRMatrix* par_matrix = (matrix)->object;
  int assemble_flag = (matrix)->assemble_flag;
  hypre_CSRMatrix* diag;
  int* diag_i;
  int* diag_j;
  double* diag_data;
  hypre_CSRMatrix* offd;
  int* offd_i;
  int* offd_j;
  double* offd_data;
  int* col_map_offd;
  int* col_starts = (par_matrix)->col_starts;
  int* row_partitioning = (matrix)->row_partitioning;
  int* col_partitioning = (matrix)->col_partitioning;
  int i;
  int j;
  int n;
  int ii;
  int indx;
  int col_indx;
  int num_procs;
  int my_id;
  int col_0;
  int col_n;
  int row;
  int row_local;
  int row_size;
  int warning = 0;
  int* counter;
  MPI_Comm_size(comm, &(num_procs));
  MPI_Comm_rank(comm, &(my_id));
  if (assemble_flag == 0) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/IJMatrix_parcsr.c", 908, 4 | (1 << 3));
    printf("Error! Matrix not assembled yet! HYPRE_IJMatrixGetValues\n");
  }
  col_0 = col_starts[my_id];
  col_n = (col_starts[my_id + 1]) - 1;
  diag = (par_matrix)->diag;
  diag_i = (diag)->i;
  diag_j = (diag)->j;
  diag_data = (diag)->data;
  offd = (par_matrix)->offd;
  offd_i = (offd)->i;
  if (num_procs > 1) {
    offd_j = (offd)->j;
    offd_data = (offd)->data;
    col_map_offd = (par_matrix)->col_map_offd;
  }
  if (nrows < 0) {
    nrows = -nrows;
    counter = (int*)(hypre_CAlloc((unsigned)(nrows + 1), (unsigned)(sizeof(int))));
    counter[0] = 0;
    for (i = 0; i < nrows; i++)
      counter[i + 1] = (counter[i]) + (ncols[i]);
    indx = 0;
    for (i = 0; i < nrows; i++) {
      row = rows[i];
      if ((row >= (row_partitioning[my_id])) && (row < (row_partitioning[my_id + 1]))) {
        row_local = (int)(row - (row_partitioning[my_id]));
        row_size = (((diag_i[row_local + 1]) - (diag_i[row_local])) + (offd_i[row_local + 1])) - (offd_i[row_local]);
        if (((counter[i]) + row_size) > (counter[nrows])) {
          hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/IJMatrix_parcsr.c", 908, 4 | (1 << 3));
          printf("Error! Not enough memory! HYPRE_IJMatrixGetValues\n");
        }
        if ((ncols[i]) < row_size)
          warning = 1;
        for (j = diag_i[row_local]; j < (diag_i[row_local + 1]); j++) {
          cols[indx] = (int)(diag_j[j]) + col_0;
          values[indx++] = diag_data[j];
        }
        for (j = offd_i[row_local]; j < (offd_i[row_local + 1]); j++) {
          cols[indx] = col_map_offd[offd_j[j]];
          values[indx++] = offd_data[j];
        }
        counter[i + 1] = indx;
      }
      else
        printf("Warning! Row %d is not on Proc. %d!\n", row, my_id);
    }
    if (warning) {
      for (i = 0; i < nrows; i++)
        ncols[i] = (counter[i + 1]) - (counter[i]);
      printf("Warning!  ncols has been changed!\n");
    }
    hypre_Free((char*)counter), counter = (void*)0;
  }
  else {
    indx = 0;
    for (ii = 0; ii < nrows; ii++) {
      row = rows[ii];
      n = ncols[ii];
      if ((row >= (row_partitioning[my_id])) && (row < (row_partitioning[my_id + 1]))) {
        row_local = (int)(row - (row_partitioning[my_id]));
        for (i = 0; i < n; i++) {
          col_indx = (cols[indx]) - (col_partitioning[0]);
          values[indx] = 0.0;
          if ((col_indx < col_0) || (col_indx > col_n)) {
            for (j = offd_i[row_local]; j < (offd_i[row_local + 1]); j++) {
              if ((col_map_offd[offd_j[j]]) == col_indx) {
                values[indx] = offd_data[j];
                break;
              }
            }
          }
          else {
            col_indx = col_indx - col_0;
            for (j = diag_i[row_local]; j < (diag_i[row_local + 1]); j++) {
              if ((diag_j[j]) == (int)col_indx) {
                values[indx] = diag_data[j];
                break;
              }
            }
          }
          indx++;
        }
      }
      else
        printf("Warning! Row %d is not on Proc. %d!\n", row, my_id);
    }
  }
  return hypre__global_error;
}
int hypre_IJMatrixSetValuesParCSR(hypre_IJMatrix* matrix, int nrows, int* ncols, int* rows, int* cols, double* values) {
  hypre_ParCSRMatrix* par_matrix;
  hypre_CSRMatrix* diag;
  hypre_CSRMatrix* offd;
  hypre_AuxParCSRMatrix* aux_matrix;
  int* row_partitioning;
  int* col_partitioning;
  MPI_Comm comm = (matrix)->comm;
  int num_procs;
  int my_id;
  int row_local;
  int col_0;
  int col_n;
  int row;
  int i;
  int ii;
  int j;
  int n;
  int not_found;
  int** aux_j;
  int* local_j;
  int* tmp_j;
  double** aux_data;
  double* local_data;
  double* tmp_data;
  int diag_space;
  int offd_space;
  int* row_length;
  int* row_space;
  int need_aux;
  int tmp_indx;
  int indx;
  int space;
  int size;
  int old_size;
  int cnt;
  int cnt_diag;
  int cnt_offd;
  int pos_diag;
  int pos_offd;
  int len_diag;
  int len_offd;
  int offd_indx;
  int diag_indx;
  int* diag_i;
  int* diag_j;
  double* diag_data;
  int* offd_i;
  int* offd_j;
  int* aux_offd_j;
  double* offd_data;
  int first;
  int current_num_elmts;
  int max_off_proc_elmts;
  int off_proc_i_indx;
  int* off_proc_i;
  int* off_proc_j;
  double* off_proc_data;
  MPI_Comm_size(comm, &(num_procs));
  MPI_Comm_rank(comm, &(my_id));
  par_matrix = (matrix)->object;
  row_partitioning = (matrix)->row_partitioning;
  col_partitioning = (matrix)->col_partitioning;
  col_0 = col_partitioning[my_id];
  col_n = (col_partitioning[my_id + 1]) - 1;
  first = col_partitioning[0];
  if (nrows < 0) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/IJMatrix_parcsr.c", 908, 4 | (2 << 3));
    printf("Error! nrows negative! HYPRE_IJMatrixSetValues\n");
  }
  if ((matrix)->assemble_flag) {
    int* col_map_offd;
    int num_cols_offd;
    int j_offd;
    indx = 0;
    for (ii = 0; ii < nrows; ii++) {
      row = rows[ii];
      n = ncols[ii];
      if ((row >= (row_partitioning[my_id])) && (row < (row_partitioning[my_id + 1]))) {
        row_local = (int)(row - (row_partitioning[my_id]));
        diag = (par_matrix)->diag;
        diag_i = (diag)->i;
        diag_j = (diag)->j;
        diag_data = (diag)->data;
        offd = (par_matrix)->offd;
        offd_i = (offd)->i;
        num_cols_offd = (offd)->num_cols;
        if (num_cols_offd) {
          col_map_offd = (par_matrix)->col_map_offd;
          offd_j = (offd)->j;
          offd_data = (offd)->data;
        }
        size = (((diag_i[row_local + 1]) - (diag_i[row_local])) + (offd_i[row_local + 1])) - (offd_i[row_local]);
        if (n > size) {
          hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/IJMatrix_parcsr.c", 908, 1);
          printf(" row %d too long! \n", row);
          return hypre__global_error;
        }
        pos_diag = diag_i[row_local];
        pos_offd = offd_i[row_local];
        len_diag = diag_i[row_local + 1];
        len_offd = offd_i[row_local + 1];
        not_found = 1;
        for (i = 0; i < n; i++) {
          if (((cols[indx]) < col_0) || ((cols[indx]) > col_n)) {
            j_offd = hypre_BigBinarySearch(col_map_offd, (cols[indx]) - first, num_cols_offd);
            if (j_offd == (-1)) {
              hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/IJMatrix_parcsr.c", 908, 1);
              printf(" Error, element %d %d does not exist\n", row, cols[indx]);
              return hypre__global_error;
            }
            for (j = pos_offd; j < len_offd; j++) {
              if ((offd_j[j]) == j_offd) {
                offd_data[j] = values[indx];
                not_found = 0;
                break;
              }
            }
            if (not_found) {
              hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/IJMatrix_parcsr.c", 908, 1);
              printf(" Error, element %d %d does not exist\n", row, cols[indx]);
              return hypre__global_error;
            }
            not_found = 1;
          }
          else
            if ((cols[indx]) == row) {
              if ((diag_j[pos_diag]) != row_local) {
                hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/IJMatrix_parcsr.c", 908, 1);
                printf(" Error, element %d %d does not exist\n", row, cols[indx]);
                return hypre__global_error;
              }
              diag_data[pos_diag] = values[indx];
            }
            else {
              for (j = pos_diag; j < len_diag; j++) {
                if ((diag_j[j]) == (int)((cols[indx]) - col_0)) {
                  diag_data[j] = values[indx];
                  not_found = 0;
                  break;
                }
              }
              if (not_found) {
                hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/IJMatrix_parcsr.c", 908, 1);
                printf(" Error, element %d %d does not exist\n", row, cols[indx]);
                return hypre__global_error;
              }
            }
          indx++;
        }
      }
      else {
        aux_matrix = (matrix)->translator;
        if (!aux_matrix) {
          size = (int)((row_partitioning[my_id + 1]) - (row_partitioning[my_id]));
          hypre_AuxParCSRMatrixCreate(&(aux_matrix), size, size, (void*)0);
          (aux_matrix)->need_aux = 0;
          (matrix)->translator = aux_matrix;
        }
        current_num_elmts = (aux_matrix)->current_num_elmts;
        max_off_proc_elmts = (aux_matrix)->max_off_proc_elmts;
        off_proc_i_indx = (aux_matrix)->off_proc_i_indx;
        off_proc_i = (aux_matrix)->off_proc_i;
        off_proc_j = (aux_matrix)->off_proc_j;
        off_proc_data = (aux_matrix)->off_proc_data;
        if (!max_off_proc_elmts) {
          max_off_proc_elmts = n < 1000 ? 1000 : n;
          (aux_matrix)->max_off_proc_elmts = max_off_proc_elmts;
          (aux_matrix)->off_proc_i = (int*)(hypre_CAlloc((unsigned)(2 * max_off_proc_elmts), (unsigned)(sizeof(int))));
          (aux_matrix)->off_proc_j = (int*)(hypre_CAlloc((unsigned)max_off_proc_elmts, (unsigned)(sizeof(int))));
          (aux_matrix)->off_proc_data = (double*)(hypre_CAlloc((unsigned)max_off_proc_elmts, (unsigned)(sizeof(double))));
          off_proc_i = (aux_matrix)->off_proc_i;
          off_proc_j = (aux_matrix)->off_proc_j;
          off_proc_data = (aux_matrix)->off_proc_data;
        }
        else
          if ((current_num_elmts + n) > max_off_proc_elmts) {
            max_off_proc_elmts += 3 * n;
            off_proc_i = (int*)(hypre_ReAlloc((char*)off_proc_i, (unsigned)(sizeof(int) * (2 * max_off_proc_elmts))));
            off_proc_j = (int*)(hypre_ReAlloc((char*)off_proc_j, (unsigned)(sizeof(int) * max_off_proc_elmts)));
            off_proc_data = (double*)(hypre_ReAlloc((char*)off_proc_data, (unsigned)(sizeof(double) * max_off_proc_elmts)));
            (aux_matrix)->max_off_proc_elmts = max_off_proc_elmts;
            (aux_matrix)->off_proc_i = off_proc_i;
            (aux_matrix)->off_proc_j = off_proc_j;
            (aux_matrix)->off_proc_data = off_proc_data;
          }
        off_proc_i[off_proc_i_indx++] = row;
        off_proc_i[off_proc_i_indx++] = n;
        for (i = 0; i < n; i++) {
          off_proc_j[current_num_elmts] = cols[indx];
          off_proc_data[current_num_elmts++] = values[indx++];
        }
        (aux_matrix)->off_proc_i_indx = off_proc_i_indx;
        (aux_matrix)->current_num_elmts = current_num_elmts;
      }
    }
  }
  else {
    aux_matrix = (matrix)->translator;
    row_space = (aux_matrix)->row_space;
    row_length = (aux_matrix)->row_length;
    need_aux = (aux_matrix)->need_aux;
    indx = 0;
    for (ii = 0; ii < nrows; ii++) {
      row = rows[ii];
      n = ncols[ii];
      if ((row >= (row_partitioning[my_id])) && (row < (row_partitioning[my_id + 1]))) {
        row_local = (int)(row - (row_partitioning[my_id]));
        if (need_aux) {
          aux_j = (aux_matrix)->aux_j;
          aux_data = (aux_matrix)->aux_data;
          local_j = aux_j[row_local];
          local_data = aux_data[row_local];
          space = row_space[row_local];
          old_size = row_length[row_local];
          size = space - old_size;
          if (size < n) {
            size = n - size;
            tmp_j = (int*)(hypre_CAlloc((unsigned)size, (unsigned)(sizeof(int))));
            tmp_data = (double*)(hypre_CAlloc((unsigned)size, (unsigned)(sizeof(double))));
          }
          else {
            tmp_j = (void*)0;
          }
          tmp_indx = 0;
          not_found = 1;
          size = old_size;
          for (i = 0; i < n; i++) {
            for (j = 0; j < old_size; j++) {
              if ((local_j[j]) == (cols[indx])) {
                local_data[j] = values[indx];
                not_found = 0;
                break;
              }
            }
            if (not_found) {
              if (size < space) {
                local_j[size] = cols[indx];
                local_data[size++] = values[indx];
              }
              else {
                tmp_j[tmp_indx] = cols[indx];
                tmp_data[tmp_indx++] = values[indx];
              }
            }
            not_found = 1;
            indx++;
          }
          row_length[row_local] = size + tmp_indx;
          if (tmp_indx) {
            aux_j[row_local] = (int*)(hypre_ReAlloc((char*)(aux_j[row_local]), (unsigned)(sizeof(int) * (size + tmp_indx))));
            aux_data[row_local] = (double*)(hypre_ReAlloc((char*)(aux_data[row_local]), (unsigned)(sizeof(double) * (size + tmp_indx))));
            row_space[row_local] = size + tmp_indx;
            local_j = aux_j[row_local];
            local_data = aux_data[row_local];
          }
          cnt = size;
          for (i = 0; i < tmp_indx; i++) {
            local_j[cnt] = tmp_j[i];
            local_data[cnt++] = tmp_data[i];
          }
          if (tmp_j) {
            hypre_Free((char*)tmp_j), tmp_j = (void*)0;
            hypre_Free((char*)tmp_data), tmp_data = (void*)0;
          }
        }
        else {
          int col_j;
          offd_indx = (aux_matrix)->indx_offd[row_local];
          diag_indx = (aux_matrix)->indx_diag[row_local];
          diag = (par_matrix)->diag;
          diag_i = (diag)->i;
          diag_j = (diag)->j;
          diag_data = (diag)->data;
          offd = (par_matrix)->offd;
          offd_i = (offd)->i;
          if (num_procs > 1) {
            offd_j = (offd)->j;
            offd_data = (offd)->data;
            aux_offd_j = (aux_matrix)->aux_offd_j;
          }
          cnt_diag = diag_indx;
          cnt_offd = offd_indx;
          diag_space = diag_i[row_local + 1];
          offd_space = offd_i[row_local + 1];
          not_found = 1;
          for (i = 0; i < n; i++) {
            if (((cols[indx]) < col_0) || ((cols[indx]) > col_n)) {
              for (j = offd_i[row_local]; j < offd_indx; j++) {
                if ((aux_offd_j[j]) == (cols[indx])) {
                  offd_data[j] = values[indx];
                  not_found = 0;
                  break;
                }
              }
              if (not_found) {
                if (cnt_offd < offd_space) {
                  aux_offd_j[cnt_offd] = cols[indx];
                  offd_data[cnt_offd++] = values[indx];
                }
                else {
                  hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/IJMatrix_parcsr.c", 908, 1);
                  printf("Error in row %d ! Too many elements!\n", row);
                  return hypre__global_error;
                }
              }
              not_found = 1;
            }
            else {
              for (j = diag_i[row_local]; j < diag_indx; j++) {
                col_j = (int)((cols[indx]) - col_0);
                if ((diag_j[j]) == col_j) {
                  diag_data[j] = values[indx];
                  not_found = 0;
                  break;
                }
              }
              if (not_found) {
                if (cnt_diag < diag_space) {
                  diag_j[cnt_diag] = col_j;
                  diag_data[cnt_diag++] = values[indx];
                }
                else {
                  hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/IJMatrix_parcsr.c", 908, 1);
                  printf("Error in row %d ! Too many elements !\n", row);
                  return hypre__global_error;
                }
              }
              not_found = 1;
            }
            indx++;
          }
          (aux_matrix)->indx_diag[row_local] = cnt_diag;
          (aux_matrix)->indx_offd[row_local] = cnt_offd;
        }
      }
      else {
        current_num_elmts = (aux_matrix)->current_num_elmts;
        max_off_proc_elmts = (aux_matrix)->max_off_proc_elmts;
        off_proc_i_indx = (aux_matrix)->off_proc_i_indx;
        off_proc_i = (aux_matrix)->off_proc_i;
        off_proc_j = (aux_matrix)->off_proc_j;
        off_proc_data = (aux_matrix)->off_proc_data;
        if (!max_off_proc_elmts) {
          max_off_proc_elmts = n < 1000 ? 1000 : n;
          (aux_matrix)->max_off_proc_elmts = max_off_proc_elmts;
          (aux_matrix)->off_proc_i = (int*)(hypre_CAlloc((unsigned)(2 * max_off_proc_elmts), (unsigned)(sizeof(int))));
          (aux_matrix)->off_proc_j = (int*)(hypre_CAlloc((unsigned)max_off_proc_elmts, (unsigned)(sizeof(int))));
          (aux_matrix)->off_proc_data = (double*)(hypre_CAlloc((unsigned)max_off_proc_elmts, (unsigned)(sizeof(double))));
          off_proc_i = (aux_matrix)->off_proc_i;
          off_proc_j = (aux_matrix)->off_proc_j;
          off_proc_data = (aux_matrix)->off_proc_data;
        }
        else
          if ((current_num_elmts + n) > max_off_proc_elmts) {
            max_off_proc_elmts += 3 * n;
            off_proc_i = (int*)(hypre_ReAlloc((char*)off_proc_i, (unsigned)(sizeof(int) * (2 * max_off_proc_elmts))));
            off_proc_j = (int*)(hypre_ReAlloc((char*)off_proc_j, (unsigned)(sizeof(int) * max_off_proc_elmts)));
            off_proc_data = (double*)(hypre_ReAlloc((char*)off_proc_data, (unsigned)(sizeof(double) * max_off_proc_elmts)));
            (aux_matrix)->max_off_proc_elmts = max_off_proc_elmts;
            (aux_matrix)->off_proc_i = off_proc_i;
            (aux_matrix)->off_proc_j = off_proc_j;
            (aux_matrix)->off_proc_data = off_proc_data;
          }
        off_proc_i[off_proc_i_indx++] = row;
        off_proc_i[off_proc_i_indx++] = n;
        for (i = 0; i < n; i++) {
          off_proc_j[current_num_elmts] = cols[indx];
          off_proc_data[current_num_elmts++] = values[indx++];
        }
        (aux_matrix)->off_proc_i_indx = off_proc_i_indx;
        (aux_matrix)->current_num_elmts = current_num_elmts;
      }
    }
  }
  return hypre__global_error;
}
int hypre_IJMatrixAddToValuesParCSR(hypre_IJMatrix* matrix, int nrows, int* ncols, int* rows, int* cols, double* values) {
  hypre_ParCSRMatrix* par_matrix;
  hypre_CSRMatrix* diag;
  hypre_CSRMatrix* offd;
  hypre_AuxParCSRMatrix* aux_matrix;
  int* row_partitioning;
  int* col_partitioning;
  MPI_Comm comm = (matrix)->comm;
  int num_procs;
  int my_id;
  int row_local;
  int row;
  int col_0;
  int col_n;
  int i;
  int ii;
  int j;
  int n;
  int not_found;
  int col_j;
  int** aux_j;
  int* local_j;
  int* tmp_j;
  double** aux_data;
  double* local_data;
  double* tmp_data;
  int diag_space;
  int offd_space;
  int* row_length;
  int* row_space;
  int need_aux;
  int tmp_indx;
  int indx;
  int space;
  int size;
  int old_size;
  int cnt;
  int cnt_diag;
  int cnt_offd;
  int pos_diag;
  int pos_offd;
  int len_diag;
  int len_offd;
  int offd_indx;
  int diag_indx;
  int first;
  int* diag_i;
  int* diag_j;
  double* diag_data;
  int* offd_i;
  int* offd_j;
  int* aux_offd_j;
  double* offd_data;
  int current_num_elmts;
  int max_off_proc_elmts;
  int off_proc_i_indx;
  int* off_proc_i;
  int* off_proc_j;
  double* off_proc_data;
  MPI_Comm_size(comm, &(num_procs));
  MPI_Comm_rank(comm, &(my_id));
  par_matrix = (matrix)->object;
  row_partitioning = (matrix)->row_partitioning;
  col_partitioning = (matrix)->col_partitioning;
  col_0 = col_partitioning[my_id];
  col_n = (col_partitioning[my_id + 1]) - 1;
  first = col_partitioning[0];
  if ((matrix)->assemble_flag) {
    int num_cols_offd;
    int* col_map_offd;
    int j_offd;
    indx = 0;
    aux_matrix = (matrix)->translator;
    for (ii = 0; ii < nrows; ii++) {
      row = rows[ii];
      n = ncols[ii];
      if ((row >= (row_partitioning[my_id])) && (row < (row_partitioning[my_id + 1]))) {
        row_local = (int)(row - (row_partitioning[my_id]));
        diag = (par_matrix)->diag;
        diag_i = (diag)->i;
        diag_j = (diag)->j;
        diag_data = (diag)->data;
        offd = (par_matrix)->offd;
        offd_i = (offd)->i;
        num_cols_offd = (offd)->num_cols;
        if (num_cols_offd) {
          col_map_offd = (par_matrix)->col_map_offd;
          offd_j = (offd)->j;
          offd_data = (offd)->data;
        }
        size = (((diag_i[row_local + 1]) - (diag_i[row_local])) + (offd_i[row_local + 1])) - (offd_i[row_local]);
        if (n > size) {
          hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/IJMatrix_parcsr.c", 908, 1);
          printf(" row %d too long! \n", row);
          return hypre__global_error;
        }
        pos_diag = diag_i[row_local];
        pos_offd = offd_i[row_local];
        len_diag = diag_i[row_local + 1];
        len_offd = offd_i[row_local + 1];
        not_found = 1;
        for (i = 0; i < n; i++) {
          if (((cols[indx]) < col_0) || ((cols[indx]) > col_n)) {
            j_offd = hypre_BigBinarySearch(col_map_offd, (cols[indx]) - first, num_cols_offd);
            if (j_offd == (-1)) {
              hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/IJMatrix_parcsr.c", 908, 1);
              printf(" Error, element %d %d does not exist\n", row, cols[indx]);
              return hypre__global_error;
            }
            for (j = pos_offd; j < len_offd; j++) {
              if ((offd_j[j]) == j_offd) {
                offd_data[j] += values[indx];
                not_found = 0;
                break;
              }
            }
            if (not_found) {
              hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/IJMatrix_parcsr.c", 908, 1);
              printf(" Error, element %d %d does not exist\n", row, cols[indx]);
              return hypre__global_error;
            }
            not_found = 1;
          }
          else
            if ((cols[indx]) == row) {
              if ((diag_j[pos_diag]) != row_local) {
                hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/IJMatrix_parcsr.c", 908, 1);
                printf(" Error, element %d %d does not exist\n", row, cols[indx]);
                return hypre__global_error;
              }
              diag_data[pos_diag] += values[indx];
            }
            else {
              for (j = pos_diag; j < len_diag; j++) {
                if ((diag_j[j]) == (int)((cols[indx]) - col_0)) {
                  diag_data[j] += values[indx];
                  not_found = 0;
                  break;
                }
              }
              if (not_found) {
                hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/IJMatrix_parcsr.c", 908, 1);
                printf(" Error, element %d %d does not exist\n", row, cols[indx]);
                return hypre__global_error;
              }
            }
          indx++;
        }
      }
      else {
        if (!aux_matrix) {
          size = (int)((row_partitioning[my_id + 1]) - (row_partitioning[my_id]));
          hypre_AuxParCSRMatrixCreate(&(aux_matrix), size, size, (void*)0);
          (aux_matrix)->need_aux = 0;
          (matrix)->translator = aux_matrix;
        }
        current_num_elmts = (aux_matrix)->current_num_elmts;
        max_off_proc_elmts = (aux_matrix)->max_off_proc_elmts;
        off_proc_i_indx = (aux_matrix)->off_proc_i_indx;
        off_proc_i = (aux_matrix)->off_proc_i;
        off_proc_j = (aux_matrix)->off_proc_j;
        off_proc_data = (aux_matrix)->off_proc_data;
        if (!max_off_proc_elmts) {
          max_off_proc_elmts = n < 1000 ? 1000 : n;
          (aux_matrix)->max_off_proc_elmts = max_off_proc_elmts;
          (aux_matrix)->off_proc_i = (int*)(hypre_CAlloc((unsigned)(2 * max_off_proc_elmts), (unsigned)(sizeof(int))));
          (aux_matrix)->off_proc_j = (int*)(hypre_CAlloc((unsigned)max_off_proc_elmts, (unsigned)(sizeof(int))));
          (aux_matrix)->off_proc_data = (double*)(hypre_CAlloc((unsigned)max_off_proc_elmts, (unsigned)(sizeof(double))));
          off_proc_i = (aux_matrix)->off_proc_i;
          off_proc_j = (aux_matrix)->off_proc_j;
          off_proc_data = (aux_matrix)->off_proc_data;
        }
        else
          if ((current_num_elmts + n) > max_off_proc_elmts) {
            max_off_proc_elmts += 3 * n;
            off_proc_i = (int*)(hypre_ReAlloc((char*)off_proc_i, (unsigned)(sizeof(int) * (2 * max_off_proc_elmts))));
            off_proc_j = (int*)(hypre_ReAlloc((char*)off_proc_j, (unsigned)(sizeof(int) * max_off_proc_elmts)));
            off_proc_data = (double*)(hypre_ReAlloc((char*)off_proc_data, (unsigned)(sizeof(double) * max_off_proc_elmts)));
            (aux_matrix)->max_off_proc_elmts = max_off_proc_elmts;
            (aux_matrix)->off_proc_i = off_proc_i;
            (aux_matrix)->off_proc_j = off_proc_j;
            (aux_matrix)->off_proc_data = off_proc_data;
          }
        off_proc_i[off_proc_i_indx++] = (-row) - 1;
        off_proc_i[off_proc_i_indx++] = n;
        for (i = 0; i < n; i++) {
          off_proc_j[current_num_elmts] = cols[indx];
          off_proc_data[current_num_elmts++] = values[indx++];
        }
        (aux_matrix)->off_proc_i_indx = off_proc_i_indx;
        (aux_matrix)->current_num_elmts = current_num_elmts;
      }
    }
  }
  else {
    aux_matrix = (matrix)->translator;
    row_space = (aux_matrix)->row_space;
    row_length = (aux_matrix)->row_length;
    need_aux = (aux_matrix)->need_aux;
    indx = 0;
    for (ii = 0; ii < nrows; ii++) {
      row = rows[ii];
      n = ncols[ii];
      if ((row >= (row_partitioning[my_id])) && (row < (row_partitioning[my_id + 1]))) {
        row_local = (int)(row - (row_partitioning[my_id]));
        if (need_aux) {
          aux_j = (aux_matrix)->aux_j;
          aux_data = (aux_matrix)->aux_data;
          local_j = aux_j[row_local];
          local_data = aux_data[row_local];
          space = row_space[row_local];
          old_size = row_length[row_local];
          size = space - old_size;
          if (size < n) {
            size = n - size;
            tmp_j = (int*)(hypre_CAlloc((unsigned)size, (unsigned)(sizeof(int))));
            tmp_data = (double*)(hypre_CAlloc((unsigned)size, (unsigned)(sizeof(double))));
          }
          else {
            tmp_j = (void*)0;
          }
          tmp_indx = 0;
          not_found = 1;
          size = old_size;
          for (i = 0; i < n; i++) {
            for (j = 0; j < old_size; j++) {
              if ((local_j[j]) == (cols[indx])) {
                local_data[j] += values[indx];
                not_found = 0;
                break;
              }
            }
            if (not_found) {
              if (size < space) {
                local_j[size] = cols[indx];
                local_data[size++] = values[indx];
              }
              else {
                tmp_j[tmp_indx] = cols[indx];
                tmp_data[tmp_indx++] = values[indx];
              }
            }
            not_found = 1;
            indx++;
          }
          row_length[row_local] = size + tmp_indx;
          if (tmp_indx) {
            aux_j[row_local] = (int*)(hypre_ReAlloc((char*)(aux_j[row_local]), (unsigned)(sizeof(int) * (size + tmp_indx))));
            aux_data[row_local] = (double*)(hypre_ReAlloc((char*)(aux_data[row_local]), (unsigned)(sizeof(double) * (size + tmp_indx))));
            row_space[row_local] = size + tmp_indx;
            local_j = aux_j[row_local];
            local_data = aux_data[row_local];
          }
          cnt = size;
          for (i = 0; i < tmp_indx; i++) {
            local_j[cnt] = tmp_j[i];
            local_data[cnt++] = tmp_data[i];
          }
          if (tmp_j) {
            hypre_Free((char*)tmp_j), tmp_j = (void*)0;
            hypre_Free((char*)tmp_data), tmp_data = (void*)0;
          }
        }
        else {
          offd_indx = (aux_matrix)->indx_offd[row_local];
          diag_indx = (aux_matrix)->indx_diag[row_local];
          diag = (par_matrix)->diag;
          diag_i = (diag)->i;
          diag_j = (diag)->j;
          diag_data = (diag)->data;
          offd = (par_matrix)->offd;
          offd_i = (offd)->i;
          if (num_procs > 1) {
            offd_j = (offd)->j;
            offd_data = (offd)->data;
            aux_offd_j = (aux_matrix)->aux_offd_j;
          }
          cnt_diag = diag_indx;
          cnt_offd = offd_indx;
          diag_space = diag_i[row_local + 1];
          offd_space = offd_i[row_local + 1];
          not_found = 1;
          for (i = 0; i < n; i++) {
            if (((cols[indx]) < col_0) || ((cols[indx]) > col_n)) {
              for (j = offd_i[row_local]; j < offd_indx; j++) {
                if ((aux_offd_j[j]) == (cols[indx])) {
                  offd_data[j] += values[indx];
                  not_found = 0;
                  break;
                }
              }
              if (not_found) {
                if (cnt_offd < offd_space) {
                  aux_offd_j[cnt_offd] = cols[indx];
                  offd_data[cnt_offd++] = values[indx];
                }
                else {
                  hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/IJMatrix_parcsr.c", 908, 1);
                  printf("Error in row %d ! Too many elements!\n", row);
                  return hypre__global_error;
                }
              }
              not_found = 1;
            }
            else {
              for (j = diag_i[row_local]; j < diag_indx; j++) {
                col_j = (int)((cols[indx]) - col_0);
                if ((diag_j[j]) == col_j) {
                  diag_data[j] += values[indx];
                  not_found = 0;
                  break;
                }
              }
              if (not_found) {
                if (cnt_diag < diag_space) {
                  diag_j[cnt_diag] = col_j;
                  diag_data[cnt_diag++] = values[indx];
                }
                else {
                  hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/IJMatrix_parcsr.c", 908, 1);
                  printf("Error in row %d ! Too many elements !\n", row);
                  return hypre__global_error;
                }
              }
              not_found = 1;
            }
            indx++;
          }
          (aux_matrix)->indx_diag[row_local] = cnt_diag;
          (aux_matrix)->indx_offd[row_local] = cnt_offd;
        }
      }
      else {
        current_num_elmts = (aux_matrix)->current_num_elmts;
        max_off_proc_elmts = (aux_matrix)->max_off_proc_elmts;
        off_proc_i_indx = (aux_matrix)->off_proc_i_indx;
        off_proc_i = (aux_matrix)->off_proc_i;
        off_proc_j = (aux_matrix)->off_proc_j;
        off_proc_data = (aux_matrix)->off_proc_data;
        if (!max_off_proc_elmts) {
          max_off_proc_elmts = n < 1000 ? 1000 : n;
          (aux_matrix)->max_off_proc_elmts = max_off_proc_elmts;
          (aux_matrix)->off_proc_i = (int*)(hypre_CAlloc((unsigned)(2 * max_off_proc_elmts), (unsigned)(sizeof(int))));
          (aux_matrix)->off_proc_j = (int*)(hypre_CAlloc((unsigned)max_off_proc_elmts, (unsigned)(sizeof(int))));
          (aux_matrix)->off_proc_data = (double*)(hypre_CAlloc((unsigned)max_off_proc_elmts, (unsigned)(sizeof(double))));
          off_proc_i = (aux_matrix)->off_proc_i;
          off_proc_j = (aux_matrix)->off_proc_j;
          off_proc_data = (aux_matrix)->off_proc_data;
        }
        else
          if ((current_num_elmts + n) > max_off_proc_elmts) {
            max_off_proc_elmts += 3 * n;
            off_proc_i = (int*)(hypre_ReAlloc((char*)off_proc_i, (unsigned)(sizeof(int) * (2 * max_off_proc_elmts))));
            off_proc_j = (int*)(hypre_ReAlloc((char*)off_proc_j, (unsigned)(sizeof(int) * max_off_proc_elmts)));
            off_proc_data = (double*)(hypre_ReAlloc((char*)off_proc_data, (unsigned)(sizeof(double) * max_off_proc_elmts)));
            (aux_matrix)->max_off_proc_elmts = max_off_proc_elmts;
            (aux_matrix)->off_proc_i = off_proc_i;
            (aux_matrix)->off_proc_j = off_proc_j;
            (aux_matrix)->off_proc_data = off_proc_data;
          }
        off_proc_i[off_proc_i_indx++] = (-row) - 1;
        off_proc_i[off_proc_i_indx++] = n;
        for (i = 0; i < n; i++) {
          off_proc_j[current_num_elmts] = cols[indx];
          off_proc_data[current_num_elmts++] = values[indx++];
        }
        (aux_matrix)->off_proc_i_indx = off_proc_i_indx;
        (aux_matrix)->current_num_elmts = current_num_elmts;
      }
    }
  }
  return hypre__global_error;
}
int hypre_IJMatrixAssembleParCSR(hypre_IJMatrix* matrix) {
  MPI_Comm comm = (matrix)->comm;
  hypre_ParCSRMatrix* par_matrix = (matrix)->object;
  hypre_AuxParCSRMatrix* aux_matrix = (matrix)->translator;
  int* row_partitioning = (matrix)->row_partitioning;
  int* col_partitioning = (matrix)->col_partitioning;
  hypre_CSRMatrix* diag = (par_matrix)->diag;
  hypre_CSRMatrix* offd = (par_matrix)->offd;
  int* diag_i = (diag)->i;
  int* offd_i = (offd)->i;
  int* diag_j;
  int* offd_j = (void*)0;
  double* diag_data;
  double* offd_data = (void*)0;
  int i;
  int j;
  int j0;
  int num_cols_offd;
  int* diag_pos;
  int* col_map_offd;
  int* row_length;
  int** aux_j;
  double** aux_data;
  int my_id;
  int num_procs;
  int num_rows;
  int i_diag;
  int i_offd;
  int* local_j;
  double* local_data;
  int col_0;
  int col_n;
  int nnz_offd;
  int* aux_offd_j;
  int* tmp_j;
  double temp;
  int base = col_partitioning[0];
  int off_proc_i_indx;
  int max_off_proc_elmts;
  int current_num_elmts;
  int* off_proc_i;
  int* off_proc_j;
  double* off_proc_data;
  int offd_proc_elmts;
  if (aux_matrix) {
    off_proc_i_indx = (aux_matrix)->off_proc_i_indx;
    MPI_Allreduce(&(off_proc_i_indx), &(offd_proc_elmts), 1, MPI_INT, _SUM, comm);
    if (offd_proc_elmts) {
      max_off_proc_elmts = (aux_matrix)->max_off_proc_elmts;
      current_num_elmts = (aux_matrix)->current_num_elmts;
      off_proc_i = (aux_matrix)->off_proc_i;
      off_proc_j = (aux_matrix)->off_proc_j;
      off_proc_data = (aux_matrix)->off_proc_data;
      hypre_IJMatrixAssembleOffProcValsParCSR(matrix, off_proc_i_indx, max_off_proc_elmts, current_num_elmts, off_proc_i, off_proc_j, off_proc_data);
    }
  }
  if ((matrix)->assemble_flag == 0) {
    MPI_Comm_size(comm, &(num_procs));
    MPI_Comm_rank(comm, &(my_id));
    num_rows = (int)((row_partitioning[my_id + 1]) - (row_partitioning[my_id]));
    col_0 = col_partitioning[my_id];
    col_n = (col_partitioning[my_id + 1]) - 1;
    if ((aux_matrix)->need_aux) {
      aux_j = (aux_matrix)->aux_j;
      aux_data = (aux_matrix)->aux_data;
      row_length = (aux_matrix)->row_length;
      diag_pos = (int*)(hypre_CAlloc((unsigned)num_rows, (unsigned)(sizeof(int))));
      i_diag = 0;
      i_offd = 0;
      for (i = 0; i < num_rows; i++) {
        local_j = aux_j[i];
        local_data = aux_data[i];
        diag_pos[i] = -1;
        for (j = 0; j < (row_length[i]); j++) {
          if (((local_j[j]) < col_0) || ((local_j[j]) > col_n))
            i_offd++;
          else {
            i_diag++;
            if ((int)((local_j[j]) - col_0) == i)
              diag_pos[i] = j;
          }
        }
        diag_i[i + 1] = i_diag;
        offd_i[i + 1] = i_offd;
      }
      if ((diag)->j)
        hypre_Free((char*)((diag)->j)), (diag)->j = (void*)0;
      if ((diag)->data)
        hypre_Free((char*)((diag)->data)), (diag)->data = (void*)0;
      if ((offd)->j)
        hypre_Free((char*)((offd)->j)), (offd)->j = (void*)0;
      if ((offd)->data)
        hypre_Free((char*)((offd)->data)), (offd)->data = (void*)0;
      diag_j = (int*)(hypre_CAlloc((unsigned)i_diag, (unsigned)(sizeof(int))));
      diag_data = (double*)(hypre_CAlloc((unsigned)i_diag, (unsigned)(sizeof(double))));
      if (i_offd > 0) {
        offd_j = (int*)(hypre_CAlloc((unsigned)i_offd, (unsigned)(sizeof(int))));
        offd_data = (double*)(hypre_CAlloc((unsigned)i_offd, (unsigned)(sizeof(double))));
        aux_offd_j = (int*)(hypre_CAlloc((unsigned)i_offd, (unsigned)(sizeof(int))));
        tmp_j = (int*)(hypre_CAlloc((unsigned)i_offd, (unsigned)(sizeof(int))));
      }
      i_diag = 0;
      i_offd = 0;
      for (i = 0; i < num_rows; i++) {
        local_j = aux_j[i];
        local_data = aux_data[i];
        if ((diag_pos[i]) > (-1)) {
          diag_j[i_diag] = (int)((local_j[diag_pos[i]]) - col_0);
          diag_data[i_diag++] = local_data[diag_pos[i]];
        }
        for (j = 0; j < (row_length[i]); j++) {
          if (((local_j[j]) < col_0) || ((local_j[j]) > col_n)) {
            aux_offd_j[i_offd] = local_j[j];
            tmp_j[i_offd] = aux_offd_j[i_offd];
            offd_data[i_offd++] = local_data[j];
          }
          else
            if (j != (diag_pos[i])) {
              diag_j[i_diag] = (int)((local_j[j]) - col_0);
              diag_data[i_diag++] = local_data[j];
            }
        }
      }
      (diag)->j = diag_j;
      (diag)->data = diag_data;
      (diag)->num_nonzeros = diag_i[num_rows];
      if (i_offd > 0) {
        (offd)->j = offd_j;
        (offd)->data = offd_data;
      }
      (offd)->num_nonzeros = offd_i[num_rows];
      hypre_Free((char*)diag_pos), diag_pos = (void*)0;
    }
    else {
      diag_j = (diag)->j;
      diag_data = (diag)->data;
      for (i = 0; i < num_rows; i++) {
        j0 = diag_i[i];
        for (j = j0; j < (diag_i[i + 1]); j++) {
          if ((diag_j[j]) == i) {
            temp = diag_data[j0];
            diag_data[j0] = diag_data[j];
            diag_data[j] = temp;
            diag_j[j] = diag_j[j0];
            diag_j[j0] = i;
          }
        }
      }
      offd_j = (offd)->j;
    }
    hypre_CSRMatrixSetRownnz(diag);
    hypre_CSRMatrixSetRownnz(offd);
    nnz_offd = offd_i[num_rows];
    if (nnz_offd) {
      hypre_BigQsort0(tmp_j, 0, nnz_offd - 1);
      num_cols_offd = 1;
      for (i = 0; i < (nnz_offd - 1); i++) {
        if ((tmp_j[i + 1]) > (tmp_j[i])) {
          tmp_j[num_cols_offd] = tmp_j[i + 1];
          num_cols_offd++;
        }
      }
      col_map_offd = (int*)(hypre_CAlloc((unsigned)num_cols_offd, (unsigned)(sizeof(int))));
      for (i = 0; i < num_cols_offd; i++)
        col_map_offd[i] = tmp_j[i];
      for (i = 0; i < nnz_offd; i++) {
        offd_j[i] = hypre_BigBinarySearch(col_map_offd, aux_offd_j[i], num_cols_offd);
      }
      if (base) {
        for (i = 0; i < num_cols_offd; i++)
          (col_map_offd[i]) -= base;
      }
      (par_matrix)->col_map_offd = col_map_offd;
      (offd)->num_cols = num_cols_offd;
      hypre_Free((char*)aux_offd_j), aux_offd_j = (void*)0;
      hypre_Free((char*)tmp_j), tmp_j = (void*)0;
    }
    hypre_AuxParCSRMatrixDestroy(aux_matrix);
    (matrix)->translator = (void*)0;
    (matrix)->assemble_flag = 1;
  }
  return hypre__global_error;
}
int hypre_IJMatrixDestroyParCSR(hypre_IJMatrix* matrix) {
  hypre_ParCSRMatrixDestroy((matrix)->object);
  hypre_AuxParCSRMatrixDestroy((matrix)->translator);
  return hypre__global_error;
}
int hypre_IJMatrixAssembleOffProcValsParCSR(hypre_IJMatrix* matrix, int off_proc_i_indx, int max_off_proc_elmts, int current_num_elmts, int* off_proc_i, int* off_proc_j, double* off_proc_data) {
  MPI_Comm comm = (matrix)->comm;
  MPI_Request* requests;
  MPI_Status* status;
  int i;
  int ii;
  int j;
  int j2;
  int jj;
  int n;
  int row;
  int iii;
  int iid;
  int indx;
  int ip;
  int proc_id;
  int num_procs;
  int my_id;
  int num_sends;
  int num_sends3;
  int num_recvs;
  int num_requests;
  int vec_start;
  int vec_len;
  int* send_procs;
  int* chunks;
  int* send_i;
  int* send_map_starts;
  int* dbl_send_map_starts;
  int* recv_procs;
  int* recv_chunks;
  int* recv_i;
  int* recv_vec_starts;
  int* dbl_recv_vec_starts;
  int* info;
  int* int_buffer;
  int* proc_id_mem;
  int* partitioning;
  int* displs;
  int* recv_buf;
  double* send_data;
  double* recv_data;
  MPI_Comm_size(comm, &(num_procs));
  MPI_Comm_rank(comm, &(my_id));
  partitioning = (matrix)->row_partitioning;
  info = (int*)(hypre_CAlloc((unsigned)num_procs, (unsigned)(sizeof(int))));
  chunks = (int*)(hypre_CAlloc((unsigned)num_procs, (unsigned)(sizeof(int))));
  proc_id_mem = (int*)(hypre_CAlloc((unsigned)(off_proc_i_indx / 2), (unsigned)(sizeof(int))));
  j = 0;
  for (i = 0; i < off_proc_i_indx; i++) {
    row = off_proc_i[i++];
    if (row < 0)
      row = (-row) - 1;
    n = (int)(off_proc_i[i]);
    proc_id = hypre_FindProc(partitioning, row, num_procs);
    proc_id_mem[j++] = proc_id;
    info[proc_id] += n;
    chunks[proc_id]++;
  }
  num_sends = 0;
  for (i = 0; i < num_procs; i++) {
    if (info[i]) {
      num_sends++;
    }
  }
  send_procs = (int*)(hypre_CAlloc((unsigned)num_sends, (unsigned)(sizeof(int))));
  send_map_starts = (int*)(hypre_CAlloc((unsigned)(num_sends + 1), (unsigned)(sizeof(int))));
  dbl_send_map_starts = (int*)(hypre_CAlloc((unsigned)(num_sends + 1), (unsigned)(sizeof(int))));
  num_sends3 = 3 * num_sends;
  int_buffer = (int*)(hypre_CAlloc((unsigned)(3 * num_sends), (unsigned)(sizeof(int))));
  j = 0;
  j2 = 0;
  send_map_starts[0] = 0;
  dbl_send_map_starts[0] = 0;
  for (i = 0; i < num_procs; i++) {
    if (info[i]) {
      send_procs[j++] = i;
      send_map_starts[j] = ((send_map_starts[j - 1]) + (2 * (chunks[i]))) + (info[i]);
      dbl_send_map_starts[j] = (dbl_send_map_starts[j - 1]) + (info[i]);
      int_buffer[j2++] = i;
      int_buffer[j2++] = chunks[i];
      int_buffer[j2++] = info[i];
    }
  }
  hypre_Free((char*)chunks), chunks = (void*)0;
  MPI_Allgather(&(num_sends3), 1, MPI_INT, info, 1, MPI_INT, comm);
  displs = (int*)(hypre_CAlloc((unsigned)(num_procs + 1), (unsigned)(sizeof(int))));
  displs[0] = 0;
  for (i = 1; i < (num_procs + 1); i++)
    displs[i] = (displs[i - 1]) + (info[i - 1]);
  recv_buf = (int*)(hypre_CAlloc((unsigned)(displs[num_procs]), (unsigned)(sizeof(int))));
  MPI_Allgatherv(int_buffer, num_sends3, MPI_INT, recv_buf, info, displs, MPI_INT, comm);
  hypre_Free((char*)int_buffer), int_buffer = (void*)0;
  hypre_Free((char*)info), info = (void*)0;
  num_recvs = 0;
  for (j = 0; j < (displs[num_procs]); j += 3) {
    if ((recv_buf[j]) == my_id)
      num_recvs++;
  }
  recv_procs = (int*)(hypre_CAlloc((unsigned)num_recvs, (unsigned)(sizeof(int))));
  recv_chunks = (int*)(hypre_CAlloc((unsigned)num_recvs, (unsigned)(sizeof(int))));
  recv_vec_starts = (int*)(hypre_CAlloc((unsigned)(num_recvs + 1), (unsigned)(sizeof(int))));
  dbl_recv_vec_starts = (int*)(hypre_CAlloc((unsigned)(num_recvs + 1), (unsigned)(sizeof(int))));
  j2 = 0;
  recv_vec_starts[0] = 0;
  dbl_recv_vec_starts[0] = 0;
  for (i = 0; i < num_procs; i++) {
    for (j = displs[i]; j < (displs[i + 1]); j += 3) {
      if ((recv_buf[j]) == my_id) {
        recv_procs[j2] = i;
        recv_chunks[j2++] = recv_buf[j + 1];
        recv_vec_starts[j2] = ((recv_vec_starts[j2 - 1]) + (2 * (recv_buf[j + 1]))) + (recv_buf[j + 2]);
        dbl_recv_vec_starts[j2] = (dbl_recv_vec_starts[j2 - 1]) + (recv_buf[j + 2]);
      }
      if (j2 == num_recvs)
        break;
    }
  }
  hypre_Free((char*)recv_buf), recv_buf = (void*)0;
  hypre_Free((char*)displs), displs = (void*)0;
  send_i = (int*)(hypre_CAlloc((unsigned)(send_map_starts[num_sends]), (unsigned)(sizeof(int))));
  send_data = (double*)(hypre_CAlloc((unsigned)(dbl_send_map_starts[num_sends]), (unsigned)(sizeof(double))));
  recv_i = (int*)(hypre_CAlloc((unsigned)(recv_vec_starts[num_recvs]), (unsigned)(sizeof(int))));
  recv_data = (double*)(hypre_CAlloc((unsigned)(dbl_recv_vec_starts[num_recvs]), (unsigned)(sizeof(double))));
  j = 0;
  jj = 0;
  for (i = 0; i < off_proc_i_indx; i++) {
    row = off_proc_i[i++];
    n = (int)(off_proc_i[i]);
    proc_id = proc_id_mem[i / 2];
    indx = hypre_BinarySearch(send_procs, proc_id, num_sends);
    iii = send_map_starts[indx];
    iid = dbl_send_map_starts[indx];
    send_i[iii++] = row;
    send_i[iii++] = (int)n;
    for (ii = 0; ii < n; ii++) {
      send_i[iii++] = off_proc_j[jj];
      send_data[iid++] = off_proc_data[jj++];
    }
    send_map_starts[indx] = iii;
    dbl_send_map_starts[indx] = iid;
  }
  hypre_Free((char*)proc_id_mem), proc_id_mem = (void*)0;
  for (i = num_sends; i > 0; i--) {
    send_map_starts[i] = send_map_starts[i - 1];
    dbl_send_map_starts[i] = dbl_send_map_starts[i - 1];
  }
  send_map_starts[0] = 0;
  dbl_send_map_starts[0] = 0;
  num_requests = num_recvs + num_sends;
  requests = (MPI_Request*)(hypre_CAlloc((unsigned)num_requests, (unsigned)(sizeof(MPI_Request))));
  status = (MPI_Status*)(hypre_CAlloc((unsigned)num_requests, (unsigned)(sizeof(MPI_Status))));
  j = 0;
  for (i = 0; i < num_recvs; i++) {
    vec_start = recv_vec_starts[i];
    vec_len = (recv_vec_starts[i + 1]) - vec_start;
    ip = recv_procs[i];
    MPI_Irecv(&(recv_i[vec_start]), vec_len, MPI_INT, ip, 0, comm, &(requests[j++]));
  }
  for (i = 0; i < num_sends; i++) {
    vec_start = send_map_starts[i];
    vec_len = (send_map_starts[i + 1]) - vec_start;
    ip = send_procs[i];
    MPI_Isend(&(send_i[vec_start]), vec_len, MPI_INT, ip, 0, comm, &(requests[j++]));
  }
  if (num_requests) {
    MPI_Waitall(num_requests, requests, status);
  }
  j = 0;
  for (i = 0; i < num_recvs; i++) {
    vec_start = dbl_recv_vec_starts[i];
    vec_len = (dbl_recv_vec_starts[i + 1]) - vec_start;
    ip = recv_procs[i];
    MPI_Irecv(&(recv_data[vec_start]), vec_len, MPI_DOUBLE, ip, 0, comm, &(requests[j++]));
  }
  for (i = 0; i < num_sends; i++) {
    vec_start = dbl_send_map_starts[i];
    vec_len = (dbl_send_map_starts[i + 1]) - vec_start;
    ip = send_procs[i];
    MPI_Isend(&(send_data[vec_start]), vec_len, MPI_DOUBLE, ip, 0, comm, &(requests[j++]));
  }
  if (num_requests) {
    MPI_Waitall(num_requests, requests, status);
    hypre_Free((char*)requests), requests = (void*)0;
    hypre_Free((char*)status), status = (void*)0;
  }
  hypre_Free((char*)send_i), send_i = (void*)0;
  hypre_Free((char*)send_data), send_data = (void*)0;
  hypre_Free((char*)send_procs), send_procs = (void*)0;
  hypre_Free((char*)send_map_starts), send_map_starts = (void*)0;
  hypre_Free((char*)dbl_send_map_starts), dbl_send_map_starts = (void*)0;
  hypre_Free((char*)recv_procs), recv_procs = (void*)0;
  hypre_Free((char*)recv_vec_starts), recv_vec_starts = (void*)0;
  hypre_Free((char*)dbl_recv_vec_starts), dbl_recv_vec_starts = (void*)0;
  j = 0;
  j2 = 0;
  for (i = 0; i < num_recvs; i++) {
    for (ii = 0; ii < (recv_chunks[i]); ii++) {
      row = recv_i[j];
      if (row < 0) {
        row = (-row) - 1;
        hypre_IJMatrixAddToValuesParCSR(matrix, 1, (int*)(&(recv_i[j + 1])), &(row), &(recv_i[j + 2]), &(recv_data[j2]));
        j2 += recv_i[j + 1];
        j += (recv_i[j + 1]) + 2;
      }
      else {
        hypre_IJMatrixSetValuesParCSR(matrix, 1, (int*)(&(recv_i[j + 1])), &(row), &(recv_i[j + 2]), &(recv_data[j2]));
        j2 += recv_i[j + 1];
        j += (recv_i[j + 1]) + 2;
      }
    }
  }
  hypre_Free((char*)recv_chunks), recv_chunks = (void*)0;
  hypre_Free((char*)recv_i), recv_i = (void*)0;
  hypre_Free((char*)recv_data), recv_data = (void*)0;
  return hypre__global_error;
}
int hypre_FindProc(int* list, int value, int list_length) {
  int low;
  int high;
  int m;
  low = 0;
  high = list_length;
  if ((value >= (list[high])) || (value < (list[low])))
    return -1;
  else {
    while ((low + 1) < high) {
      m = (low + high) / 2;
      if (value < (list[m])) {
        high = m;
      }
      else
        if (value >= (list[m])) {
          low = m;
        }
    }
    return low;
  }
}
//==================== IJVector_parcsr.c ===================
int hypre_IJVectorCreatePar(hypre_IJVector* vector, int* IJpartitioning) {
  MPI_Comm comm = (vector)->comm;
  int num_procs;
  int j;
  int global_n;
  int* partitioning;
  int jmin;
  MPI_Comm_size(comm, &(num_procs));
  jmin = IJpartitioning[0];
  global_n = (IJpartitioning[num_procs]) - jmin;
  partitioning = (int*)(hypre_CAlloc((unsigned)(num_procs + 1), (unsigned)(sizeof(int))));
  for (j = 0; j < (num_procs + 1); j++)
    partitioning[j] = (IJpartitioning[j]) - jmin;
  (vector)->object = hypre_ParVectorCreate(comm, global_n, (int*)partitioning);
  return hypre__global_error;
}
int hypre_IJVectorDestroyPar(hypre_IJVector* vector) {
  return hypre_ParVectorDestroy((vector)->object);
}
int hypre_IJVectorInitializePar(hypre_IJVector* vector) {
  hypre_ParVector* par_vector = (vector)->object;
  hypre_AuxParVector* aux_vector = (vector)->translator;
  int* partitioning = (par_vector)->partitioning;
  hypre_Vector* local_vector = (par_vector)->local_vector;
  int my_id;
  MPI_Comm comm = (vector)->comm;
  MPI_Comm_rank(comm, &(my_id));
  if (!partitioning) {
    printf("No ParVector partitioning for initialization -- ");
    printf("hypre_IJVectorInitializePar\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/IJVector_parcsr.c", 908, 4 | (1 << 3));
  }
  (local_vector)->size = (int)((partitioning[my_id + 1]) - (partitioning[my_id]));
  hypre_ParVectorInitialize(par_vector);
  if (!aux_vector) {
    hypre_AuxParVectorCreate(&(aux_vector));
    (vector)->translator = aux_vector;
  }
  hypre_AuxParVectorInitialize(aux_vector);
  return hypre__global_error;
}
int hypre_IJVectorAssemblePar(hypre_IJVector* vector) {
  int* IJpartitioning = (vector)->partitioning;
  hypre_ParVector* par_vector = (vector)->object;
  hypre_AuxParVector* aux_vector = (vector)->translator;
  int* partitioning = (par_vector)->partitioning;
  MPI_Comm comm = (vector)->comm;
  if (!par_vector) {
    printf("par_vector == NULL -- ");
    printf("hypre_IJVectorAssemblePar\n");
    printf("**** Vector storage is either unallocated or orphaned ****\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/IJVector_parcsr.c", 908, 4 | (1 << 3));
  }
  if (!IJpartitioning) {
    printf("IJpartitioning == NULL -- ");
    printf("hypre_IJVectorAssemblePar\n");
    printf("**** IJVector partitioning is either unallocated or orphaned ****\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/IJVector_parcsr.c", 908, 4 | (1 << 3));
  }
  if (!partitioning) {
    printf("partitioning == NULL -- ");
    printf("hypre_IJVectorAssemblePar\n");
    printf("**** ParVector partitioning is either unallocated or orphaned ****\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/IJ_mv/IJVector_parcsr.c", 908, 4 | (1 << 3));
  }
  if (aux_vector) {
    int off_proc_elmts;
    int current_num_elmts;
    int max_off_proc_elmts;
    int* off_proc_i;
    double* off_proc_data;
    current_num_elmts = (aux_vector)->current_num_elmts;
    MPI_Allreduce(&(current_num_elmts), &(off_proc_elmts), 1, MPI_INT, _SUM, comm);
    if (off_proc_elmts) {
      max_off_proc_elmts = (aux_vector)->max_off_proc_elmts;
      off_proc_i = (aux_vector)->off_proc_i;
      off_proc_data = (aux_vector)->off_proc_data;
      hypre_IJVectorAssembleOffProcValsPar(vector, max_off_proc_elmts, current_num_elmts, off_proc_i, off_proc_data);
      hypre_Free((char*)((aux_vector)->off_proc_i)), (aux_vector)->off_proc_i = (void*)0;
      hypre_Free((char*)((aux_vector)->off_proc_data)), (aux_vector)->off_proc_data = (void*)0;
      (aux_vector)->max_off_proc_elmts = 0;
      (aux_vector)->current_num_elmts = 0;
    }
  }
  return hypre__global_error;
}
int hypre_IJVectorAssembleOffProcValsPar(hypre_IJVector* vector, int max_off_proc_elmts, int current_num_elmts, int* off_proc_i, double* off_proc_data) {
  MPI_Comm comm = (vector)->comm;
  hypre_ParVector* par_vector = (vector)->object;
  MPI_Request* requests;
  MPI_Status* status;
  int i;
  int j;
  int j2;
  int iii;
  int indx;
  int ip;
  int first_index;
  int row;
  int proc_id;
  int num_procs;
  int my_id;
  int num_sends;
  int num_sends2;
  int num_recvs;
  int num_requests;
  int vec_start;
  int vec_len;
  int* send_procs;
  int* send_i;
  int* send_map_starts;
  int* recv_procs;
  int* recv_i;
  int* recv_vec_starts;
  int* info;
  int* int_buffer;
  int* proc_id_mem;
  int* partitioning;
  int* displs;
  int* recv_buf;
  double* send_data;
  double* recv_data;
  double* data = ((par_vector)->local_vector)->data;
  MPI_Comm_size(comm, &(num_procs));
  MPI_Comm_rank(comm, &(my_id));
  partitioning = (vector)->partitioning;
  first_index = partitioning[my_id];
  info = (int*)(hypre_CAlloc((unsigned)num_procs, (unsigned)(sizeof(int))));
  proc_id_mem = (int*)(hypre_CAlloc((unsigned)current_num_elmts, (unsigned)(sizeof(int))));
  for (i = 0; i < current_num_elmts; i++) {
    row = off_proc_i[i];
    if (row < 0)
      row = (-row) - 1;
    proc_id = hypre_FindProc(partitioning, row, num_procs);
    proc_id_mem[i] = proc_id;
    info[proc_id]++;
  }
  num_sends = 0;
  for (i = 0; i < num_procs; i++) {
    if (info[i]) {
      num_sends++;
    }
  }
  num_sends2 = 2 * num_sends;
  send_procs = (int*)(hypre_CAlloc((unsigned)num_sends, (unsigned)(sizeof(int))));
  send_map_starts = (int*)(hypre_CAlloc((unsigned)(num_sends + 1), (unsigned)(sizeof(int))));
  int_buffer = (int*)(hypre_CAlloc((unsigned)num_sends2, (unsigned)(sizeof(int))));
  j = 0;
  j2 = 0;
  send_map_starts[0] = 0;
  for (i = 0; i < num_procs; i++) {
    if (info[i]) {
      send_procs[j++] = i;
      send_map_starts[j] = (send_map_starts[j - 1]) + (info[i]);
      int_buffer[j2++] = i;
      int_buffer[j2++] = info[i];
    }
  }
  MPI_Allgather(&(num_sends2), 1, MPI_INT, info, 1, MPI_INT, comm);
  displs = (int*)(hypre_CAlloc((unsigned)(num_procs + 1), (unsigned)(sizeof(int))));
  displs[0] = 0;
  for (i = 1; i < (num_procs + 1); i++)
    displs[i] = (displs[i - 1]) + (info[i - 1]);
  recv_buf = (int*)(hypre_CAlloc((unsigned)(displs[num_procs]), (unsigned)(sizeof(int))));
  MPI_Allgatherv(int_buffer, num_sends2, MPI_INT, recv_buf, info, displs, MPI_INT, comm);
  hypre_Free((char*)int_buffer), int_buffer = (void*)0;
  hypre_Free((char*)info), info = (void*)0;
  num_recvs = 0;
  for (j = 0; j < (displs[num_procs]); j += 2) {
    if ((recv_buf[j]) == my_id)
      num_recvs++;
  }
  recv_procs = (int*)(hypre_CAlloc((unsigned)num_recvs, (unsigned)(sizeof(int))));
  recv_vec_starts = (int*)(hypre_CAlloc((unsigned)(num_recvs + 1), (unsigned)(sizeof(int))));
  j2 = 0;
  recv_vec_starts[0] = 0;
  for (i = 0; i < num_procs; i++) {
    for (j = displs[i]; j < (displs[i + 1]); j += 2) {
      if ((recv_buf[j]) == my_id) {
        recv_procs[j2++] = i;
        recv_vec_starts[j2] = (recv_vec_starts[j2 - 1]) + (recv_buf[j + 1]);
      }
      if (j2 == num_recvs)
        break;
    }
  }
  hypre_Free((char*)recv_buf), recv_buf = (void*)0;
  hypre_Free((char*)displs), displs = (void*)0;
  send_i = (int*)(hypre_CAlloc((unsigned)(send_map_starts[num_sends]), (unsigned)(sizeof(int))));
  send_data = (double*)(hypre_CAlloc((unsigned)(send_map_starts[num_sends]), (unsigned)(sizeof(double))));
  recv_i = (int*)(hypre_CAlloc((unsigned)(recv_vec_starts[num_recvs]), (unsigned)(sizeof(int))));
  recv_data = (double*)(hypre_CAlloc((unsigned)(recv_vec_starts[num_recvs]), (unsigned)(sizeof(double))));
  for (i = 0; i < current_num_elmts; i++) {
    proc_id = proc_id_mem[i];
    indx = hypre_BinarySearch(send_procs, proc_id, num_sends);
    iii = send_map_starts[indx];
    send_i[iii] = off_proc_i[i];
    send_data[iii] = off_proc_data[i];
    send_map_starts[indx]++;
  }
  hypre_Free((char*)proc_id_mem), proc_id_mem = (void*)0;
  for (i = num_sends; i > 0; i--) {
    send_map_starts[i] = send_map_starts[i - 1];
  }
  send_map_starts[0] = 0;
  num_requests = num_recvs + num_sends;
  requests = (MPI_Request*)(hypre_CAlloc((unsigned)num_requests, (unsigned)(sizeof(MPI_Request))));
  status = (MPI_Status*)(hypre_CAlloc((unsigned)num_requests, (unsigned)(sizeof(MPI_Status))));
  j = 0;
  for (i = 0; i < num_recvs; i++) {
    vec_start = recv_vec_starts[i];
    vec_len = (recv_vec_starts[i + 1]) - vec_start;
    ip = recv_procs[i];
    MPI_Irecv(&(recv_i[vec_start]), vec_len, MPI_INT, ip, 0, comm, &(requests[j++]));
  }
  for (i = 0; i < num_sends; i++) {
    vec_start = send_map_starts[i];
    vec_len = (send_map_starts[i + 1]) - vec_start;
    ip = send_procs[i];
    MPI_Isend(&(send_i[vec_start]), vec_len, MPI_INT, ip, 0, comm, &(requests[j++]));
  }
  if (num_requests) {
    MPI_Waitall(num_requests, requests, status);
  }
  j = 0;
  for (i = 0; i < num_recvs; i++) {
    vec_start = recv_vec_starts[i];
    vec_len = (recv_vec_starts[i + 1]) - vec_start;
    ip = recv_procs[i];
    MPI_Irecv(&(recv_data[vec_start]), vec_len, MPI_DOUBLE, ip, 0, comm, &(requests[j++]));
  }
  for (i = 0; i < num_sends; i++) {
    vec_start = send_map_starts[i];
    vec_len = (send_map_starts[i + 1]) - vec_start;
    ip = send_procs[i];
    MPI_Isend(&(send_data[vec_start]), vec_len, MPI_DOUBLE, ip, 0, comm, &(requests[j++]));
  }
  if (num_requests) {
    MPI_Waitall(num_requests, requests, status);
    hypre_Free((char*)requests), requests = (void*)0;
    hypre_Free((char*)status), status = (void*)0;
  }
  hypre_Free((char*)send_i), send_i = (void*)0;
  hypre_Free((char*)send_data), send_data = (void*)0;
  hypre_Free((char*)send_procs), send_procs = (void*)0;
  hypre_Free((char*)send_map_starts), send_map_starts = (void*)0;
  hypre_Free((char*)recv_procs), recv_procs = (void*)0;
  for (i = 0; i < (recv_vec_starts[num_recvs]); i++) {
    row = recv_i[i];
    if (row < 0) {
      row = (-row) - 1;
      j = (int)(row - first_index);
      data[j] += recv_data[i];
    }
    else {
      j = (int)(row - first_index);
      data[j] = recv_data[i];
    }
  }
  hypre_Free((char*)recv_vec_starts), recv_vec_starts = (void*)0;
  hypre_Free((char*)recv_i), recv_i = (void*)0;
  hypre_Free((char*)recv_data), recv_data = (void*)0;
  return hypre__global_error;
}
//==================== aux_par_vector.c ====================
int hypre_AuxParVectorCreate(hypre_AuxParVector** aux_vector) {
  hypre_AuxParVector* vector;
  vector = (hypre_AuxParVector*)(hypre_CAlloc((unsigned)1, (unsigned)(sizeof(hypre_AuxParVector))));
  (vector)->max_off_proc_elmts = 0;
  (vector)->current_num_elmts = 0;
  (vector)->off_proc_i = (void*)0;
  (vector)->off_proc_data = (void*)0;
  *aux_vector = vector;
  return 0;
}
int hypre_AuxParVectorDestroy(hypre_AuxParVector* vector) {
  int ierr = 0;
  if (vector) {
    if ((vector)->off_proc_i)
      hypre_Free((char*)((vector)->off_proc_i)), (vector)->off_proc_i = (void*)0;
    if ((vector)->off_proc_data)
      hypre_Free((char*)((vector)->off_proc_data)), (vector)->off_proc_data = (void*)0;
    hypre_Free((char*)vector), vector = (void*)0;
  }
  return ierr;
}
int hypre_AuxParVectorInitialize(hypre_AuxParVector* vector) {
  int max_off_proc_elmts = (vector)->max_off_proc_elmts;
  if (max_off_proc_elmts > 0) {
    (vector)->off_proc_i = (int*)(hypre_CAlloc((unsigned)max_off_proc_elmts, (unsigned)(sizeof(int))));
    (vector)->off_proc_data = (double*)(hypre_CAlloc((unsigned)max_off_proc_elmts, (unsigned)(sizeof(double))));
  }
  return 0;
}
//=================== aux_parcsr_matrix.c ==================
int hypre_AuxParCSRMatrixCreate(hypre_AuxParCSRMatrix** aux_matrix, int local_num_rows, int local_num_cols, int* sizes) {
  hypre_AuxParCSRMatrix* matrix;
  matrix = (hypre_AuxParCSRMatrix*)(hypre_CAlloc((unsigned)1, (unsigned)(sizeof(hypre_AuxParCSRMatrix))));
  (matrix)->local_num_rows = local_num_rows;
  (matrix)->local_num_cols = local_num_cols;
  if (sizes) {
    (matrix)->row_space = sizes;
  }
  else {
    (matrix)->row_space = (void*)0;
  }
  (matrix)->need_aux = 1;
  (matrix)->max_off_proc_elmts = 0;
  (matrix)->current_num_elmts = 0;
  (matrix)->off_proc_i_indx = 0;
  (matrix)->row_length = (void*)0;
  (matrix)->aux_j = (void*)0;
  (matrix)->aux_data = (void*)0;
  (matrix)->indx_diag = (void*)0;
  (matrix)->indx_offd = (void*)0;
  (matrix)->off_proc_i = (void*)0;
  (matrix)->off_proc_j = (void*)0;
  (matrix)->off_proc_data = (void*)0;
  (matrix)->aux_offd_j = (void*)0;
  *aux_matrix = matrix;
  return 0;
}
int hypre_AuxParCSRMatrixDestroy(hypre_AuxParCSRMatrix* matrix) {
  int ierr = 0;
  int i;
  int num_rows;
  if (matrix) {
    num_rows = (matrix)->local_num_rows;
    if ((matrix)->row_length)
      hypre_Free((char*)((matrix)->row_length)), (matrix)->row_length = (void*)0;
    if ((matrix)->row_space)
      hypre_Free((char*)((matrix)->row_space)), (matrix)->row_space = (void*)0;
    if ((matrix)->aux_j) {
      for (i = 0; i < num_rows; i++)
        hypre_Free((char*)((matrix)->aux_j[i])), (matrix)->aux_j[i] = (void*)0;
      hypre_Free((char*)((matrix)->aux_j)), (matrix)->aux_j = (void*)0;
    }
    if ((matrix)->aux_data) {
      for (i = 0; i < num_rows; i++)
        hypre_Free((char*)((matrix)->aux_data[i])), (matrix)->aux_data[i] = (void*)0;
      hypre_Free((char*)((matrix)->aux_data)), (matrix)->aux_data = (void*)0;
    }
    if ((matrix)->indx_diag)
      hypre_Free((char*)((matrix)->indx_diag)), (matrix)->indx_diag = (void*)0;
    if ((matrix)->indx_offd)
      hypre_Free((char*)((matrix)->indx_offd)), (matrix)->indx_offd = (void*)0;
    if ((matrix)->off_proc_i)
      hypre_Free((char*)((matrix)->off_proc_i)), (matrix)->off_proc_i = (void*)0;
    if ((matrix)->off_proc_j)
      hypre_Free((char*)((matrix)->off_proc_j)), (matrix)->off_proc_j = (void*)0;
    if ((matrix)->off_proc_data)
      hypre_Free((char*)((matrix)->off_proc_data)), (matrix)->off_proc_data = (void*)0;
    if ((matrix)->aux_offd_j)
      hypre_Free((char*)((matrix)->aux_offd_j)), (matrix)->aux_offd_j = (void*)0;
    hypre_Free((char*)matrix), matrix = (void*)0;
  }
  return ierr;
}
int hypre_AuxParCSRMatrixInitialize(hypre_AuxParCSRMatrix* matrix) {
  int local_num_rows = (matrix)->local_num_rows;
  int* row_space = (matrix)->row_space;
  int max_off_proc_elmts = (matrix)->max_off_proc_elmts;
  int** aux_j;
  double** aux_data;
  int i;
  if (local_num_rows < 0)
    return -1;
  if (local_num_rows == 0)
    return 0;
  if (max_off_proc_elmts > 0) {
    (matrix)->off_proc_i = (int*)(hypre_CAlloc((unsigned)(2 * max_off_proc_elmts), (unsigned)(sizeof(int))));
    (matrix)->off_proc_j = (int*)(hypre_CAlloc((unsigned)max_off_proc_elmts, (unsigned)(sizeof(int))));
    (matrix)->off_proc_data = (double*)(hypre_CAlloc((unsigned)max_off_proc_elmts, (unsigned)(sizeof(double))));
  }
  if ((matrix)->need_aux) {
    aux_j = (int**)(hypre_CAlloc((unsigned)local_num_rows, (unsigned)(sizeof(int*))));
    aux_data = (double**)(hypre_CAlloc((unsigned)local_num_rows, (unsigned)(sizeof(double*))));
    if (!(matrix)->row_length)
      (matrix)->row_length = (int*)(hypre_CAlloc((unsigned)local_num_rows, (unsigned)(sizeof(int))));
    if (row_space) {
      for (i = 0; i < local_num_rows; i++) {
        aux_j[i] = (int*)(hypre_CAlloc((unsigned)(row_space[i]), (unsigned)(sizeof(int))));
        aux_data[i] = (double*)(hypre_CAlloc((unsigned)(row_space[i]), (unsigned)(sizeof(double))));
      }
    }
    else {
      row_space = (int*)(hypre_CAlloc((unsigned)local_num_rows, (unsigned)(sizeof(int))));
      for (i = 0; i < local_num_rows; i++) {
        row_space[i] = 30;
        aux_j[i] = (int*)(hypre_CAlloc((unsigned)30, (unsigned)(sizeof(int))));
        aux_data[i] = (double*)(hypre_CAlloc((unsigned)30, (unsigned)(sizeof(double))));
      }
      (matrix)->row_space = row_space;
    }
    (matrix)->aux_j = aux_j;
    (matrix)->aux_data = aux_data;
  }
  else {
    (matrix)->indx_diag = (int*)(hypre_CAlloc((unsigned)local_num_rows, (unsigned)(sizeof(int))));
    (matrix)->indx_offd = (int*)(hypre_CAlloc((unsigned)local_num_rows, (unsigned)(sizeof(int))));
  }
  return 0;
}
//====================== HYPRE_gmres.c =====================
int HYPRE_GMRESSetup(HYPRE_Solver solver, HYPRE_Matrix A, HYPRE_Vector b, HYPRE_Vector x) {
  return hypre_GMRESSetup(solver, A, b, x);
}
int HYPRE_GMRESSolve(HYPRE_Solver solver, HYPRE_Matrix A, HYPRE_Vector b, HYPRE_Vector x) {
  return hypre_GMRESSolve(solver, A, b, x);
}
int HYPRE_GMRESSetKDim(HYPRE_Solver solver, int k_dim) {
  return hypre_GMRESSetKDim((void*)solver, k_dim);
}
int HYPRE_GMRESSetTol(HYPRE_Solver solver, double tol) {
  return hypre_GMRESSetTol((void*)solver, tol);
}
int HYPRE_GMRESSetMaxIter(HYPRE_Solver solver, int max_iter) {
  return hypre_GMRESSetMaxIter((void*)solver, max_iter);
}
int HYPRE_GMRESSetPrecond(HYPRE_Solver solver, HYPRE_PtrToSolverFcn precond, HYPRE_PtrToSolverFcn precond_setup, HYPRE_Solver precond_solver) {
  return hypre_GMRESSetPrecond((void*)solver, precond, precond_setup, (void*)precond_solver);
}
int HYPRE_GMRESSetPrintLevel(HYPRE_Solver solver, int level) {
  return hypre_GMRESSetPrintLevel((void*)solver, level);
}
int HYPRE_GMRESSetLogging(HYPRE_Solver solver, int level) {
  return hypre_GMRESSetLogging((void*)solver, level);
}
int HYPRE_GMRESGetNumIterations(HYPRE_Solver solver, int* num_iterations) {
  return hypre_GMRESGetNumIterations((void*)solver, num_iterations);
}
int HYPRE_GMRESGetFinalRelativeResidualNorm(HYPRE_Solver solver, double* norm) {
  return hypre_GMRESGetFinalRelativeResidualNorm((void*)solver, norm);
}
//======================= HYPRE_pcg.c ======================
int HYPRE_PCGSetup(HYPRE_Solver solver, HYPRE_Matrix A, HYPRE_Vector b, HYPRE_Vector x) {
  return hypre_PCGSetup(solver, A, b, x);
}
int HYPRE_PCGSolve(HYPRE_Solver solver, HYPRE_Matrix A, HYPRE_Vector b, HYPRE_Vector x) {
  return hypre_PCGSolve((void*)solver, (void*)A, (void*)b, (void*)x);
}
int HYPRE_PCGSetTol(HYPRE_Solver solver, double tol) {
  return hypre_PCGSetTol((void*)solver, tol);
}
int HYPRE_PCGSetMaxIter(HYPRE_Solver solver, int max_iter) {
  return hypre_PCGSetMaxIter((void*)solver, max_iter);
}
int HYPRE_PCGSetTwoNorm(HYPRE_Solver solver, int two_norm) {
  return hypre_PCGSetTwoNorm((void*)solver, two_norm);
}
int HYPRE_PCGSetRelChange(HYPRE_Solver solver, int rel_change) {
  return hypre_PCGSetRelChange((void*)solver, rel_change);
}
int HYPRE_PCGSetPrecond(HYPRE_Solver solver, HYPRE_PtrToSolverFcn precond, HYPRE_PtrToSolverFcn precond_setup, HYPRE_Solver precond_solver) {
  return hypre_PCGSetPrecond((void*)solver, precond, precond_setup, (void*)precond_solver);
}
int HYPRE_PCGSetPrintLevel(HYPRE_Solver solver, int level) {
  return hypre_PCGSetPrintLevel((void*)solver, level);
}
int HYPRE_PCGGetNumIterations(HYPRE_Solver solver, int* num_iterations) {
  return hypre_PCGGetNumIterations((void*)solver, num_iterations);
}
int HYPRE_PCGGetFinalRelativeResidualNorm(HYPRE_Solver solver, double* norm) {
  return hypre_PCGGetFinalRelativeResidualNorm((void*)solver, norm);
}
//========================= gmres.c ========================
hypre_GMRESFunctions* hypre_GMRESFunctionsCreate( (char* (int count, int elt_size))* CAlloc,  (int (char* ptr))* Free,  (int (void* A, int* my_id, int* num_procs))* CommInfo,  (void* (void* vector))* CreateVector,  (void* (int size, void* vectors))* CreateVectorArray,  (int (void* vector))* DestroyVector,  (void* (void* A, void* x))* MatvecCreate,  (int (void* matvec_data, double alpha, void* A, void* x, double beta, void* y))* Matvec,  (int (void* matvec_data))* MatvecDestroy,  (double (void* x, void* y))* InnerProd,  (int (void* x, void* y))* CopyVector,  (int (void* x))* ClearVector,  (int (double alpha, void* x))* ScaleVector,  (int (double alpha, void* x, void* y))* Axpy,  (int (void* vdata, void* A, void* b, void* x))* PrecondSetup,  (int (void* vdata, void* A, void* b, void* x))* Precond) {
  hypre_GMRESFunctions* gmres_functions;
  gmres_functions = (hypre_GMRESFunctions*)(CAlloc(1, sizeof(hypre_GMRESFunctions)));
  (gmres_functions)->CAlloc = CAlloc;
  (gmres_functions)->Free = Free;
  (gmres_functions)->CommInfo = CommInfo;
  (gmres_functions)->CreateVector = CreateVector;
  (gmres_functions)->CreateVectorArray = CreateVectorArray;
  (gmres_functions)->DestroyVector = DestroyVector;
  (gmres_functions)->MatvecCreate = MatvecCreate;
  (gmres_functions)->Matvec = Matvec;
  (gmres_functions)->MatvecDestroy = MatvecDestroy;
  (gmres_functions)->InnerProd = InnerProd;
  (gmres_functions)->CopyVector = CopyVector;
  (gmres_functions)->ClearVector = ClearVector;
  (gmres_functions)->ScaleVector = ScaleVector;
  (gmres_functions)->Axpy = Axpy;
  (gmres_functions)->precond_setup = PrecondSetup;
  (gmres_functions)->precond = Precond;
  return gmres_functions;
}
void* hypre_GMRESCreate(hypre_GMRESFunctions* gmres_functions) {
  hypre_GMRESData* gmres_data;
  gmres_data = (hypre_GMRESData*)(*(gmres_functions)->CAlloc((unsigned)1, (unsigned)(sizeof(hypre_GMRESData))));
  (gmres_data)->functions = gmres_functions;
  (gmres_data)->k_dim = 5;
  (gmres_data)->tol = 1.0e-06;
  (gmres_data)->cf_tol = 0.0;
  (gmres_data)->min_iter = 0;
  (gmres_data)->max_iter = 1000;
  (gmres_data)->rel_change = 0;
  (gmres_data)->stop_crit = 0;
  (gmres_data)->converged = 0;
  (gmres_data)->precond_data = (void*)0;
  (gmres_data)->print_level = 0;
  (gmres_data)->logging = 0;
  (gmres_data)->p = (void*)0;
  (gmres_data)->r = (void*)0;
  (gmres_data)->w = (void*)0;
  (gmres_data)->matvec_data = (void*)0;
  (gmres_data)->norms = (void*)0;
  (gmres_data)->log_file_name = (void*)0;
  return (void*)gmres_data;
}
int hypre_GMRESDestroy(void* gmres_vdata) {
  hypre_GMRESData* gmres_data = gmres_vdata;
  hypre_GMRESFunctions* gmres_functions = (gmres_data)->functions;
  int i;
  int ierr = 0;
  if (gmres_data) {
    if (((gmres_data)->logging > 0) || ((gmres_data)->print_level > 0)) {
      if ((gmres_data)->norms != (void*)0)
        *(gmres_functions)->Free((char*)((gmres_data)->norms)), (gmres_data)->norms = (void*)0;
    }
    if ((gmres_data)->matvec_data != (void*)0)
      *(gmres_functions)->MatvecDestroy((gmres_data)->matvec_data);
    if ((gmres_data)->r != (void*)0)
      *(gmres_functions)->DestroyVector((gmres_data)->r);
    if ((gmres_data)->w != (void*)0)
      *(gmres_functions)->DestroyVector((gmres_data)->w);
    if ((gmres_data)->p != (void*)0) {
      for (i = 0; i < ((gmres_data)->k_dim + 1); i++) {
        if (((gmres_data)->p[i]) != (void*)0)
          *(gmres_functions)->DestroyVector((gmres_data)->p[i]);
      }
      *(gmres_functions)->Free((char*)((gmres_data)->p)), (gmres_data)->p = (void*)0;
    }
    *(gmres_functions)->Free((char*)gmres_data), gmres_data = (void*)0;
    *(gmres_functions)->Free((char*)gmres_functions), gmres_functions = (void*)0;
  }
  return ierr;
}
int hypre_GMRESSetup(void* gmres_vdata, void* A, void* b, void* x) {
  hypre_GMRESData* gmres_data = gmres_vdata;
  hypre_GMRESFunctions* gmres_functions = (gmres_data)->functions;
  int k_dim = (gmres_data)->k_dim;
  int max_iter = (gmres_data)->max_iter;
   (int ())* precond_setup = (gmres_functions)->precond_setup;
  void* precond_data = (gmres_data)->precond_data;
  int ierr = 0;
  (gmres_data)->A = A;
  if ((gmres_data)->p == (void*)0)
    (gmres_data)->p = *(gmres_functions)->CreateVectorArray(k_dim + 1, x);
  if ((gmres_data)->r == (void*)0)
    (gmres_data)->r = *(gmres_functions)->CreateVector(b);
  if ((gmres_data)->w == (void*)0)
    (gmres_data)->w = *(gmres_functions)->CreateVector(b);
  if ((gmres_data)->matvec_data == (void*)0)
    (gmres_data)->matvec_data = *(gmres_functions)->MatvecCreate(A, x);
  ierr = precond_setup(precond_data, A, b, x);
  if (((gmres_data)->logging > 0) || ((gmres_data)->print_level > 0)) {
    if ((gmres_data)->norms == (void*)0)
      (gmres_data)->norms = (double*)(*(gmres_functions)->CAlloc((unsigned)(max_iter + 1), (unsigned)(sizeof(double))));
  }
  if ((gmres_data)->print_level > 0) {
    if ((gmres_data)->log_file_name == (void*)0)
      (gmres_data)->log_file_name = "gmres.out.log";
  }
  return ierr;
}
int hypre_GMRESSolve(void* gmres_vdata, void* A, void* b, void* x) {
  hypre_GMRESData* gmres_data = gmres_vdata;
  hypre_GMRESFunctions* gmres_functions = (gmres_data)->functions;
  int k_dim = (gmres_data)->k_dim;
  int min_iter = (gmres_data)->min_iter;
  int max_iter = (gmres_data)->max_iter;
  int rel_change = (gmres_data)->rel_change;
  int stop_crit = (gmres_data)->stop_crit;
  double accuracy = (gmres_data)->tol;
  double cf_tol = (gmres_data)->cf_tol;
  void* matvec_data = (gmres_data)->matvec_data;
  void* r = (gmres_data)->r;
  void* w = (gmres_data)->w;
  void** p = (gmres_data)->p;
   (int ())* precond = (gmres_functions)->precond;
  int* precond_data = (gmres_data)->precond_data;
  int print_level = (gmres_data)->print_level;
  int logging = (gmres_data)->logging;
  double* norms = (gmres_data)->norms;
  int ierr = 0;
  int break_value = 0;
  int i;
  int j;
  int k;
  double* rs;
  double** hh;
  double* c;
  double* s;
  int iter;
  int my_id;
  int num_procs;
  double epsilon;
  double gamma;
  double t;
  double r_norm;
  double b_norm;
  double den_norm;
  double x_norm;
  double epsmac = 1.e-16;
  double ieee_check = 0.;
  double guard_zero_residual;
  double cf_ave_0 = 0.0;
  double cf_ave_1 = 0.0;
  double weight;
  double r_norm_0;
  double relative_error;
  (gmres_data)->converged = 0;
  guard_zero_residual = 0.0;
  *(gmres_functions)->CommInfo(A, &(my_id), &(num_procs));
  if ((logging > 0) || (print_level > 0)) {
    norms = (gmres_data)->norms;
  }
  rs = (double*)(*(gmres_functions)->CAlloc((unsigned)(k_dim + 1), (unsigned)(sizeof(double))));
  c = (double*)(*(gmres_functions)->CAlloc((unsigned)k_dim, (unsigned)(sizeof(double))));
  s = (double*)(*(gmres_functions)->CAlloc((unsigned)k_dim, (unsigned)(sizeof(double))));
  hh = (double**)(*(gmres_functions)->CAlloc((unsigned)(k_dim + 1), (unsigned)(sizeof(double*))));
  for (i = 0; i < (k_dim + 1); i++) {
    hh[i] = (double*)(*(gmres_functions)->CAlloc((unsigned)k_dim, (unsigned)(sizeof(double))));
  }
  *(gmres_functions)->CopyVector(b, p[0]);
  *(gmres_functions)->Matvec(matvec_data, -1.0, A, x, 1.0, p[0]);
  b_norm = sqrt(*(gmres_functions)->InnerProd(b, b));
  if (b_norm != 0.)
    ieee_check = b_norm / b_norm;
  if (ieee_check != ieee_check) {
    if ((logging > 0) || (print_level > 0)) {
      printf("\n\nERROR detected by Hypre ... BEGIN\n");
      printf("ERROR -- hypre_GMRESSolve: INFs and/or NaNs detected in input.\n");
      printf("User probably placed non-numerics in supplied b.\n");
      printf("Returning error flag += 101.  Program not terminated.\n");
      printf("ERROR detected by Hypre ... END\n\n\n");
    }
    ierr += 101;
    return ierr;
  }
  r_norm = sqrt(*(gmres_functions)->InnerProd(p[0], p[0]));
  r_norm_0 = r_norm;
  if (r_norm != 0.)
    ieee_check = r_norm / r_norm;
  if (ieee_check != ieee_check) {
    if ((logging > 0) || (print_level > 0)) {
      printf("\n\nERROR detected by Hypre ... BEGIN\n");
      printf("ERROR -- hypre_GMRESSolve: INFs and/or NaNs detected in input.\n");
      printf("User probably placed non-numerics in supplied A or x_0.\n");
      printf("Returning error flag += 101.  Program not terminated.\n");
      printf("ERROR detected by Hypre ... END\n\n\n");
    }
    ierr += 101;
    return ierr;
  }
  if ((logging > 0) || (print_level > 0)) {
    norms[0] = r_norm;
    if ((print_level > 1) && (my_id == 0)) {
      printf("L2 norm of b: %e\n", b_norm);
      if (b_norm == 0.0)
        printf("Rel_resid_norm actually contains the residual norm\n");
      printf("Initial L2 norm of residual: %e\n", r_norm);
    }
  }
  iter = 0;
  if (b_norm > 0.0) {
    den_norm = b_norm;
  }
  else {
    den_norm = r_norm;
  }
  ;
  epsilon = accuracy;
  if (stop_crit && (!rel_change))
    epsilon = accuracy;
  if ((print_level > 1) && (my_id == 0)) {
    if (b_norm > 0.0) {
      printf("=============================================\n\n");
      printf("Iters     resid.norm     conv.rate  rel.res.norm\n");
      printf("-----    ------------    ---------- ------------\n");
    }
    else {
      printf("=============================================\n\n");
      printf("Iters     resid.norm     conv.rate\n");
      printf("-----    ------------    ----------\n");
    }
    ;
  }
  if (rel_change) {
    relative_error = epsilon + 1.;
  }
  while (iter < max_iter) {
    rs[0] = r_norm;
    if (r_norm == 0.0) {
      *(gmres_functions)->Free((char*)c), c = (void*)0;
      *(gmres_functions)->Free((char*)s), s = (void*)0;
      *(gmres_functions)->Free((char*)rs), rs = (void*)0;
      for (i = 0; i < (k_dim + 1); i++)
        *(gmres_functions)->Free((char*)(hh[i])), hh[i] = (void*)0;
      *(gmres_functions)->Free((char*)hh), hh = (void*)0;
      ierr = 0;
      return ierr;
    }
    if (((r_norm / den_norm) <= epsilon) && (iter >= min_iter)) {
      if (rel_change) {
        if (relative_error <= epsilon) {
          *(gmres_functions)->CopyVector(b, r);
          *(gmres_functions)->Matvec(matvec_data, -1.0, A, x, 1.0, r);
          r_norm = sqrt(*(gmres_functions)->InnerProd(r, r));
          if ((r_norm / den_norm) <= epsilon) {
            if ((print_level > 1) && (my_id == 0)) {
              printf("\n\n");
              printf("Final L2 norm of residual: %e\n\n", r_norm);
            }
            break;
          }
          else
            if ((print_level > 0) && (my_id == 0))
              printf("false convergence 1\n");
        }
      }
      else {
        *(gmres_functions)->CopyVector(b, r);
        *(gmres_functions)->Matvec(matvec_data, -1.0, A, x, 1.0, r);
        r_norm = sqrt(*(gmres_functions)->InnerProd(r, r));
        if ((r_norm / den_norm) <= epsilon) {
          if ((print_level > 1) && (my_id == 0)) {
            printf("\n\n");
            printf("Final L2 norm of residual: %e\n\n", r_norm);
          }
          break;
        }
        else
          if ((print_level > 0) && (my_id == 0))
            printf("false convergence 1\n");
      }
    }
    t = 1.0 / r_norm;
    *(gmres_functions)->ScaleVector(t, p[0]);
    i = 0;
    while (((i < k_dim) && ((((r_norm / den_norm) > epsilon) || (iter < min_iter)) || (rel_change && (relative_error > epsilon)))) && (iter < max_iter)) {
      i++;
      iter++;
      *(gmres_functions)->ClearVector(r);
      precond(precond_data, A, p[i - 1], r);
      *(gmres_functions)->Matvec(matvec_data, 1.0, A, r, 0.0, p[i]);
      for (j = 0; j < i; j++) {
        hh[j][i - 1] = *(gmres_functions)->InnerProd(p[j], p[i]);
        *(gmres_functions)->Axpy(-(hh[j][i - 1]), p[j], p[i]);
      }
      t = sqrt(*(gmres_functions)->InnerProd(p[i], p[i]));
      hh[i][i - 1] = t;
      if (t != 0.0) {
        t = 1.0 / t;
        *(gmres_functions)->ScaleVector(t, p[i]);
      }
      for (j = 1; j < i; j++) {
        t = hh[j - 1][i - 1];
        hh[j - 1][i - 1] = ((c[j - 1]) * t) + ((s[j - 1]) * (hh[j][i - 1]));
        hh[j][i - 1] = ((-(s[j - 1])) * t) + ((c[j - 1]) * (hh[j][i - 1]));
      }
      gamma = sqrt(((hh[i - 1][i - 1]) * (hh[i - 1][i - 1])) + ((hh[i][i - 1]) * (hh[i][i - 1])));
      if (gamma == 0.0)
        gamma = epsmac;
      c[i - 1] = (hh[i - 1][i - 1]) / gamma;
      s[i - 1] = (hh[i][i - 1]) / gamma;
      rs[i] = (-(s[i - 1])) * (rs[i - 1]);
      rs[i - 1] = (c[i - 1]) * (rs[i - 1]);
      hh[i - 1][i - 1] = ((c[i - 1]) * (hh[i - 1][i - 1])) + ((s[i - 1]) * (hh[i][i - 1]));
      r_norm = fabs(rs[i]);
      if (print_level > 0) {
        norms[iter] = r_norm;
        if ((print_level > 1) && (my_id == 0)) {
          if (b_norm > 0.0)
            printf("% 5d    %e    %f   %e\n", iter, norms[iter], (norms[iter]) / (norms[iter - 1]), (norms[iter]) / b_norm);
          else
            printf("% 5d    %e    %f\n", iter, norms[iter], (norms[iter]) / (norms[iter - 1]));
        }
      }
      if (cf_tol > 0.0) {
        cf_ave_0 = cf_ave_1;
        cf_ave_1 = pow(r_norm / r_norm_0, 1.0 / (2.0 * iter));
        weight = fabs(cf_ave_1 - cf_ave_0);
        weight = weight / (cf_ave_1 < cf_ave_0 ? cf_ave_0 : cf_ave_1);
        weight = 1.0 - weight;
        if ((weight * cf_ave_1) > cf_tol) {
          break_value = 1;
          break;
        }
      }
    }
    if (break_value)
      break;
    rs[i - 1] = (rs[i - 1]) / (hh[i - 1][i - 1]);
    for (k = i - 2; k >= 0; k--) {
      t = rs[k];
      for (j = k + 1; j < i; j++) {
        t -= ((hh[k][j]) * (rs[j]));
      }
      rs[k] = t / (hh[k][k]);
    }
    *(gmres_functions)->CopyVector(p[0], w);
    *(gmres_functions)->ScaleVector(rs[0], w);
    for (j = 1; j < i; j++)
      *(gmres_functions)->Axpy(rs[j], p[j], w);
    *(gmres_functions)->ClearVector(r);
    precond(precond_data, A, w, r);
    *(gmres_functions)->Axpy(1.0, r, x);
    if (((r_norm / den_norm) <= epsilon) && (iter >= min_iter)) {
      if (rel_change) {
        x_norm = sqrt(*(gmres_functions)->InnerProd(x, x));
        if (x_norm <= guard_zero_residual)
          break;
        r_norm = sqrt(*(gmres_functions)->InnerProd(r, r));
        relative_error = r_norm / x_norm;
      }
      *(gmres_functions)->CopyVector(b, r);
      *(gmres_functions)->Matvec(matvec_data, -1.0, A, x, 1.0, r);
      r_norm = sqrt(*(gmres_functions)->InnerProd(r, r));
      if ((r_norm / den_norm) <= epsilon) {
        if ((print_level > 1) && (my_id == 0)) {
          printf("\n\n");
          printf("Final L2 norm of residual: %e\n\n", r_norm);
        }
        if (rel_change && (r_norm > guard_zero_residual)) {
          x_norm = sqrt(*(gmres_functions)->InnerProd(x, x));
          if (x_norm <= guard_zero_residual)
            break;
          if (relative_error < epsilon) {
            (gmres_data)->converged = 1;
            break;
          }
        }
        else {
          (gmres_data)->converged = 1;
          break;
        }
      }
      else {
        if ((print_level > 0) && (my_id == 0))
          printf("false convergence 2\n");
        *(gmres_functions)->CopyVector(r, p[0]);
        i = 0;
      }
    }
    for (j = i; j > 0; j--) {
      rs[j - 1] = (-(s[j - 1])) * (rs[j]);
      rs[j] = (c[j - 1]) * (rs[j]);
    }
    if (i)
      *(gmres_functions)->Axpy((rs[0]) - 1.0, p[0], p[0]);
    for (j = 1; j < (i + 1); j++)
      *(gmres_functions)->Axpy(rs[j], p[j], p[0]);
  }
  if ((print_level > 1) && (my_id == 0))
    printf("\n\n");
  (gmres_data)->num_iterations = iter;
  if (b_norm > 0.0)
    (gmres_data)->rel_residual_norm = r_norm / b_norm;
  if (b_norm == 0.0)
    (gmres_data)->rel_residual_norm = r_norm;
  if ((iter >= max_iter) && ((r_norm / den_norm) > epsilon))
    ierr = 1;
  *(gmres_functions)->Free((char*)c), c = (void*)0;
  *(gmres_functions)->Free((char*)s), s = (void*)0;
  *(gmres_functions)->Free((char*)rs), rs = (void*)0;
  for (i = 0; i < (k_dim + 1); i++) {
    *(gmres_functions)->Free((char*)(hh[i])), hh[i] = (void*)0;
  }
  *(gmres_functions)->Free((char*)hh), hh = (void*)0;
  return ierr;
}
int hypre_GMRESSetKDim(void* gmres_vdata, int k_dim) {
  hypre_GMRESData* gmres_data = gmres_vdata;
  int ierr = 0;
  (gmres_data)->k_dim = k_dim;
  return ierr;
}
int hypre_GMRESSetTol(void* gmres_vdata, double tol) {
  hypre_GMRESData* gmres_data = gmres_vdata;
  int ierr = 0;
  (gmres_data)->tol = tol;
  return ierr;
}
int hypre_GMRESSetMaxIter(void* gmres_vdata, int max_iter) {
  hypre_GMRESData* gmres_data = gmres_vdata;
  int ierr = 0;
  (gmres_data)->max_iter = max_iter;
  return ierr;
}
int hypre_GMRESSetPrecond(void* gmres_vdata,  (int ())* precond,  (int ())* precond_setup, void* precond_data) {
  hypre_GMRESData* gmres_data = gmres_vdata;
  hypre_GMRESFunctions* gmres_functions = (gmres_data)->functions;
  int ierr = 0;
  (gmres_functions)->precond = precond;
  (gmres_functions)->precond_setup = precond_setup;
  (gmres_data)->precond_data = precond_data;
  return ierr;
}
int hypre_GMRESSetPrintLevel(void* gmres_vdata, int level) {
  hypre_GMRESData* gmres_data = gmres_vdata;
  int ierr = 0;
  (gmres_data)->print_level = level;
  return ierr;
}
int hypre_GMRESSetLogging(void* gmres_vdata, int level) {
  hypre_GMRESData* gmres_data = gmres_vdata;
  int ierr = 0;
  (gmres_data)->logging = level;
  return ierr;
}
int hypre_GMRESGetNumIterations(void* gmres_vdata, int* num_iterations) {
  hypre_GMRESData* gmres_data = gmres_vdata;
  int ierr = 0;
  *num_iterations = (gmres_data)->num_iterations;
  return ierr;
}
int hypre_GMRESGetFinalRelativeResidualNorm(void* gmres_vdata, double* relative_residual_norm) {
  hypre_GMRESData* gmres_data = gmres_vdata;
  int ierr = 0;
  *relative_residual_norm = (gmres_data)->rel_residual_norm;
  return ierr;
}
//========================== pcg.c =========================
hypre_PCGFunctions* hypre_PCGFunctionsCreate( (char* (int count, int elt_size))* CAlloc,  (int (char* ptr))* Free,  (int (void* A, int* my_id, int* num_procs))* CommInfo,  (void* (void* vector))* CreateVector,  (int (void* vector))* DestroyVector,  (void* (void* A, void* x))* MatvecCreate,  (int (void* matvec_data, double alpha, void* A, void* x, double beta, void* y))* Matvec,  (int (void* matvec_data))* MatvecDestroy,  (double (void* x, void* y))* InnerProd,  (int (void* x, void* y))* CopyVector,  (int (void* x))* ClearVector,  (int (double alpha, void* x))* ScaleVector,  (int (double alpha, void* x, void* y))* Axpy,  (int (void* vdata, void* A, void* b, void* x))* PrecondSetup,  (int (void* vdata, void* A, void* b, void* x))* Precond) {
  hypre_PCGFunctions* pcg_functions;
  pcg_functions = (hypre_PCGFunctions*)(CAlloc(1, sizeof(hypre_PCGFunctions)));
  (pcg_functions)->CAlloc = CAlloc;
  (pcg_functions)->Free = Free;
  (pcg_functions)->CommInfo = CommInfo;
  (pcg_functions)->CreateVector = CreateVector;
  (pcg_functions)->DestroyVector = DestroyVector;
  (pcg_functions)->MatvecCreate = MatvecCreate;
  (pcg_functions)->Matvec = Matvec;
  (pcg_functions)->MatvecDestroy = MatvecDestroy;
  (pcg_functions)->InnerProd = InnerProd;
  (pcg_functions)->CopyVector = CopyVector;
  (pcg_functions)->ClearVector = ClearVector;
  (pcg_functions)->ScaleVector = ScaleVector;
  (pcg_functions)->Axpy = Axpy;
  (pcg_functions)->precond_setup = PrecondSetup;
  (pcg_functions)->precond = Precond;
  return pcg_functions;
}
void* hypre_PCGCreate(hypre_PCGFunctions* pcg_functions) {
  hypre_PCGData* pcg_data;
  pcg_data = (hypre_PCGData*)(*(pcg_functions)->CAlloc((unsigned)1, (unsigned)(sizeof(hypre_PCGData))));
  (pcg_data)->functions = pcg_functions;
  (pcg_data)->tol = 1.0e-06;
  (pcg_data)->atolf = 0.0;
  (pcg_data)->cf_tol = 0.0;
  (pcg_data)->max_iter = 1000;
  (pcg_data)->two_norm = 0;
  (pcg_data)->rel_change = 0;
  (pcg_data)->stop_crit = 0;
  (pcg_data)->converged = 0;
  (pcg_data)->owns_matvec_data = 1;
  (pcg_data)->matvec_data = (void*)0;
  (pcg_data)->precond_data = (void*)0;
  (pcg_data)->print_level = 0;
  (pcg_data)->logging = 0;
  (pcg_data)->norms = (void*)0;
  (pcg_data)->rel_norms = (void*)0;
  (pcg_data)->p = (void*)0;
  (pcg_data)->s = (void*)0;
  (pcg_data)->r = (void*)0;
  return (void*)pcg_data;
}
int hypre_PCGDestroy(void* pcg_vdata) {
  hypre_PCGData* pcg_data = pcg_vdata;
  hypre_PCGFunctions* pcg_functions = (pcg_data)->functions;
  int ierr = 0;
  if (pcg_data) {
    if ((pcg_data)->norms != (void*)0) {
      *(pcg_functions)->Free((char*)((pcg_data)->norms)), (pcg_data)->norms = (void*)0;
      (pcg_data)->norms = (void*)0;
    }
    if ((pcg_data)->rel_norms != (void*)0) {
      *(pcg_functions)->Free((char*)((pcg_data)->rel_norms)), (pcg_data)->rel_norms = (void*)0;
      (pcg_data)->rel_norms = (void*)0;
    }
    if (((pcg_data)->matvec_data != (void*)0) && (pcg_data)->owns_matvec_data) {
      *(pcg_functions)->MatvecDestroy((pcg_data)->matvec_data);
      (pcg_data)->matvec_data = (void*)0;
    }
    if ((pcg_data)->p != (void*)0) {
      *(pcg_functions)->DestroyVector((pcg_data)->p);
      (pcg_data)->p = (void*)0;
    }
    if ((pcg_data)->s != (void*)0) {
      *(pcg_functions)->DestroyVector((pcg_data)->s);
      (pcg_data)->s = (void*)0;
    }
    if ((pcg_data)->r != (void*)0) {
      *(pcg_functions)->DestroyVector((pcg_data)->r);
      (pcg_data)->r = (void*)0;
    }
    *(pcg_functions)->Free((char*)pcg_data), pcg_data = (void*)0;
    *(pcg_functions)->Free((char*)pcg_functions), pcg_functions = (void*)0;
  }
  return ierr;
}
int hypre_PCGSetup(void* pcg_vdata, void* A, void* b, void* x) {
  hypre_PCGData* pcg_data = pcg_vdata;
  hypre_PCGFunctions* pcg_functions = (pcg_data)->functions;
  int max_iter = (pcg_data)->max_iter;
   (int ())* precond_setup = (pcg_functions)->precond_setup;
  void* precond_data = (pcg_data)->precond_data;
  int ierr = 0;
  (pcg_data)->A = A;
  if ((pcg_data)->p != (void*)0)
    *(pcg_functions)->DestroyVector((pcg_data)->p);
  (pcg_data)->p = *(pcg_functions)->CreateVector(x);
  if ((pcg_data)->s != (void*)0)
    *(pcg_functions)->DestroyVector((pcg_data)->s);
  (pcg_data)->s = *(pcg_functions)->CreateVector(x);
  if ((pcg_data)->r != (void*)0)
    *(pcg_functions)->DestroyVector((pcg_data)->r);
  (pcg_data)->r = *(pcg_functions)->CreateVector(b);
  if (((pcg_data)->matvec_data != (void*)0) && (pcg_data)->owns_matvec_data)
    *(pcg_functions)->MatvecDestroy((pcg_data)->matvec_data);
  (pcg_data)->matvec_data = *(pcg_functions)->MatvecCreate(A, x);
  ierr = precond_setup(precond_data, A, b, x);
  if (((pcg_data)->logging > 0) || ((pcg_data)->print_level > 0)) {
    if ((pcg_data)->norms != (void*)0)
      *(pcg_functions)->Free((char*)((pcg_data)->norms)), (pcg_data)->norms = (void*)0;
    (pcg_data)->norms = (double*)(*(pcg_functions)->CAlloc((unsigned)(max_iter + 1), (unsigned)(sizeof(double))));
    if ((pcg_data)->rel_norms != (void*)0)
      *(pcg_functions)->Free((char*)((pcg_data)->rel_norms)), (pcg_data)->rel_norms = (void*)0;
    (pcg_data)->rel_norms = (double*)(*(pcg_functions)->CAlloc((unsigned)(max_iter + 1), (unsigned)(sizeof(double))));
  }
  return ierr;
}
int hypre_PCGSolve(void* pcg_vdata, void* A, void* b, void* x) {
  hypre_PCGData* pcg_data = pcg_vdata;
  hypre_PCGFunctions* pcg_functions = (pcg_data)->functions;
  double tol = (pcg_data)->tol;
  double atolf = (pcg_data)->atolf;
  double cf_tol = (pcg_data)->cf_tol;
  int max_iter = (pcg_data)->max_iter;
  int two_norm = (pcg_data)->two_norm;
  int rel_change = (pcg_data)->rel_change;
  int stop_crit = (pcg_data)->stop_crit;
  void* p = (pcg_data)->p;
  void* s = (pcg_data)->s;
  void* r = (pcg_data)->r;
  void* matvec_data = (pcg_data)->matvec_data;
   (int ())* precond = (pcg_functions)->precond;
  void* precond_data = (pcg_data)->precond_data;
  int print_level = (pcg_data)->print_level;
  int logging = (pcg_data)->logging;
  double* norms = (pcg_data)->norms;
  double* rel_norms = (pcg_data)->rel_norms;
  double alpha;
  double beta;
  double gamma;
  double gamma_old;
  double bi_prod;
  double i_prod;
  double eps;
  double pi_prod;
  double xi_prod;
  double ieee_check = 0.;
  double i_prod_0;
  double cf_ave_0 = 0.0;
  double cf_ave_1 = 0.0;
  double weight;
  double ratio;
  double guard_zero_residual;
  double sdotp;
  int i = 0;
  int ierr = 0;
  int my_id;
  int num_procs;
  (pcg_data)->converged = 0;
  *(pcg_functions)->CommInfo(A, &(my_id), &(num_procs));
  guard_zero_residual = 0.0;
  if (two_norm) {
    bi_prod = *(pcg_functions)->InnerProd(b, b);
    if ((print_level > 1) && (my_id == 0))
      printf("<b,b>: %e\n", bi_prod);
  }
  else {
    *(pcg_functions)->ClearVector(p);
    precond(precond_data, A, b, p);
    bi_prod = *(pcg_functions)->InnerProd(p, b);
    if ((print_level > 1) && (my_id == 0))
      printf("<C*b,b>: %e\n", bi_prod);
  }
  ;
  if (bi_prod != 0.)
    ieee_check = bi_prod / bi_prod;
  if (ieee_check != ieee_check) {
    if ((print_level > 0) || (logging > 0)) {
      printf("\n\nERROR detected by Hypre ...  BEGIN\n");
      printf("ERROR -- hypre_PCGSolve: INFs and/or NaNs detected in input.\n");
      printf("User probably placed non-numerics in supplied b.\n");
      printf("Returning error flag += 101.  Program not terminated.\n");
      printf("ERROR detected by Hypre ...  END\n\n\n");
    }
    ierr += 101;
    return ierr;
  }
  eps = tol * tol;
  if (bi_prod > 0.0) {
    if ((stop_crit && (!rel_change)) && (atolf <= 0)) {
      eps = eps / bi_prod;
    }
    else
      if (atolf > 0)
        bi_prod += atolf;
  }
  else {
    *(pcg_functions)->CopyVector(b, x);
    if ((logging > 0) || (print_level > 0)) {
      norms[0] = 0.0;
      rel_norms[i] = 0.0;
    }
    ierr = 0;
    return ierr;
  }
  ;
  *(pcg_functions)->CopyVector(b, r);
  *(pcg_functions)->Matvec(matvec_data, -1.0, A, x, 1.0, r);
  *(pcg_functions)->ClearVector(p);
  precond(precond_data, A, r, p);
  gamma = *(pcg_functions)->InnerProd(r, p);
  if (gamma != 0.)
    ieee_check = gamma / gamma;
  if (ieee_check != ieee_check) {
    if ((print_level > 0) || (logging > 0)) {
      printf("\n\nERROR detected by Hypre ...  BEGIN\n");
      printf("ERROR -- hypre_PCGSolve: INFs and/or NaNs detected in input.\n");
      printf("User probably placed non-numerics in supplied A or x_0.\n");
      printf("Returning error flag += 101.  Program not terminated.\n");
      printf("ERROR detected by Hypre ...  END\n\n\n");
    }
    ierr += 101;
    return ierr;
  }
  if (((logging > 0) || (print_level > 0)) || (cf_tol > 0.0)) {
    if (two_norm)
      i_prod_0 = *(pcg_functions)->InnerProd(r, r);
    else
      i_prod_0 = gamma;
    if ((logging > 0) || (print_level > 0))
      norms[0] = sqrt(i_prod_0);
  }
  if ((print_level > 1) && (my_id == 0)) {
    printf("\n\n");
    if (two_norm) {
      if ((stop_crit && (!rel_change)) && (atolf == 0)) {
        printf("Iters       ||r||_2     conv.rate\n");
        printf("-----    ------------   ---------\n");
      }
      else {
        printf("Iters       ||r||_2     conv.rate  ||r||_2/||b||_2\n");
        printf("-----    ------------   ---------  ------------ \n");
      }
    }
    else {
      printf("Iters       ||r||_C      ||r||_C/||b||_C\n");
      printf("-----    ------------    ------------ \n");
    }
  }
  while ((i + 1) <= max_iter) {
    i++;
    *(pcg_functions)->Matvec(matvec_data, 1.0, A, p, 0.0, s);
    sdotp = *(pcg_functions)->InnerProd(s, p);
    if (sdotp == 0.0) {
      ++ierr;
      if (i == 1)
        i_prod = i_prod_0;
      break;
    }
    alpha = gamma / sdotp;
    gamma_old = gamma;
    *(pcg_functions)->Axpy(alpha, p, x);
    *(pcg_functions)->Axpy(-alpha, s, r);
    *(pcg_functions)->ClearVector(s);
    precond(precond_data, A, r, s);
    gamma = *(pcg_functions)->InnerProd(r, s);
    if (two_norm)
      i_prod = *(pcg_functions)->InnerProd(r, r);
    else
      i_prod = gamma;
    if ((logging > 0) || (print_level > 0)) {
      norms[i] = sqrt(i_prod);
      rel_norms[i] = bi_prod ? sqrt(i_prod / bi_prod) : 0;
    }
    if ((print_level > 1) && (my_id == 0)) {
      if (two_norm) {
        if ((stop_crit && (!rel_change)) && (atolf == 0)) {
          printf("% 5d    %e    %f\n", i, norms[i], (norms[i]) / (norms[i - 1]));
        }
        else {
          printf("% 5d    %e    %f    %e\n", i, norms[i], (norms[i]) / (norms[i - 1]), rel_norms[i]);
        }
      }
      else {
        printf("% 5d    %e    %f    %e\n", i, norms[i], (norms[i]) / (norms[i - 1]), rel_norms[i]);
      }
    }
    if ((i_prod / bi_prod) < eps) {
      if (rel_change && (i_prod > guard_zero_residual)) {
        pi_prod = *(pcg_functions)->InnerProd(p, p);
        xi_prod = *(pcg_functions)->InnerProd(x, x);
        ratio = ((alpha * alpha) * pi_prod) / xi_prod;
        if (ratio < eps) {
          (pcg_data)->converged = 1;
          break;
        }
      }
      else {
        (pcg_data)->converged = 1;
        break;
      }
    }
    if ((gamma < 1.0e-292) && ((-gamma) < 1.0e-292)) {
      ierr = 1;
      break;
    }
    if (cf_tol > 0.0) {
      cf_ave_0 = cf_ave_1;
      if (i_prod_0 < 1.0e-292) {
        ierr = 1;
        break;
      }
      cf_ave_1 = pow(i_prod / i_prod_0, 1.0 / (2.0 * i));
      weight = fabs(cf_ave_1 - cf_ave_0);
      weight = weight / (cf_ave_1 < cf_ave_0 ? cf_ave_0 : cf_ave_1);
      weight = 1.0 - weight;
      if ((weight * cf_ave_1) > cf_tol)
        break;
    }
    beta = gamma / gamma_old;
    *(pcg_functions)->ScaleVector(beta, p);
    *(pcg_functions)->Axpy(1.0, s, p);
  }
  if ((print_level > 1) && (my_id == 0))
    printf("\n\n");
  (pcg_data)->num_iterations = i;
  if (bi_prod > 0.0)
    (pcg_data)->rel_residual_norm = sqrt(i_prod / bi_prod);
  else
    (pcg_data)->rel_residual_norm = 0.0;
  return ierr;
}
int hypre_PCGSetTol(void* pcg_vdata, double tol) {
  hypre_PCGData* pcg_data = pcg_vdata;
  int ierr = 0;
  (pcg_data)->tol = tol;
  return ierr;
}
int hypre_PCGSetMaxIter(void* pcg_vdata, int max_iter) {
  hypre_PCGData* pcg_data = pcg_vdata;
  int ierr = 0;
  (pcg_data)->max_iter = max_iter;
  return ierr;
}
int hypre_PCGSetTwoNorm(void* pcg_vdata, int two_norm) {
  hypre_PCGData* pcg_data = pcg_vdata;
  int ierr = 0;
  (pcg_data)->two_norm = two_norm;
  return ierr;
}
int hypre_PCGSetRelChange(void* pcg_vdata, int rel_change) {
  hypre_PCGData* pcg_data = pcg_vdata;
  int ierr = 0;
  (pcg_data)->rel_change = rel_change;
  return ierr;
}
int hypre_PCGSetPrecond(void* pcg_vdata,  (int ())* precond,  (int ())* precond_setup, void* precond_data) {
  hypre_PCGData* pcg_data = pcg_vdata;
  hypre_PCGFunctions* pcg_functions = (pcg_data)->functions;
  int ierr = 0;
  (pcg_functions)->precond = precond;
  (pcg_functions)->precond_setup = precond_setup;
  (pcg_data)->precond_data = precond_data;
  return ierr;
}
int hypre_PCGSetPrintLevel(void* pcg_vdata, int level) {
  hypre_PCGData* pcg_data = pcg_vdata;
  int ierr = 0;
  (pcg_data)->print_level = level;
  return ierr;
}
int hypre_PCGGetNumIterations(void* pcg_vdata, int* num_iterations) {
  hypre_PCGData* pcg_data = pcg_vdata;
  int ierr = 0;
  *num_iterations = (pcg_data)->num_iterations;
  return ierr;
}
int hypre_PCGGetFinalRelativeResidualNorm(void* pcg_vdata, double* relative_residual_norm) {
  hypre_PCGData* pcg_data = pcg_vdata;
  int ierr = 0;
  double rel_residual_norm = (pcg_data)->rel_residual_norm;
  *relative_residual_norm = rel_residual_norm;
  return ierr;
}
//======================== par_amg.h =======================
typedef struct $anon_struct_21$TU11{
  hypre_CSRMatrix** A_array;
  hypre_Vector** F_array;
  hypre_Vector** U_array;
  hypre_CSRMatrix** P_array;
  hypre_Vector* Vtemp;
  int num_levels;
  int participate;
} hypre_SeqAMGData;
typedef struct $anon_struct_22$TU11{
  int max_levels;
  double strong_threshold;
  double max_row_sum;
  double trunc_factor;
  double agg_trunc_factor;
  double jacobi_trunc_threshold;
  double S_commpkg_switch;
  double CR_rate;
  int measure_type;
  int setup_type;
  int coarsen_type;
  int P_max_elmts;
  int interp_type;
  int restr_par;
  int agg_interp_type;
  int agg_P_max_elmts;
  int P_max1;
  int P_max2;
  int agg_num_levels;
  int num_paths;
  int post_interp_type;
  int num_CR_relax_steps;
  int IS_type;
  int CR_use_CG;
  int max_coarse_size;
  int min_coarse_size;
  int redundant;
  int participate;
  int seq_threshold;
  int max_iter;
  int min_iter;
  int cycle_type;
  int* num_grid_sweeps;
  int* grid_relax_type;
  int** grid_relax_points;
  int relax_order;
  int user_coarse_relax_type;
  double* relax_weight;
  double* omega;
  double tol;
  hypre_ParCSRMatrix* A;
  int num_variables;
  int num_functions;
  int nodal;
  int num_points;
  int* dof_func;
  int* dof_point;
  int* point_dof_map;
  hypre_ParCSRMatrix** A_array;
  hypre_ParVector** F_array;
  hypre_ParVector** U_array;
  hypre_ParCSRMatrix** P_array;
  hypre_ParCSRMatrix** R_array;
  int** CF_marker_array;
  int** dof_func_array;
  int** dof_point_array;
  int** point_dof_map_array;
  int num_levels;
  double** l1_norms;
  int block_mode;
  int smooth_num_levels;
  int smooth_type;
  HYPRE_Solver* smoother;
  HYPRE_Solver* smoother_prec;
  int smooth_num_sweeps;
  int variant;
  int overlap;
  int domain_type;
  double schwarz_rlx_weight;
  int sym;
  int level;
  int max_nz_per_row;
  double threshold;
  double filter;
  double drop_tol;
  char* euclidfile;
  double* theta_est;
  double* max_eig_est;
  double* min_eig_est;
  int cheby_order;
  double cheby_eig_ratio;
  hypre_ParVector* Vtemp;
  hypre_Vector* Vtemp_local;
  double* Vtemp_local_data;
  double cycle_op_count;
  hypre_ParVector* Rtemp;
  hypre_ParVector* Ptemp;
  hypre_ParVector* Ztemp;
  int gsmg;
  int num_samples;
  int logging;
  int num_iterations;
  int cum_num_iterations;
  double rel_resid_norm;
  hypre_ParVector* residual;
  int print_level;
  char  log_file_name[256];
  int debug_flag;
  HYPRE_Solver coarse_solver;
  hypre_ParCSRMatrix* A_coarse;
  hypre_ParVector* f_coarse;
  hypre_ParVector* u_coarse;
  MPI_Comm new_comm;
  double* A_mat;
  double* b_vec;
  int* comm_info;
  hypre_SeqAMGData* seq_data;
} hypre_ParAMGData;
//======================= parcsr_ls.h ======================
int alt_insert_new_nodes(hypre_ParCSRCommPkg* comm_pkg, hypre_ParCSRCommPkg* extend_comm_pkg, int* IN_marker, int full_off_procNodes, int* OUT_marker);
int big_insert_new_nodes(hypre_ParCSRCommPkg* comm_pkg, hypre_ParCSRCommPkg* extend_comm_pkg, int* IN_marker, int full_off_procNodes, int offset, int* OUT_marker);
int hypre_ParCSRFindExtendCommPkg(hypre_ParCSRMatrix* A, int newoff, int* found, hypre_ParCSRCommPkg** extend_comm_pkg);
int new_offd_nodes(int** found, int num_cols_A_offd, int* A_ext_i, int* big_A_ext_j, int** A_ext_j_ptr, int num_cols_S_offd, int* col_map_offd, int col_1, int col_n, int* Sop_i, int* big_Sop_j, int** Sop_j_ptr, int* CF_marker, hypre_ParCSRCommPkg* comm_pkg);
int hypre_seqAMGSetup(hypre_ParAMGData* amg_data, int p_level, int coarse_threshold);
int hypre_seqAMGCycle(hypre_ParAMGData* amg_data, int p_level, hypre_ParVector** Par_F_array, hypre_ParVector** Par_U_array);
int hypre_GenerateSubComm(MPI_Comm comm, int participate, MPI_Comm* new_comm_ptr);
void hypre_merge_lists(int* list1, int* list2, int* np1, MPI_Datatype* dptr);
void* hypre_BoomerAMGCreate(void);
int hypre_BoomerAMGDestroy(void* data);
int hypre_BoomerAMGSetRestriction(void* data, int restr_par);
int hypre_BoomerAMGSetMaxLevels(void* data, int max_levels);
int hypre_BoomerAMGSetStrongThreshold(void* data, double strong_threshold);
int hypre_BoomerAMGSetMaxRowSum(void* data, double max_row_sum);
int hypre_BoomerAMGSetTruncFactor(void* data, double trunc_factor);
int hypre_BoomerAMGSetAggTruncFactor(void* data, double agg_trunc_factor);
int hypre_BoomerAMGSetPMaxElmts(void* data, int P_max_elmts);
int hypre_BoomerAMGSetPMax1(void* data, int P_max1);
int hypre_BoomerAMGSetPMax2(void* data, int P_max2);
int hypre_BoomerAMGSetJacobiTruncThreshold(void* data, double jacobi_trunc_threshold);
int hypre_BoomerAMGSetPostInterpType(void* data, int post_interp_type);
int hypre_BoomerAMGSetSCommPkgSwitch(void* data, double S_commpkg_switch);
int hypre_BoomerAMGSetInterpType(void* data, int interp_type);
int hypre_BoomerAMGSetMinIter(void* data, int min_iter);
int hypre_BoomerAMGSetMaxIter(void* data, int max_iter);
int hypre_BoomerAMGSetCoarsenType(void* data, int coarsen_type);
int hypre_BoomerAMGSetMeasureType(void* data, int measure_type);
int hypre_BoomerAMGSetSetupType(void* data, int setup_type);
int hypre_BoomerAMGSetCycleType(void* data, int cycle_type);
int hypre_BoomerAMGSetTol(void* data, double tol);
int hypre_BoomerAMGSetNumSweeps(void* data, int num_sweeps);
int hypre_BoomerAMGSetCycleNumSweeps(void* data, int num_sweeps, int k);
int hypre_BoomerAMGSetNumGridSweeps(void* data, int* num_grid_sweeps);
int hypre_BoomerAMGSetRelaxType(void* data, int relax_type);
int hypre_BoomerAMGSetCycleRelaxType(void* data, int relax_type, int k);
int hypre_BoomerAMGSetRelaxOrder(void* data, int relax_order);
int hypre_BoomerAMGSetGridRelaxType(void* data, int* grid_relax_type);
int hypre_BoomerAMGSetGridRelaxPoints(void* data, int** grid_relax_points);
int hypre_BoomerAMGSetRelaxWeight(void* data, double* relax_weight);
int hypre_BoomerAMGSetRelaxWt(void* data, double relax_weight);
int hypre_BoomerAMGSetOuterWt(void* data, double omega);
int hypre_BoomerAMGSetSmoothType(void* data, int smooth_type);
int hypre_BoomerAMGSetSmoothNumLevels(void* data, int smooth_num_levels);
int hypre_BoomerAMGSetSmoothNumSweeps(void* data, int smooth_num_sweeps);
int hypre_BoomerAMGSetLogging(void* data, int logging);
int hypre_BoomerAMGSetPrintLevel(void* data, int print_level);
int hypre_BoomerAMGSetPrintFileName(void* data, char* print_file_name);
int hypre_BoomerAMGSetNumIterations(void* data, int num_iterations);
int hypre_BoomerAMGSetDebugFlag(void* data, int debug_flag);
int hypre_BoomerAMGSetGSMG(void* data, int par);
int hypre_BoomerAMGSetNumSamples(void* data, int par);
int hypre_BoomerAMGSetNumFunctions(void* data, int num_functions);
int hypre_BoomerAMGSetNodal(void* data, int nodal);
int hypre_BoomerAMGSetNumPaths(void* data, int num_paths);
int hypre_BoomerAMGSetAggInterpType(void* data, int agg_interp_type);
int hypre_BoomerAMGSetAggPMaxElmts(void* data, int agg_P_max_elmts);
int hypre_BoomerAMGSetAggNumLevels(void* data, int agg_num_levels);
int hypre_BoomerAMGSetNumCRRelaxSteps(void* data, int num_CR_relax_steps);
int hypre_BoomerAMGSetCRRate(void* data, double CR_rate);
int hypre_BoomerAMGSetISType(void* data, int IS_type);
int hypre_BoomerAMGSetCRUseCG(void* data, int CR_use_CG);
int hypre_BoomerAMGSetVariant(void* data, int variant);
int hypre_BoomerAMGSetOverlap(void* data, int overlap);
int hypre_BoomerAMGSetChebyOrder(void* data, int order);
int hypre_BoomerAMGSetChebyEigRatio(void* data, double ratio);
int hypre_BoomerAMGSetup(void* amg_vdata, hypre_ParCSRMatrix* A, hypre_ParVector* f, hypre_ParVector* u);
int hypre_BoomerAMGSolve(void* amg_vdata, hypre_ParCSRMatrix* A, hypre_ParVector* f, hypre_ParVector* u);
int hypre_BoomerAMGCGRelaxWt(void* amg_vdata, int level, int num_cg_sweeps, double* rlx_wt_ptr);
int hypre_Bisection(int n, double* diag, double* offd, double y, double z, double tol, int k, double* ev_ptr);
int hypre_BoomerAMGCoarsen(hypre_ParCSRMatrix* S, hypre_ParCSRMatrix* A, int CF_init, int debug_flag, int** CF_marker_ptr);
int hypre_BoomerAMGCoarsenRuge(hypre_ParCSRMatrix* S, hypre_ParCSRMatrix* A, int measure_type, int coarsen_type, int debug_flag, int** CF_marker_ptr);
int hypre_BoomerAMGCoarsenFalgout(hypre_ParCSRMatrix* S, hypre_ParCSRMatrix* A, int measure_type, int debug_flag, int** CF_marker_ptr);
int hypre_BoomerAMGCoarsenHMIS(hypre_ParCSRMatrix* S, hypre_ParCSRMatrix* A, int measure_type, int debug_flag, int** CF_marker_ptr);
int hypre_BoomerAMGCoarsenPMIS(hypre_ParCSRMatrix* S, hypre_ParCSRMatrix* A, int CF_init, int debug_flag, int** CF_marker_ptr);
int hypre_BoomerAMGCoarseParms(MPI_Comm comm, int local_num_variables, int num_functions, int* dof_func, int* CF_marker, int** coarse_dof_func_ptr, int** coarse_pnts_global_ptr);
int hypre_BoomerAMGCycle(void* amg_vdata, hypre_ParVector** F_array, hypre_ParVector** U_array);
int hypre_BoomerAMGIndepSetInit(hypre_ParCSRMatrix* S, double* measure_array, int seq_rand);
int hypre_BoomerAMGIndepSet(hypre_ParCSRMatrix* S, double* measure_array, int* graph_array, int graph_array_size, int* graph_array_offd, int graph_array_offd_size, int* IS_marker, int* IS_marker_offd);
int hypre_BoomerAMGBuildInterp(hypre_ParCSRMatrix* A, int* CF_marker, hypre_ParCSRMatrix* S, int* num_cpts_global, int num_functions, int* dof_func, int debug_flag, double trunc_factor, int max_elmts, int* col_offd_S_to_A, hypre_ParCSRMatrix** P_ptr);
int hypre_BoomerAMGInterpTruncation(hypre_ParCSRMatrix* P, double trunc_factor, int max_elmts);
void hypre_qsort2abs(int* v, double* w, int left, int right);
void hypre_BoomerAMGJacobiInterp(hypre_ParCSRMatrix* A, hypre_ParCSRMatrix** P, hypre_ParCSRMatrix* S, int num_functions, int* dof_func, int* CF_marker, int level, double truncation_threshold, double truncation_threshold_minus);
void hypre_BoomerAMGJacobiInterp_1(hypre_ParCSRMatrix* A, hypre_ParCSRMatrix** P, hypre_ParCSRMatrix* S, int* CF_marker, int level, double truncation_threshold, double truncation_threshold_minus, int* dof_func, int* dof_func_offd, double weight_AF);
void hypre_BoomerAMGTruncateInterp(hypre_ParCSRMatrix* P, double eps, double dlt, int* CF_marker);
int hypre_ParCSRMatrix_dof_func_offd(hypre_ParCSRMatrix* A, int num_functions, int* dof_func, int** dof_func_offd);
int hypre_map(int ix, int iy, int iz, int p, int q, int r, int P, int Q, int R, int* nx_part, int* ny_part, int* nz_part, int* global_part, int* value_ptr);
int hypre_BoomerAMGBuildStdInterp(hypre_ParCSRMatrix* A, int* CF_marker, hypre_ParCSRMatrix* S, int* num_cpts_global, int num_functions, int* dof_func, int debug_flag, double trunc_factor, int max_elmts, int sep_weight, int* col_offd_S_to_A, hypre_ParCSRMatrix** P_ptr);
int hypre_BoomerAMGBuildExtPIInterp(hypre_ParCSRMatrix* A, int* CF_marker, hypre_ParCSRMatrix* S, int* num_cpts_global, int num_functions, int* dof_func, int debug_flag, double trunc_factor, int max_elmts, int* col_offd_S_to_A, hypre_ParCSRMatrix** P_ptr);
int hypre_BoomerAMGBuildExtPICCInterp(hypre_ParCSRMatrix* A, int* CF_marker, hypre_ParCSRMatrix* S, int* num_cpts_global, int num_functions, int* dof_func, int debug_flag, double trunc_factor, int max_elmts, int* col_offd_S_to_A, hypre_ParCSRMatrix** P_ptr);
int hypre_BoomerAMGBuildFF1Interp(hypre_ParCSRMatrix* A, int* CF_marker, hypre_ParCSRMatrix* S, int* num_cpts_global, int num_functions, int* dof_func, int debug_flag, double trunc_factor, int max_elmts, int* col_offd_S_to_A, hypre_ParCSRMatrix** P_ptr);
int hypre_BoomerAMGBuildExtInterp(hypre_ParCSRMatrix* A, int* CF_marker, hypre_ParCSRMatrix* S, int* num_cpts_global, int num_functions, int* dof_func, int debug_flag, double trunc_factor, int max_elmts, int* col_offd_S_to_A, hypre_ParCSRMatrix** P_ptr);
int hypre_BoomerAMGBuildMultipass(hypre_ParCSRMatrix* A, int* CF_marker, hypre_ParCSRMatrix* S, int* num_cpts_global, int num_functions, int* dof_func, int debug_flag, double trunc_factor, int P_max_elmts, int weight_option, int* col_offd_S_to_A, hypre_ParCSRMatrix** P_ptr);
int hypre_BoomerAMGCreateNodalA(hypre_ParCSRMatrix* A, int num_functions, int* dof_func, int option, hypre_ParCSRMatrix** AN_ptr);
int hypre_BoomerAMGCreateScalarCFS(hypre_ParCSRMatrix* SN, int* CFN_marker, int* col_offd_SN_to_AN, int num_functions, int nodal, int data, int** dof_func_ptr, int** CF_marker_ptr, int** col_offd_S_to_A_ptr, hypre_ParCSRMatrix** S_ptr);
hypre_BigCSRMatrix* hypre_ExchangeRAPData(hypre_BigCSRMatrix* RAP_int, hypre_ParCSRCommPkg* comm_pkg_RT);
int hypre_BoomerAMGBuildCoarseOperator(hypre_ParCSRMatrix* RT, hypre_ParCSRMatrix* A, hypre_ParCSRMatrix* P, hypre_ParCSRMatrix** RAP_ptr);
int hypre_GetCommPkgRTFromCommPkgA(hypre_ParCSRMatrix* RT, hypre_ParCSRMatrix* A, int* fine_to_coarse, int* tmp_map_offd);
int hypre_BoomerAMGRelax(hypre_ParCSRMatrix* A, hypre_ParVector* f, int* cf_marker, int relax_type, int relax_points, double relax_weight, double omega, double* l1_norms, hypre_ParVector* u, hypre_ParVector* Vtemp, hypre_ParVector* Ztemp);
int gselim(double* A, double* x, int n);
int hypre_BoomerAMGRelaxIF(hypre_ParCSRMatrix* A, hypre_ParVector* f, int* cf_marker, int relax_type, int relax_order, int cycle_type, double relax_weight, double omega, double* l1_norms, hypre_ParVector* u, hypre_ParVector* Vtemp, hypre_ParVector* Ztemp);
int hypre_ParCSRMatrixScaledNorm(hypre_ParCSRMatrix* A, double* scnorm);
int hypre_BoomerAMGSetupStats(void* amg_vdata, hypre_ParCSRMatrix* A);
int hypre_BoomerAMGWriteSolverParams(void* data);
int hypre_BoomerAMGCreateS(hypre_ParCSRMatrix* A, double strength_threshold, double max_row_sum, int num_functions, int* dof_func, hypre_ParCSRMatrix** S_ptr);
int hypre_BoomerAMGCreateSabs(hypre_ParCSRMatrix* A, double strength_threshold, double max_row_sum, int num_functions, int* dof_func, hypre_ParCSRMatrix** S_ptr);
int hypre_BoomerAMGCreateSCommPkg(hypre_ParCSRMatrix* A, hypre_ParCSRMatrix* S, int** col_offd_S_to_A_ptr);
int hypre_BoomerAMGCreate2ndS(hypre_ParCSRMatrix* S, int* CF_marker, int num_paths, int* coarse_row_starts, hypre_ParCSRMatrix** C_ptr);
int hypre_BoomerAMGCorrectCFMarker(int* CF_marker, int num_var, int* new_CF_marker);
int hypre_BoomerAMGCorrectCFMarker2(int* CF_marker, int num_var, int* new_CF_marker);
double afun(double xx, double yy, double zz);
double bfun(double xx, double yy, double zz);
double cfun(double xx, double yy, double zz);
double dfun(double xx, double yy, double zz);
double efun(double xx, double yy, double zz);
double ffun(double xx, double yy, double zz);
double gfun(double xx, double yy, double zz);
double rfun(double xx, double yy, double zz);
double bndfun(double xx, double yy, double zz);
int hypre_BoomerAMGBuildPartialStdInterp(hypre_ParCSRMatrix* A, int* CF_marker, hypre_ParCSRMatrix* S, int* num_cpts_global, int* num_old_cpts_global, int num_functions, int* dof_func, int debug_flag, double trunc_factor, int max_elmts, int sep_weight, int* col_offd_S_to_A, hypre_ParCSRMatrix** P_ptr);
int hypre_BoomerAMGBuildPartialExtPIInterp(hypre_ParCSRMatrix* A, int* CF_marker, hypre_ParCSRMatrix* S, int* num_cpts_global, int* num_old_cpts_global, int num_functions, int* dof_func, int debug_flag, double trunc_factor, int max_elmts, int* col_offd_S_to_A, hypre_ParCSRMatrix** P_ptr);
int hypre_BoomerAMGBuildPartialExtInterp(hypre_ParCSRMatrix* A, int* CF_marker, hypre_ParCSRMatrix* S, int* num_cpts_global, int* num_old_cpts_global, int num_functions, int* dof_func, int debug_flag, double trunc_factor, int max_elmts, int* col_offd_S_to_A, hypre_ParCSRMatrix** P_ptr);
int hypre_ParKrylovFree(char* ptr);
void* hypre_ParKrylovCreateVector(void* vvector);
void* hypre_ParKrylovCreateVectorArray(int n, void* vvector);
int hypre_ParKrylovDestroyVector(void* vvector);
void* hypre_ParKrylovMatvecCreate(void* A, void* x);
int hypre_ParKrylovMatvec(void* matvec_data, double alpha, void* A, void* x, double beta, void* y);
int hypre_ParKrylovMatvecDestroy(void* matvec_data);
double hypre_ParKrylovInnerProd(void* x, void* y);
int hypre_ParKrylovCopyVector(void* x, void* y);
int hypre_ParKrylovClearVector(void* x);
int hypre_ParKrylovScaleVector(double alpha, void* x);
int hypre_ParKrylovAxpy(double alpha, void* x, void* y);
int hypre_ParKrylovCommInfo(void* A, int* my_id, int* num_procs);
int hypre_ParKrylovIdentitySetup(void* vdata, void* A, void* b, void* x);
int hypre_ParKrylovIdentity(void* vdata, void* A, void* b, void* x);
int hypre_ParCSRMaxEigEstimateCG(hypre_ParCSRMatrix* A, int scale, int max_iter, double* max_eig, double* min_eig);
int hypre_ParCSRRelax_Cheby(hypre_ParCSRMatrix* A, hypre_ParVector* f, double max_eig, double min_eig, double eig_ratio, int order, int scale, int variant, hypre_ParVector* u, hypre_ParVector* v, hypre_ParVector* v2);
int hypre_BoomerAMGRelax_FCFJacobi(hypre_ParCSRMatrix* A, hypre_ParVector* f, int* cf_marker, double relax_weight, hypre_ParVector* u, hypre_ParVector* Vtemp);
int hypre_ParCSRRelax_CG(HYPRE_Solver solver, hypre_ParCSRMatrix* A, hypre_ParVector* f, hypre_ParVector* u, int num_its);
int hypre_ParCSRComputeL1Norms(hypre_ParCSRMatrix* A, int option, int* cf_marker, double** l1_norm_ptr);
int hypre_ParCSRComputeL1NormsThreads(hypre_ParCSRMatrix* A, int option, int num_threads, int* cf_marker, double** l1_norm_ptr);
int hypre_ParCSRRelax_L1(hypre_ParCSRMatrix* A, hypre_ParVector* f, double relax_weight, double omega, double* l1_norms, hypre_ParVector* u, hypre_ParVector* v, hypre_ParVector* z);
int hypre_ParCSRRelax_L1_GS(hypre_ParCSRMatrix* A, hypre_ParVector* f, double relax_weight, double omega, double* l1_norms, hypre_ParVector* u, hypre_ParVector* v, hypre_ParVector* z);
int hypre_ParCSRRelax_L1_Jacobi(hypre_ParCSRMatrix* A, hypre_ParVector* f, int* cf_marker, int relax_points, double relax_weight, double* l1_norms, hypre_ParVector* u, hypre_ParVector* Vtemp);
//=================== HYPRE_parcsr_amg.c ===================
int HYPRE_BoomerAMGCreate(HYPRE_Solver* solver) {
  *solver = (HYPRE_Solver)(hypre_BoomerAMGCreate());
  if (!solver)
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/HYPRE_parcsr_amg.c", 908, 4 | (1 << 3));
  return hypre__global_error;
}
int HYPRE_BoomerAMGDestroy(HYPRE_Solver solver) {
  return hypre_BoomerAMGDestroy((void*)solver);
}
int HYPRE_BoomerAMGSetup(HYPRE_Solver solver, HYPRE_ParCSRMatrix A, HYPRE_ParVector b, HYPRE_ParVector x) {
  return hypre_BoomerAMGSetup((void*)solver, (hypre_ParCSRMatrix*)A, (hypre_ParVector*)b, (hypre_ParVector*)x);
}
int HYPRE_BoomerAMGSolve(HYPRE_Solver solver, HYPRE_ParCSRMatrix A, HYPRE_ParVector b, HYPRE_ParVector x) {
  return hypre_BoomerAMGSolve((void*)solver, (hypre_ParCSRMatrix*)A, (hypre_ParVector*)b, (hypre_ParVector*)x);
}
int HYPRE_BoomerAMGSetStrongThreshold(HYPRE_Solver solver, double strong_threshold) {
  return hypre_BoomerAMGSetStrongThreshold((void*)solver, strong_threshold);
}
int HYPRE_BoomerAMGSetMaxRowSum(HYPRE_Solver solver, double max_row_sum) {
  return hypre_BoomerAMGSetMaxRowSum((void*)solver, max_row_sum);
}
int HYPRE_BoomerAMGSetTruncFactor(HYPRE_Solver solver, double trunc_factor) {
  return hypre_BoomerAMGSetTruncFactor((void*)solver, trunc_factor);
}
int HYPRE_BoomerAMGSetPMaxElmts(HYPRE_Solver solver, int P_max_elmts) {
  return hypre_BoomerAMGSetPMaxElmts((void*)solver, P_max_elmts);
}
int HYPRE_BoomerAMGSetInterpType(HYPRE_Solver solver, int interp_type) {
  return hypre_BoomerAMGSetInterpType((void*)solver, interp_type);
}
int HYPRE_BoomerAMGSetMaxIter(HYPRE_Solver solver, int max_iter) {
  return hypre_BoomerAMGSetMaxIter((void*)solver, max_iter);
}
int HYPRE_BoomerAMGSetCoarsenType(HYPRE_Solver solver, int coarsen_type) {
  return hypre_BoomerAMGSetCoarsenType((void*)solver, coarsen_type);
}
int HYPRE_BoomerAMGSetTol(HYPRE_Solver solver, double tol) {
  return hypre_BoomerAMGSetTol((void*)solver, tol);
}
int HYPRE_BoomerAMGSetNumGridSweeps(HYPRE_Solver solver, int* num_grid_sweeps) {
  return hypre_BoomerAMGSetNumGridSweeps((void*)solver, num_grid_sweeps);
}
int HYPRE_BoomerAMGSetCycleNumSweeps(HYPRE_Solver solver, int num_sweeps, int k) {
  return hypre_BoomerAMGSetCycleNumSweeps((void*)solver, num_sweeps, k);
}
int HYPRE_BoomerAMGSetGridRelaxType(HYPRE_Solver solver, int* grid_relax_type) {
  return hypre_BoomerAMGSetGridRelaxType((void*)solver, grid_relax_type);
}
int HYPRE_BoomerAMGSetRelaxType(HYPRE_Solver solver, int relax_type) {
  return hypre_BoomerAMGSetRelaxType((void*)solver, relax_type);
}
int HYPRE_BoomerAMGSetCycleRelaxType(HYPRE_Solver solver, int relax_type, int k) {
  return hypre_BoomerAMGSetCycleRelaxType((void*)solver, relax_type, k);
}
int HYPRE_BoomerAMGSetRelaxOrder(HYPRE_Solver solver, int relax_order) {
  return hypre_BoomerAMGSetRelaxOrder((void*)solver, relax_order);
}
int HYPRE_BoomerAMGSetGridRelaxPoints(HYPRE_Solver solver, int** grid_relax_points) {
  return hypre_BoomerAMGSetGridRelaxPoints((void*)solver, grid_relax_points);
}
int HYPRE_BoomerAMGSetRelaxWeight(HYPRE_Solver solver, double* relax_weight) {
  return hypre_BoomerAMGSetRelaxWeight((void*)solver, relax_weight);
}
int HYPRE_BoomerAMGSetPrintLevel(HYPRE_Solver solver, int print_level) {
  return hypre_BoomerAMGSetPrintLevel((void*)solver, print_level);
}
int HYPRE_BoomerAMGSetPrintFileName(HYPRE_Solver solver, char* print_file_name) {
  return hypre_BoomerAMGSetPrintFileName((void*)solver, print_file_name);
}
int HYPRE_BoomerAMGSetNumFunctions(HYPRE_Solver solver, int num_functions) {
  return hypre_BoomerAMGSetNumFunctions((void*)solver, num_functions);
}
int HYPRE_BoomerAMGSetAggNumLevels(HYPRE_Solver solver, int agg_num_levels) {
  return hypre_BoomerAMGSetAggNumLevels((void*)solver, agg_num_levels);
}
//================== HYPRE_parcsr_gmres.c ==================
int HYPRE_ParCSRGMRESCreate(MPI_Comm comm, HYPRE_Solver* solver) {
  hypre_GMRESFunctions* gmres_functions = hypre_GMRESFunctionsCreate(hypre_CAlloc, hypre_ParKrylovFree, hypre_ParKrylovCommInfo, hypre_ParKrylovCreateVector, hypre_ParKrylovCreateVectorArray, hypre_ParKrylovDestroyVector, hypre_ParKrylovMatvecCreate, hypre_ParKrylovMatvec, hypre_ParKrylovMatvecDestroy, hypre_ParKrylovInnerProd, hypre_ParKrylovCopyVector, hypre_ParKrylovClearVector, hypre_ParKrylovScaleVector, hypre_ParKrylovAxpy, hypre_ParKrylovIdentitySetup, hypre_ParKrylovIdentity);
  *solver = (HYPRE_Solver)(hypre_GMRESCreate(gmres_functions));
  if (!solver)
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/HYPRE_parcsr_gmres.c", 908, 4 | (2 << 3));
  return hypre__global_error;
}
int HYPRE_ParCSRGMRESDestroy(HYPRE_Solver solver) {
  return hypre_GMRESDestroy((void*)solver);
}
//=================== HYPRE_parcsr_pcg.c ===================
int HYPRE_ParCSRPCGCreate(MPI_Comm comm, HYPRE_Solver* solver) {
  hypre_PCGFunctions* pcg_functions = hypre_PCGFunctionsCreate(hypre_CAlloc, hypre_ParKrylovFree, hypre_ParKrylovCommInfo, hypre_ParKrylovCreateVector, hypre_ParKrylovDestroyVector, hypre_ParKrylovMatvecCreate, hypre_ParKrylovMatvec, hypre_ParKrylovMatvecDestroy, hypre_ParKrylovInnerProd, hypre_ParKrylovCopyVector, hypre_ParKrylovClearVector, hypre_ParKrylovScaleVector, hypre_ParKrylovAxpy, hypre_ParKrylovIdentitySetup, hypre_ParKrylovIdentity);
  *solver = (HYPRE_Solver)(hypre_PCGCreate(pcg_functions));
  if (!solver)
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/HYPRE_parcsr_pcg.c", 908, 4 | (2 << 3));
  return hypre__global_error;
}
int HYPRE_ParCSRPCGDestroy(HYPRE_Solver solver) {
  return hypre_PCGDestroy((void*)solver);
}
int HYPRE_ParCSRPCGSetup(HYPRE_Solver solver, HYPRE_ParCSRMatrix A, HYPRE_ParVector b, HYPRE_ParVector x) {
  return HYPRE_PCGSetup(solver, (HYPRE_Matrix)A, (HYPRE_Vector)b, (HYPRE_Vector)x);
}
int HYPRE_ParCSRPCGSolve(HYPRE_Solver solver, HYPRE_ParCSRMatrix A, HYPRE_ParVector b, HYPRE_ParVector x) {
  return HYPRE_PCGSolve(solver, (HYPRE_Matrix)A, (HYPRE_Vector)b, (HYPRE_Vector)x);
}
int HYPRE_ParCSRDiagScaleSetup(HYPRE_Solver solver, HYPRE_ParCSRMatrix A, HYPRE_ParVector y, HYPRE_ParVector x) {
  return 0;
}
int HYPRE_ParCSRDiagScale(HYPRE_Solver solver, HYPRE_ParCSRMatrix HA, HYPRE_ParVector Hy, HYPRE_ParVector Hx) {
  hypre_ParCSRMatrix* A = (hypre_ParCSRMatrix*)HA;
  hypre_ParVector* y = (hypre_ParVector*)Hy;
  hypre_ParVector* x = (hypre_ParVector*)Hx;
  double* x_data = ((x)->local_vector)->data;
  double* y_data = ((y)->local_vector)->data;
  double* A_data = ((A)->diag)->data;
  int* A_i = ((A)->diag)->i;
  int local_size = ((x)->local_vector)->size;
  int i;
  int ierr = 0;
  for (i = 0; i < local_size; i++) {
    x_data[i] = (y_data[i]) / (A_data[A_i[i]]);
  }
  return ierr;
}
//====================== aux_interp.c ======================
int alt_insert_new_nodes(hypre_ParCSRCommPkg* comm_pkg, hypre_ParCSRCommPkg* extend_comm_pkg, int* IN_marker, int full_off_procNodes, int* OUT_marker) {
  hypre_ParCSRCommHandle* comm_handle;
  int i;
  int j;
  int start;
  int index;
  int shift;
  int num_sends;
  int num_recvs;
  int* recv_vec_starts;
  int e_num_sends;
  int* int_buf_data;
  int* e_out_marker;
  num_sends = (comm_pkg)->num_sends;
  num_recvs = (comm_pkg)->num_recvs;
  recv_vec_starts = (comm_pkg)->recv_vec_starts;
  e_num_sends = (extend_comm_pkg)->num_sends;
  index = ((comm_pkg)->send_map_starts[num_sends]) < ((extend_comm_pkg)->send_map_starts[e_num_sends]) ? (extend_comm_pkg)->send_map_starts[e_num_sends] : (comm_pkg)->send_map_starts[num_sends];
  int_buf_data = (int*)(hypre_CAlloc((unsigned)index, (unsigned)(sizeof(int))));
  index = 0;
  for (i = 0; i < num_sends; i++) {
    start = (comm_pkg)->send_map_starts[i];
    for (j = start; j < ((comm_pkg)->send_map_starts[i + 1]); j++)
      int_buf_data[index++] = IN_marker[(comm_pkg)->send_map_elmts[j]];
  }
  comm_handle = hypre_ParCSRCommHandleCreate(11, comm_pkg, int_buf_data, OUT_marker);
  hypre_ParCSRCommHandleDestroy(comm_handle);
  comm_handle = (void*)0;
  shift = recv_vec_starts[num_recvs];
  e_out_marker = OUT_marker + shift;
  index = 0;
  for (i = 0; i < e_num_sends; i++) {
    start = (extend_comm_pkg)->send_map_starts[i];
    for (j = start; j < ((extend_comm_pkg)->send_map_starts[i + 1]); j++)
      int_buf_data[index++] = IN_marker[(extend_comm_pkg)->send_map_elmts[j]];
  }
  comm_handle = hypre_ParCSRCommHandleCreate(11, extend_comm_pkg, int_buf_data, e_out_marker);
  hypre_ParCSRCommHandleDestroy(comm_handle);
  comm_handle = (void*)0;
  hypre_Free((char*)int_buf_data), int_buf_data = (void*)0;
  return hypre__global_error;
}
int big_insert_new_nodes(hypre_ParCSRCommPkg* comm_pkg, hypre_ParCSRCommPkg* extend_comm_pkg, int* IN_marker, int full_off_procNodes, int offset, int* OUT_marker) {
  hypre_ParCSRCommHandle* comm_handle;
  int i;
  int j;
  int start;
  int index;
  int shift;
  int num_sends;
  int num_recvs;
  int* recv_vec_starts;
  int e_num_sends;
  int* big_buf_data;
  int* e_out_marker;
  num_sends = (comm_pkg)->num_sends;
  num_recvs = (comm_pkg)->num_recvs;
  recv_vec_starts = (comm_pkg)->recv_vec_starts;
  e_num_sends = (extend_comm_pkg)->num_sends;
  index = ((comm_pkg)->send_map_starts[num_sends]) < ((extend_comm_pkg)->send_map_starts[e_num_sends]) ? (extend_comm_pkg)->send_map_starts[e_num_sends] : (comm_pkg)->send_map_starts[num_sends];
  big_buf_data = (int*)(hypre_CAlloc((unsigned)index, (unsigned)(sizeof(int))));
  index = 0;
  for (i = 0; i < num_sends; i++) {
    start = (comm_pkg)->send_map_starts[i];
    for (j = start; j < ((comm_pkg)->send_map_starts[i + 1]); j++)
      big_buf_data[index++] = offset + (int)(IN_marker[(comm_pkg)->send_map_elmts[j]]);
  }
  comm_handle = hypre_ParCSRCommHandleCreate(21, comm_pkg, big_buf_data, OUT_marker);
  hypre_ParCSRCommHandleDestroy(comm_handle);
  comm_handle = (void*)0;
  shift = recv_vec_starts[num_recvs];
  e_out_marker = OUT_marker + shift;
  index = 0;
  for (i = 0; i < e_num_sends; i++) {
    start = (extend_comm_pkg)->send_map_starts[i];
    for (j = start; j < ((extend_comm_pkg)->send_map_starts[i + 1]); j++)
      big_buf_data[index++] = offset + (int)(IN_marker[(extend_comm_pkg)->send_map_elmts[j]]);
  }
  comm_handle = hypre_ParCSRCommHandleCreate(21, extend_comm_pkg, big_buf_data, e_out_marker);
  hypre_ParCSRCommHandleDestroy(comm_handle);
  comm_handle = (void*)0;
  hypre_Free((char*)big_buf_data), big_buf_data = (void*)0;
  return hypre__global_error;
}
int hypre_ParCSRFindExtendCommPkg(hypre_ParCSRMatrix* A, int newoff, int* found, hypre_ParCSRCommPkg** extend_comm_pkg) {
  int num_sends;
  int* send_procs;
  int* send_map_starts;
  int* send_map_elmts;
  int num_recvs;
  int* recv_procs;
  int* recv_vec_starts;
  hypre_ParCSRCommPkg* new_comm_pkg;
  MPI_Comm comm = (A)->comm;
  int first_col_diag = (A)->first_col_diag;
  int* col_starts = (A)->col_starts;
  int num_cols_diag = ((A)->diag)->num_cols;
  hypre_MatvecCommPkgCreate_core(comm, found, first_col_diag, col_starts, num_cols_diag, newoff, first_col_diag, found, 1, &(num_recvs), &(recv_procs), &(recv_vec_starts), &(num_sends), &(send_procs), &(send_map_starts), &(send_map_elmts));
  new_comm_pkg = (hypre_ParCSRCommPkg*)(hypre_CAlloc((unsigned)1, (unsigned)(sizeof(hypre_ParCSRCommPkg))));
  (new_comm_pkg)->comm = comm;
  (new_comm_pkg)->num_recvs = num_recvs;
  (new_comm_pkg)->recv_procs = recv_procs;
  (new_comm_pkg)->recv_vec_starts = recv_vec_starts;
  (new_comm_pkg)->num_sends = num_sends;
  (new_comm_pkg)->send_procs = send_procs;
  (new_comm_pkg)->send_map_starts = send_map_starts;
  (new_comm_pkg)->send_map_elmts = send_map_elmts;
  *extend_comm_pkg = new_comm_pkg;
  return hypre__global_error;
}
int new_offd_nodes(int** found, int num_cols_A_offd, int* A_ext_i, int* big_A_ext_j, int** A_ext_j_ptr, int num_cols_S_offd, int* col_map_offd, int col_1, int col_n, int* Sop_i, int* big_Sop_j, int** Sop_j_ptr, int* CF_marker, hypre_ParCSRCommPkg* comm_pkg) {
  int i;
  int ii;
  int j;
  int ifound;
  int kk;
  int got_loc;
  int loc_col;
  int min;
  int size_offP;
  int* tmp_found;
  int big_ifound;
  int big_i1;
  int big_k1;
  int* CF_marker_offd = (void*)0;
  int* int_buf_data;
  int* loc;
  int* A_ext_j;
  int* Sop_j;
  int newoff = 0;
  hypre_ParCSRCommHandle* comm_handle;
  CF_marker_offd = (int*)(hypre_CAlloc((unsigned)num_cols_A_offd, (unsigned)(sizeof(int))));
  int_buf_data = (int*)(hypre_CAlloc((unsigned)((comm_pkg)->send_map_starts[(comm_pkg)->num_sends]), (unsigned)(sizeof(int))));
  ii = 0;
  for (i = 0; i < (comm_pkg)->num_sends; i++) {
    for (j = (comm_pkg)->send_map_starts[i]; j < ((comm_pkg)->send_map_starts[i + 1]); j++)
      int_buf_data[ii++] = CF_marker[(comm_pkg)->send_map_elmts[j]];
  }
  comm_handle = hypre_ParCSRCommHandleCreate(11, comm_pkg, int_buf_data, CF_marker_offd);
  hypre_ParCSRCommHandleDestroy(comm_handle);
  hypre_Free((char*)int_buf_data), int_buf_data = (void*)0;
  size_offP = A_ext_i[num_cols_A_offd];
  tmp_found = (int*)(hypre_CAlloc((unsigned)size_offP, (unsigned)(sizeof(int))));
  A_ext_j = (int*)(hypre_CAlloc((unsigned)size_offP, (unsigned)(sizeof(int))));
  loc = (int*)(hypre_CAlloc((unsigned)size_offP, (unsigned)(sizeof(int))));
  for (i = 0; i < num_cols_A_offd; i++) {
    if ((CF_marker_offd[i]) < 0) {
      for (j = A_ext_i[i]; j < (A_ext_i[i + 1]); j++) {
        big_i1 = big_A_ext_j[j];
        if ((big_i1 < col_1) || (big_i1 >= col_n)) {
          ifound = hypre_BigBinarySearch(col_map_offd, big_i1, num_cols_A_offd);
          if (ifound == (-1)) {
            tmp_found[newoff] = big_i1;
            loc[newoff++] = j;
          }
          else {
            A_ext_j[j] = (-ifound) - 1;
          }
        }
        else
          A_ext_j[j] = (int)(big_i1 - col_1);
      }
    }
  }
  if (newoff > 0) {
    hypre_BigQsort0(tmp_found, 0, newoff - 1);
    big_ifound = tmp_found[0];
    min = 1;
    for (i = 1; i < newoff; i++) {
      if ((tmp_found[i]) > big_ifound) {
        big_ifound = tmp_found[i];
        tmp_found[min++] = big_ifound;
      }
    }
  }
  for (i = 0; i < newoff; i++) {
    kk = hypre_BigBinarySearch(tmp_found, big_A_ext_j[loc[i]], min);
    A_ext_j[loc[i]] = ((-kk) - num_cols_A_offd) - 1;
  }
  if (newoff > 0)
    newoff = min;
  hypre_Free((char*)big_A_ext_j), big_A_ext_j = (void*)0;
  hypre_Free((char*)loc), loc = (void*)0;
  Sop_j = (int*)(hypre_CAlloc((unsigned)(Sop_i[num_cols_S_offd]), (unsigned)(sizeof(int))));
  if (newoff < num_cols_A_offd) {
    for (i = 0; i < num_cols_S_offd; i++) {
      if ((CF_marker_offd[i]) < 0) {
        for (kk = Sop_i[i]; kk < (Sop_i[i + 1]); kk++) {
          big_k1 = big_Sop_j[kk];
          if ((big_k1 < col_1) || (big_k1 >= col_n)) {
            got_loc = hypre_BigBinarySearch(tmp_found, big_k1, newoff);
            if (got_loc > (-1))
              loc_col = got_loc + num_cols_A_offd;
            else
              loc_col = hypre_BigBinarySearch(col_map_offd, big_k1, num_cols_A_offd);
            if (loc_col < 0) {
              printf("Could not find node: STOP\n");
              return -1;
            }
            Sop_j[kk] = (-loc_col) - 1;
          }
          else
            Sop_j[kk] = (int)(big_k1 - col_1);
        }
      }
    }
  }
  else {
    for (i = 0; i < num_cols_S_offd; i++) {
      if ((CF_marker_offd[i]) < 0) {
        for (kk = Sop_i[i]; kk < (Sop_i[i + 1]); kk++) {
          big_k1 = big_Sop_j[kk];
          if ((big_k1 < col_1) || (big_k1 >= col_n)) {
            loc_col = hypre_BigBinarySearch(col_map_offd, big_k1, num_cols_A_offd);
            if (loc_col == (-1))
              loc_col = hypre_BigBinarySearch(tmp_found, big_k1, newoff) + num_cols_A_offd;
            if (loc_col < 0) {
              printf("Could not find node: STOP\n");
              return -1;
            }
            Sop_j[kk] = (-loc_col) - 1;
          }
          else
            Sop_j[kk] = (int)(big_k1 - col_1);
        }
      }
    }
  }
  hypre_Free((char*)big_Sop_j), big_Sop_j = (void*)0;
  hypre_Free((char*)CF_marker_offd), CF_marker_offd = (void*)0;
  *found = tmp_found;
  *A_ext_j_ptr = A_ext_j;
  *Sop_j_ptr = Sop_j;
  return newoff;
}
//===================== gen_redcs_mat.c ====================
int hypre_seqAMGSetup(hypre_ParAMGData* amg_data, int p_level, int coarse_threshold) {
  hypre_ParCSRMatrix** Par_A_array = (amg_data)->A_array;
  MPI_Comm comm = (Par_A_array[0])->comm;
  MPI_Comm new_comm;
  MPI_Comm seq_comm;
  hypre_ParCSRMatrix* A_seq = (void*)0;
  hypre_CSRMatrix* A_seq_diag;
  hypre_CSRMatrix* A_seq_offd;
  hypre_ParVector* F_seq = (void*)0;
  hypre_ParVector* U_seq = (void*)0;
  hypre_ParCSRMatrix* A;
  int** dof_func_array;
  int num_procs;
  int my_id;
  int not_finished_coarsening;
  int level;
  int redundant;
  HYPRE_Solver coarse_solver;
  dof_func_array = (amg_data)->dof_func_array;
  redundant = (amg_data)->redundant;
  MPI_Comm_size(comm, &(num_procs));
  level = p_level;
  not_finished_coarsening = 1;
  A = Par_A_array[level];
  {
    double* A_seq_data = (void*)0;
    int* A_seq_i = (void*)0;
    int* A_seq_offd_i = (void*)0;
    int* A_seq_j = (void*)0;
    double* A_tmp_data = (void*)0;
    int* A_tmp_i = (void*)0;
    int* A_tmp_j = (void*)0;
    int* info = (void*)0;
    int* displs = (void*)0;
    int* displs2 = (void*)0;
    int i;
    int j;
    int size;
    int num_nonzeros;
    int total_nnz;
    int cnt;
    hypre_CSRMatrix* A_diag = (A)->diag;
    hypre_CSRMatrix* A_offd = (A)->offd;
    int* col_map_offd = (A)->col_map_offd;
    int* A_diag_i = (A_diag)->i;
    int* A_offd_i = (A_offd)->i;
    int* A_diag_j = (A_diag)->j;
    int* A_offd_j = (A_offd)->j;
    double* A_diag_data = (A_diag)->data;
    double* A_offd_data = (A_offd)->data;
    int num_rows = (A_diag)->num_rows;
    int first_row_index = (A)->first_row_index;
    int new_num_procs;
    int* row_starts;
    hypre_GenerateSubComm(comm, num_rows, &(new_comm));
    if (num_rows) {
      (amg_data)->participate = 1;
      MPI_Comm_size(new_comm, &(new_num_procs));
      MPI_Comm_rank(new_comm, &(my_id));
      info = (int*)(hypre_CAlloc((unsigned)new_num_procs, (unsigned)(sizeof(int))));
      if (redundant)
        MPI_Allgather(&(num_rows), 1, MPI_INT, info, 1, MPI_INT, new_comm);
      else
        MPI_Gather(&(num_rows), 1, MPI_INT, info, 1, MPI_INT, 0, new_comm);
      if (redundant || (my_id == 0)) {
        HYPRE_BoomerAMGCreate(&(coarse_solver));
        HYPRE_BoomerAMGSetMaxRowSum(coarse_solver, (amg_data)->max_row_sum);
        HYPRE_BoomerAMGSetStrongThreshold(coarse_solver, (amg_data)->strong_threshold);
        HYPRE_BoomerAMGSetCoarsenType(coarse_solver, (amg_data)->coarsen_type);
        HYPRE_BoomerAMGSetInterpType(coarse_solver, (amg_data)->interp_type);
        HYPRE_BoomerAMGSetTruncFactor(coarse_solver, (amg_data)->trunc_factor);
        HYPRE_BoomerAMGSetPMaxElmts(coarse_solver, (amg_data)->P_max_elmts);
        HYPRE_BoomerAMGSetGridRelaxType(coarse_solver, (amg_data)->grid_relax_type);
        HYPRE_BoomerAMGSetGridRelaxPoints(coarse_solver, (amg_data)->grid_relax_points);
        HYPRE_BoomerAMGSetRelaxOrder(coarse_solver, (amg_data)->relax_order);
        HYPRE_BoomerAMGSetRelaxWeight(coarse_solver, &((amg_data)->relax_weight[p_level]));
        HYPRE_BoomerAMGSetNumGridSweeps(coarse_solver, (amg_data)->num_grid_sweeps);
        HYPRE_BoomerAMGSetNumFunctions(coarse_solver, (amg_data)->num_functions);
        HYPRE_BoomerAMGSetMaxIter(coarse_solver, 1);
        HYPRE_BoomerAMGSetTol(coarse_solver, 0);
      }
      A_tmp_i = (int*)(hypre_CAlloc((unsigned)(num_rows + 1), (unsigned)(sizeof(int))));
      A_tmp_i[0] = 0;
      for (i = 1; i < (num_rows + 1); i++)
        A_tmp_i[i] = (((A_diag_i[i]) - (A_diag_i[i - 1])) + (A_offd_i[i])) - (A_offd_i[i - 1]);
      num_nonzeros = (A_offd_i[num_rows]) + (A_diag_i[num_rows]);
      A_tmp_j = (int*)(hypre_CAlloc((unsigned)num_nonzeros, (unsigned)(sizeof(int))));
      A_tmp_data = (double*)(hypre_CAlloc((unsigned)num_nonzeros, (unsigned)(sizeof(double))));
      cnt = 0;
      for (i = 0; i < num_rows; i++) {
        for (j = A_diag_i[i]; j < (A_diag_i[i + 1]); j++) {
          A_tmp_j[cnt] = (int)(A_diag_j[j]) + first_row_index;
          A_tmp_data[cnt++] = A_diag_data[j];
        }
        for (j = A_offd_i[i]; j < (A_offd_i[i + 1]); j++) {
          A_tmp_j[cnt] = col_map_offd[A_offd_j[j]];
          A_tmp_data[cnt++] = A_offd_data[j];
        }
      }
      displs = (int*)(hypre_CAlloc((unsigned)(new_num_procs + 1), (unsigned)(sizeof(int))));
      displs[0] = 0;
      for (i = 1; i < (new_num_procs + 1); i++)
        displs[i] = (displs[i - 1]) + (info[i - 1]);
      size = displs[new_num_procs];
      if (redundant || (my_id == 0)) {
        A_seq_i = (int*)(hypre_CAlloc((unsigned)(size + 1), (unsigned)(sizeof(int))));
        A_seq_offd_i = (int*)(hypre_CAlloc((unsigned)(size + 1), (unsigned)(sizeof(int))));
      }
      if (redundant)
        MPI_Allgatherv(&(A_tmp_i[1]), num_rows, MPI_INT, &(A_seq_i[1]), info, displs, MPI_INT, new_comm);
      else
        MPI_Gatherv(&(A_tmp_i[1]), num_rows, MPI_INT, &(A_seq_i[1]), info, displs, MPI_INT, 0, new_comm);
      if (redundant || (my_id == 0)) {
        displs2 = (int*)(hypre_CAlloc((unsigned)(new_num_procs + 1), (unsigned)(sizeof(int))));
        A_seq_i[0] = 0;
        displs2[0] = 0;
        for (j = 1; j < (displs[1]); j++)
          A_seq_i[j] = (A_seq_i[j]) + (A_seq_i[j - 1]);
        for (i = 1; i < new_num_procs; i++) {
          for (j = displs[i]; j < (displs[i + 1]); j++) {
            A_seq_i[j] = (A_seq_i[j]) + (A_seq_i[j - 1]);
          }
        }
        A_seq_i[size] = (A_seq_i[size]) + (A_seq_i[size - 1]);
        displs2[new_num_procs] = A_seq_i[size];
        for (i = 1; i < (new_num_procs + 1); i++) {
          displs2[i] = A_seq_i[displs[i]];
          info[i - 1] = (displs2[i]) - (displs2[i - 1]);
        }
        total_nnz = displs2[new_num_procs];
        A_seq_j = (int*)(hypre_CAlloc((unsigned)total_nnz, (unsigned)(sizeof(int))));
        A_seq_data = (double*)(hypre_CAlloc((unsigned)total_nnz, (unsigned)(sizeof(double))));
      }
      if (redundant) {
        MPI_Allgatherv(A_tmp_j, num_nonzeros, MPI_INT, A_seq_j, info, displs2, MPI_INT, new_comm);
        MPI_Allgatherv(A_tmp_data, num_nonzeros, MPI_DOUBLE, A_seq_data, info, displs2, MPI_DOUBLE, new_comm);
      }
      else {
        MPI_Gatherv(A_tmp_j, num_nonzeros, MPI_INT, A_seq_j, info, displs2, MPI_INT, 0, new_comm);
        MPI_Gatherv(A_tmp_data, num_nonzeros, MPI_DOUBLE, A_seq_data, info, displs2, MPI_DOUBLE, 0, new_comm);
      }
      hypre_Free((char*)info), info = (void*)0;
      hypre_Free((char*)displs), displs = (void*)0;
      hypre_Free((char*)A_tmp_i), A_tmp_i = (void*)0;
      hypre_Free((char*)A_tmp_j), A_tmp_j = (void*)0;
      hypre_Free((char*)A_tmp_data), A_tmp_data = (void*)0;
      if (redundant || (my_id == 0)) {
        hypre_Free((char*)displs2), displs2 = (void*)0;
        row_starts = (int*)(hypre_CAlloc((unsigned)2, (unsigned)(sizeof(int))));
        row_starts[0] = 0;
        row_starts[1] = size;
        seq_comm = MPI_COMM_SELF;
        A_seq = hypre_ParCSRMatrixCreate(seq_comm, size, size, row_starts, row_starts, 0, total_nnz, 0);
        A_seq_diag = (A_seq)->diag;
        A_seq_offd = (A_seq)->offd;
        (A_seq_diag)->data = A_seq_data;
        (A_seq_diag)->i = A_seq_i;
        (A_seq_diag)->j = A_seq_j;
        (A_seq_offd)->i = A_seq_offd_i;
        F_seq = hypre_ParVectorCreate(seq_comm, size, row_starts);
        U_seq = hypre_ParVectorCreate(seq_comm, size, row_starts);
        (F_seq)->owns_partitioning = 0;
        (U_seq)->owns_partitioning = 0;
        hypre_ParVectorInitialize(F_seq);
        hypre_ParVectorInitialize(U_seq);
        hypre_BoomerAMGSetup(coarse_solver, A_seq, F_seq, U_seq);
        (amg_data)->coarse_solver = coarse_solver;
        (amg_data)->A_coarse = A_seq;
        (amg_data)->f_coarse = F_seq;
        (amg_data)->u_coarse = U_seq;
      }
      (amg_data)->new_comm = new_comm;
    }
  }
  return 0;
}
int hypre_seqAMGCycle(hypre_ParAMGData* amg_data, int p_level, hypre_ParVector** Par_F_array, hypre_ParVector** Par_U_array) {
  hypre_ParVector* Aux_U;
  hypre_ParVector* Aux_F;
  int Solve_err_flag = 0;
  int n;
  int i;
  hypre_Vector* u_local;
  double* u_data;
  int first_index;
  MPI_Comm new_comm = (amg_data)->new_comm;
  HYPRE_Solver coarse_solver = (amg_data)->coarse_solver;
  hypre_ParCSRMatrix* A_coarse = (amg_data)->A_coarse;
  hypre_ParVector* F_coarse = (amg_data)->f_coarse;
  hypre_ParVector* U_coarse = (amg_data)->u_coarse;
  int redundant = (amg_data)->redundant;
  Aux_U = Par_U_array[p_level];
  Aux_F = Par_F_array[p_level];
  first_index = (Aux_U)->first_index;
  u_local = (Aux_U)->local_vector;
  u_data = (u_local)->data;
  n = (u_local)->size;
  if ((amg_data)->participate) {
    double* f_data;
    hypre_Vector* f_local;
    hypre_Vector* tmp_vec;
    int nf;
    int local_info;
    double* recv_buf;
    int* displs = (void*)0;
    int* info = (void*)0;
    int size;
    int new_num_procs;
    int my_id;
    MPI_Comm_size(new_comm, &(new_num_procs));
    MPI_Comm_rank(new_comm, &(my_id));
    f_local = (Aux_F)->local_vector;
    f_data = (f_local)->data;
    nf = (f_local)->size;
    info = (int*)(hypre_CAlloc((unsigned)new_num_procs, (unsigned)(sizeof(int))));
    local_info = nf;
    if (redundant)
      MPI_Allgather(&(local_info), 1, MPI_INT, info, 1, MPI_INT, new_comm);
    else
      MPI_Gather(&(local_info), 1, MPI_INT, info, 1, MPI_INT, 0, new_comm);
    if (redundant || (my_id == 0)) {
      displs = (int*)(hypre_CAlloc((unsigned)(new_num_procs + 1), (unsigned)(sizeof(int))));
      displs[0] = 0;
      for (i = 1; i < (new_num_procs + 1); i++)
        displs[i] = (displs[i - 1]) + (info[i - 1]);
      size = displs[new_num_procs];
      tmp_vec = (F_coarse)->local_vector;
      recv_buf = (tmp_vec)->data;
    }
    if (redundant)
      MPI_Allgatherv(f_data, nf, MPI_DOUBLE, recv_buf, info, displs, MPI_DOUBLE, new_comm);
    else
      MPI_Gatherv(f_data, nf, MPI_DOUBLE, recv_buf, info, displs, MPI_DOUBLE, 0, new_comm);
    if (redundant || (my_id == 0)) {
      tmp_vec = (U_coarse)->local_vector;
      recv_buf = (tmp_vec)->data;
    }
    if (redundant) {
      MPI_Allgatherv(u_data, n, MPI_DOUBLE, recv_buf, info, displs, MPI_DOUBLE, new_comm);
      hypre_Free((char*)displs), displs = (void*)0;
      hypre_Free((char*)info), info = (void*)0;
    }
    else
      MPI_Gatherv(u_data, n, MPI_DOUBLE, recv_buf, info, displs, MPI_DOUBLE, 0, new_comm);
    if (redundant || (my_id == 0)) {
      hypre_BoomerAMGSolve(coarse_solver, A_coarse, F_coarse, U_coarse);
    }
    if (redundant) {
      double* local_data;
      local_data = ((U_coarse)->local_vector)->data;
      for (i = 0; i < n; i++) {
        u_data[i] = local_data[(int)first_index + i];
      }
    }
    else {
      double* local_data;
      if (my_id == 0)
        local_data = ((U_coarse)->local_vector)->data;
      MPI_Scatterv(local_data, info, displs, MPI_DOUBLE, u_data, n, MPI_DOUBLE, 0, new_comm);
      if (my_id == 0)
        hypre_Free((char*)displs), displs = (void*)0;
      hypre_Free((char*)info), info = (void*)0;
    }
  }
  return Solve_err_flag;
}
int hypre_GenerateSubComm(MPI_Comm comm, int participate, MPI_Comm* new_comm_ptr) {
  MPI_Comm new_comm;
  MPI_Group orig_group;
  MPI_Group new_group;
  MPI_Op hypre_MPI_MERGE;
  int* info;
  int* ranks;
  int new_num_procs;
  int my_info;
  int my_id;
  int num_procs;
  int* list_len;
  MPI_Comm_rank(comm, &(my_id));
  if (participate)
    my_info = 1;
  else
    my_info = 0;
  MPI_Allreduce(&(my_info), &(new_num_procs), 1, MPI_INT, _SUM, comm);
  if (new_num_procs == 0) {
    new_comm = MPI_COMM_NULL;
    *new_comm_ptr = new_comm;
    return 0;
  }
  ranks = (int*)(hypre_CAlloc((unsigned)(new_num_procs + 2), (unsigned)(sizeof(int))));
  if (new_num_procs == 1) {
    if (participate)
      my_info = my_id;
    MPI_Allreduce(&(my_info), &(ranks[2]), 1, MPI_INT, _SUM, comm);
  }
  else {
    info = (int*)(hypre_CAlloc((unsigned)(new_num_procs + 2), (unsigned)(sizeof(int))));
    list_len = (int*)(hypre_CAlloc((unsigned)1, (unsigned)(sizeof(int))));
    if (participate) {
      info[0] = 1;
      info[1] = 1;
      info[2] = my_id;
    }
    else
      info[0] = 0;
    list_len[0] = new_num_procs + 2;
    MPI_Op_create((MPI_User_function*)hypre_merge_lists, 0, &(hypre_MPI_MERGE));
    MPI_Allreduce(info, ranks, list_len[0], MPI_INT, hypre_MPI_MERGE, comm);
    MPI_Op_free(&(hypre_MPI_MERGE));
    hypre_Free((char*)list_len), list_len = (void*)0;
    hypre_Free((char*)info), info = (void*)0;
  }
  MPI_Comm_size(comm, &(num_procs));
  MPI_Comm_group(comm, &(orig_group));
  MPI_Group_incl(orig_group, new_num_procs, &(ranks[2]), &(new_group));
  MPI_Comm_create(comm, new_group, &(new_comm));
  MPI_Group_free(&(new_group));
  MPI_Group_free(&(orig_group));
  hypre_Free((char*)ranks), ranks = (void*)0;
  *new_comm_ptr = new_comm;
  return 0;
}
void hypre_merge_lists(int* list1, int* list2, int* np1, MPI_Datatype* dptr) {
  int i;
  int len1;
  int len2;
  int indx1;
  int indx2;
  if (((list1[0]) == 0) || (((list2[0]) == 0) && ((list1[0]) == 0))) {
    return;
  }
  else {
    list2[0] = 1;
    len1 = list1[1];
    len2 = list2[1];
    list2[1] = len1 + len2;
    if ((list2[1]) > ((*np1) + 2))
      printf("segfault in MPI User function merge_list\n");
    indx1 = len1 + 1;
    indx2 = len2 + 1;
    for (i = (len1 + len2) + 1; i > 1; i--) {
      if (((indx2 > 1) && (indx1 > 1)) && ((list1[indx1]) > (list2[indx2]))) {
        list2[i] = list1[indx1];
        indx1--;
      }
      else
        if (indx2 > 1) {
          list2[i] = list2[indx2];
          indx2--;
        }
        else
          if (indx1 > 1) {
            list2[i] = list1[indx1];
            indx1--;
          }
    }
  }
}
//======================== par_amg.c =======================
void* hypre_BoomerAMGCreate() {
  hypre_ParAMGData* amg_data;
  int max_levels;
  double strong_threshold;
  double max_row_sum;
  double trunc_factor;
  double agg_trunc_factor;
  double jacobi_trunc_threshold;
  double S_commpkg_switch;
  double CR_rate;
  int interp_type;
  int coarsen_type;
  int measure_type;
  int setup_type;
  int P_max_elmts;
  int P_max1;
  int P_max2;
  int num_functions;
  int nodal;
  int num_paths;
  int agg_interp_type;
  int agg_P_max_elmts;
  int agg_num_levels;
  int post_interp_type;
  int num_CR_relax_steps;
  int IS_type;
  int CR_use_CG;
  int seq_threshold;
  int coarse_threshold;
  int min_iter;
  int max_iter;
  int cycle_type;
  double tol;
  int num_sweeps;
  int relax_type;
  int relax_order;
  double relax_wt;
  double outer_wt;
  int smooth_type;
  int smooth_num_levels;
  int smooth_num_sweeps;
  int variant;
  int overlap;
  int domain_type;
  double schwarz_rlx_weight;
  int level;
  int sym;
  double thresh;
  double filter;
  double drop_tol;
  int max_nz_per_row;
  char* euclidfile;
  int cheby_order;
  double cheby_eig_ratio;
  int block_mode;
  int num_iterations;
  int cum_num_iterations;
  int print_level;
  int logging;
  char  log_file_name[256];
  int debug_flag;
  max_levels = 25;
  strong_threshold = 0.25;
  max_row_sum = 0.9;
  trunc_factor = 0.0;
  agg_trunc_factor = 0.0;
  jacobi_trunc_threshold = 0.01;
  S_commpkg_switch = 1.0;
  interp_type = 0;
  coarsen_type = 6;
  measure_type = 0;
  setup_type = 1;
  P_max_elmts = 0;
  P_max1 = 0;
  P_max2 = 0;
  num_functions = 1;
  nodal = 0;
  agg_interp_type = 4;
  agg_P_max_elmts = 0;
  num_paths = 1;
  agg_num_levels = 0;
  post_interp_type = 0;
  num_CR_relax_steps = 2;
  CR_rate = 0.7;
  IS_type = 1;
  CR_use_CG = 0;
  seq_threshold = 0;
  coarse_threshold = 9;
  variant = 0;
  overlap = 1;
  domain_type = 2;
  schwarz_rlx_weight = 1.0;
  smooth_num_sweeps = 1;
  smooth_num_levels = 0;
  smooth_type = 6;
  level = 1;
  sym = 0;
  thresh = 0.1;
  filter = 0.05;
  drop_tol = 0.0001;
  max_nz_per_row = 20;
  euclidfile = (void*)0;
  min_iter = 0;
  max_iter = 20;
  cycle_type = 1;
  tol = 1.0e-7;
  num_sweeps = 1;
  relax_type = 3;
  relax_order = 1;
  relax_wt = 1.0;
  outer_wt = 1.0;
  cheby_order = 2;
  cheby_eig_ratio = .3;
  block_mode = 0;
  num_iterations = 0;
  cum_num_iterations = 0;
  print_level = 0;
  logging = 0;
  sprintf(log_file_name, "%s", "amg.out.log");
  debug_flag = 0;
  amg_data = (hypre_ParAMGData*)(hypre_CAlloc((unsigned)1, (unsigned)(sizeof(hypre_ParAMGData))));
  (amg_data)->seq_threshold = seq_threshold;
  (amg_data)->max_coarse_size = coarse_threshold;
  (amg_data)->seq_data = (void*)0;
  (amg_data)->user_coarse_relax_type = 9;
  hypre_BoomerAMGSetMaxLevels(amg_data, max_levels);
  hypre_BoomerAMGSetStrongThreshold(amg_data, strong_threshold);
  hypre_BoomerAMGSetMaxRowSum(amg_data, max_row_sum);
  hypre_BoomerAMGSetTruncFactor(amg_data, trunc_factor);
  hypre_BoomerAMGSetAggTruncFactor(amg_data, agg_trunc_factor);
  hypre_BoomerAMGSetJacobiTruncThreshold(amg_data, jacobi_trunc_threshold);
  hypre_BoomerAMGSetSCommPkgSwitch(amg_data, S_commpkg_switch);
  hypre_BoomerAMGSetInterpType(amg_data, interp_type);
  hypre_BoomerAMGSetMeasureType(amg_data, measure_type);
  hypre_BoomerAMGSetCoarsenType(amg_data, coarsen_type);
  hypre_BoomerAMGSetSetupType(amg_data, setup_type);
  hypre_BoomerAMGSetPMaxElmts(amg_data, P_max_elmts);
  hypre_BoomerAMGSetPMax1(amg_data, P_max1);
  hypre_BoomerAMGSetPMax2(amg_data, P_max2);
  hypre_BoomerAMGSetNumFunctions(amg_data, num_functions);
  hypre_BoomerAMGSetNodal(amg_data, nodal);
  hypre_BoomerAMGSetAggInterpType(amg_data, agg_interp_type);
  hypre_BoomerAMGSetAggPMaxElmts(amg_data, agg_P_max_elmts);
  hypre_BoomerAMGSetNumPaths(amg_data, num_paths);
  hypre_BoomerAMGSetAggNumLevels(amg_data, agg_num_levels);
  hypre_BoomerAMGSetPostInterpType(amg_data, post_interp_type);
  hypre_BoomerAMGSetNumCRRelaxSteps(amg_data, num_CR_relax_steps);
  hypre_BoomerAMGSetCRRate(amg_data, CR_rate);
  hypre_BoomerAMGSetISType(amg_data, IS_type);
  hypre_BoomerAMGSetCRUseCG(amg_data, CR_use_CG);
  hypre_BoomerAMGSetVariant(amg_data, variant);
  hypre_BoomerAMGSetOverlap(amg_data, overlap);
  hypre_BoomerAMGSetMinIter(amg_data, min_iter);
  hypre_BoomerAMGSetMaxIter(amg_data, max_iter);
  hypre_BoomerAMGSetCycleType(amg_data, cycle_type);
  hypre_BoomerAMGSetTol(amg_data, tol);
  hypre_BoomerAMGSetNumSweeps(amg_data, num_sweeps);
  hypre_BoomerAMGSetRelaxType(amg_data, relax_type);
  hypre_BoomerAMGSetRelaxOrder(amg_data, relax_order);
  hypre_BoomerAMGSetRelaxWt(amg_data, relax_wt);
  hypre_BoomerAMGSetOuterWt(amg_data, outer_wt);
  hypre_BoomerAMGSetSmoothType(amg_data, smooth_type);
  hypre_BoomerAMGSetSmoothNumLevels(amg_data, smooth_num_levels);
  hypre_BoomerAMGSetSmoothNumSweeps(amg_data, smooth_num_sweeps);
  hypre_BoomerAMGSetChebyOrder(amg_data, cheby_order);
  hypre_BoomerAMGSetChebyEigRatio(amg_data, cheby_eig_ratio);
  hypre_BoomerAMGSetNumIterations(amg_data, num_iterations);
  (amg_data)->cum_num_iterations = cum_num_iterations;
  hypre_BoomerAMGSetPrintLevel(amg_data, print_level);
  hypre_BoomerAMGSetLogging(amg_data, logging);
  hypre_BoomerAMGSetPrintFileName(amg_data, log_file_name);
  hypre_BoomerAMGSetDebugFlag(amg_data, debug_flag);
  hypre_BoomerAMGSetRestriction(amg_data, 0);
  hypre_BoomerAMGSetGSMG(amg_data, 0);
  hypre_BoomerAMGSetNumSamples(amg_data, 0);
  (amg_data)->A_array = (void*)0;
  (amg_data)->P_array = (void*)0;
  (amg_data)->R_array = (void*)0;
  (amg_data)->CF_marker_array = (void*)0;
  (amg_data)->Vtemp = (void*)0;
  (amg_data)->Rtemp = (void*)0;
  (amg_data)->Ptemp = (void*)0;
  (amg_data)->Ztemp = (void*)0;
  (amg_data)->F_array = (void*)0;
  (amg_data)->U_array = (void*)0;
  (amg_data)->dof_func = (void*)0;
  (amg_data)->dof_func_array = (void*)0;
  (amg_data)->dof_point_array = (void*)0;
  (amg_data)->dof_point_array = (void*)0;
  (amg_data)->point_dof_map_array = (void*)0;
  (amg_data)->smoother = (void*)0;
  (amg_data)->smoother_prec = (void*)0;
  (amg_data)->block_mode = block_mode;
  (amg_data)->max_eig_est = (void*)0;
  (amg_data)->min_eig_est = (void*)0;
  (amg_data)->theta_est = (void*)0;
  return (void*)amg_data;
}
int hypre_BoomerAMGDestroy(void* data) {
  hypre_ParAMGData* amg_data = data;
  int num_levels = (amg_data)->num_levels;
  int i;
  HYPRE_Solver* smoother = (amg_data)->smoother;
  HYPRE_Solver* smoother_prec = (amg_data)->smoother_prec;
  if ((amg_data)->seq_data) {
    hypre_SeqAMGData* seq_data = (amg_data)->seq_data;
    int tot_levels = (seq_data)->num_levels;
    if ((seq_data)->participate) {
      for (i = num_levels - 1; i < tot_levels; i++) {
        hypre_SeqVectorDestroy((seq_data)->F_array[i]);
        hypre_SeqVectorDestroy((seq_data)->U_array[i]);
        hypre_CSRMatrixDestroy((seq_data)->A_array[i]);
      }
      for (i = num_levels - 1; i < (tot_levels - 1); i++) {
        hypre_CSRMatrixDestroy((seq_data)->P_array[i]);
      }
      for (i = num_levels - 1; i < (tot_levels - 1); i++) {
        hypre_Free((char*)((amg_data)->CF_marker_array[i])), (amg_data)->CF_marker_array[i] = (void*)0;
      }
      for (i = num_levels; i < tot_levels; i++)
        hypre_Free((char*)((amg_data)->dof_func_array[i])), (amg_data)->dof_func_array[i] = (void*)0;
      hypre_Free((char*)((seq_data)->F_array)), (seq_data)->F_array = (void*)0;
      hypre_Free((char*)((seq_data)->U_array)), (seq_data)->U_array = (void*)0;
      hypre_Free((char*)((seq_data)->A_array)), (seq_data)->A_array = (void*)0;
      hypre_Free((char*)((seq_data)->P_array)), (seq_data)->P_array = (void*)0;
      hypre_SeqVectorDestroy((seq_data)->Vtemp);
    }
    hypre_Free((char*)seq_data), seq_data = (void*)0;
  }
  if ((amg_data)->grid_relax_type) {
    int* grid_relax_type = (amg_data)->grid_relax_type;
    if (((grid_relax_type[1]) == 13) || ((grid_relax_type[3]) == 13)) {
      if ((grid_relax_type[1]) == 13) {
        for (i = 0; i < num_levels; i++) {
          HYPRE_ParCSRPCGDestroy(smoother[i]);
        }
      }
      else
        if ((grid_relax_type[3]) == 13) {
          HYPRE_ParCSRPCGDestroy(smoother[num_levels - 1]);
        }
      hypre_Free((char*)((amg_data)->smoother)), (amg_data)->smoother = (void*)0;
      (amg_data)->smoother = (void*)0;
    }
    else
      if (((grid_relax_type[1]) == 14) || ((grid_relax_type[3]) == 14)) {
        if ((grid_relax_type[1]) == 14) {
          for (i = 0; i < num_levels; i++) {
            HYPRE_ParCSRPCGDestroy(smoother[i]);
            HYPRE_BoomerAMGDestroy(smoother_prec[i]);
          }
        }
        else
          if ((grid_relax_type[3]) == 14) {
            HYPRE_ParCSRPCGDestroy(smoother[num_levels - 1]);
            HYPRE_BoomerAMGDestroy(smoother_prec[num_levels - 1]);
          }
        hypre_Free((char*)((amg_data)->smoother)), (amg_data)->smoother = (void*)0;
        (amg_data)->smoother = (void*)0;
        hypre_Free((char*)((amg_data)->smoother_prec)), (amg_data)->smoother_prec = (void*)0;
        (amg_data)->smoother_prec = (void*)0;
      }
  }
  if ((amg_data)->theta_est) {
    hypre_Free((char*)((amg_data)->theta_est)), (amg_data)->theta_est = (void*)0;
    (amg_data)->theta_est = (void*)0;
  }
  if ((amg_data)->max_eig_est) {
    hypre_Free((char*)((amg_data)->max_eig_est)), (amg_data)->max_eig_est = (void*)0;
    (amg_data)->max_eig_est = (void*)0;
  }
  if ((amg_data)->min_eig_est) {
    hypre_Free((char*)((amg_data)->min_eig_est)), (amg_data)->min_eig_est = (void*)0;
    (amg_data)->min_eig_est = (void*)0;
  }
  if ((amg_data)->num_grid_sweeps) {
    hypre_Free((char*)((amg_data)->num_grid_sweeps)), (amg_data)->num_grid_sweeps = (void*)0;
    (amg_data)->num_grid_sweeps = (void*)0;
  }
  if ((amg_data)->grid_relax_type) {
    hypre_Free((char*)((amg_data)->grid_relax_type)), (amg_data)->grid_relax_type = (void*)0;
    (amg_data)->grid_relax_type = (void*)0;
  }
  if ((amg_data)->relax_weight) {
    hypre_Free((char*)((amg_data)->relax_weight)), (amg_data)->relax_weight = (void*)0;
    (amg_data)->relax_weight = (void*)0;
  }
  if ((amg_data)->omega) {
    hypre_Free((char*)((amg_data)->omega)), (amg_data)->omega = (void*)0;
    (amg_data)->omega = (void*)0;
  }
  if ((amg_data)->dof_func) {
    hypre_Free((char*)((amg_data)->dof_func)), (amg_data)->dof_func = (void*)0;
    (amg_data)->dof_func = (void*)0;
  }
  if ((amg_data)->grid_relax_points) {
    for (i = 0; i < 4; i++)
      hypre_Free((char*)((amg_data)->grid_relax_points[i])), (amg_data)->grid_relax_points[i] = (void*)0;
    hypre_Free((char*)((amg_data)->grid_relax_points)), (amg_data)->grid_relax_points = (void*)0;
    (amg_data)->grid_relax_points = (void*)0;
  }
  for (i = 1; i < num_levels; i++) {
    hypre_ParVectorDestroy((amg_data)->F_array[i]);
    hypre_ParVectorDestroy((amg_data)->U_array[i]);
    if ((amg_data)->A_array[i])
      hypre_ParCSRMatrixDestroy((amg_data)->A_array[i]);
    if ((amg_data)->P_array[i - 1])
      hypre_ParCSRMatrixDestroy((amg_data)->P_array[i - 1]);
    hypre_Free((char*)((amg_data)->CF_marker_array[i - 1])), (amg_data)->CF_marker_array[i - 1] = (void*)0;
  }
  if (num_levels == 1) {
    hypre_Free((char*)((amg_data)->CF_marker_array[0])), (amg_data)->CF_marker_array[0] = (void*)0;
  }
  hypre_ParVectorDestroy((amg_data)->Vtemp);
  hypre_Free((char*)((amg_data)->F_array)), (amg_data)->F_array = (void*)0;
  hypre_Free((char*)((amg_data)->U_array)), (amg_data)->U_array = (void*)0;
  hypre_Free((char*)((amg_data)->A_array)), (amg_data)->A_array = (void*)0;
  hypre_Free((char*)((amg_data)->P_array)), (amg_data)->P_array = (void*)0;
  hypre_Free((char*)((amg_data)->CF_marker_array)), (amg_data)->CF_marker_array = (void*)0;
  if ((amg_data)->Rtemp)
    hypre_ParVectorDestroy((amg_data)->Rtemp);
  if ((amg_data)->Ptemp)
    hypre_ParVectorDestroy((amg_data)->Ptemp);
  if ((amg_data)->Ztemp)
    hypre_ParVectorDestroy((amg_data)->Ztemp);
  if ((amg_data)->dof_func_array) {
    for (i = 1; i < num_levels; i++)
      hypre_Free((char*)((amg_data)->dof_func_array[i])), (amg_data)->dof_func_array[i] = (void*)0;
    hypre_Free((char*)((amg_data)->dof_func_array)), (amg_data)->dof_func_array = (void*)0;
    (amg_data)->dof_func_array = (void*)0;
  }
  if ((amg_data)->restr_par) {
    hypre_Free((char*)((amg_data)->R_array)), (amg_data)->R_array = (void*)0;
    (amg_data)->R_array = (void*)0;
  }
  if ((amg_data)->dof_point_array) {
    for (i = 0; i < num_levels; i++)
      hypre_Free((char*)((amg_data)->dof_point_array[i])), (amg_data)->dof_point_array[i] = (void*)0;
    hypre_Free((char*)((amg_data)->dof_point_array)), (amg_data)->dof_point_array = (void*)0;
    (amg_data)->dof_point_array = (void*)0;
  }
  if ((amg_data)->point_dof_map_array) {
    for (i = 0; i < num_levels; i++)
      hypre_Free((char*)((amg_data)->point_dof_map_array[i])), (amg_data)->point_dof_map_array[i] = (void*)0;
    hypre_Free((char*)((amg_data)->point_dof_map_array)), (amg_data)->point_dof_map_array = (void*)0;
    (amg_data)->point_dof_map_array = (void*)0;
  }
  if ((amg_data)->residual) {
    hypre_ParVectorDestroy((amg_data)->residual);
    (amg_data)->residual = (void*)0;
  }
  hypre_Free((char*)amg_data), amg_data = (void*)0;
  return hypre__global_error;
}
int hypre_BoomerAMGSetRestriction(void* data, int restr_par) {
  hypre_ParAMGData* amg_data = data;
  if (!amg_data) {
    printf("Warning! BoomerAMG object empty!\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  (amg_data)->restr_par = restr_par;
  return hypre__global_error;
}
int hypre_BoomerAMGSetMaxLevels(void* data, int max_levels) {
  hypre_ParAMGData* amg_data = data;
  if (!amg_data) {
    printf("Warning! BoomerAMG object empty!\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  if (max_levels < 1) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (2 << 3));
    return hypre__global_error;
  }
  (amg_data)->max_levels = max_levels;
  return hypre__global_error;
}
int hypre_BoomerAMGSetStrongThreshold(void* data, double strong_threshold) {
  hypre_ParAMGData* amg_data = data;
  if (!amg_data) {
    printf("Warning! BoomerAMG object empty!\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  if ((strong_threshold < 0) || (strong_threshold > 1)) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (2 << 3));
    return hypre__global_error;
  }
  (amg_data)->strong_threshold = strong_threshold;
  return hypre__global_error;
}
int hypre_BoomerAMGSetMaxRowSum(void* data, double max_row_sum) {
  hypre_ParAMGData* amg_data = data;
  if (!amg_data) {
    printf("Warning! BoomerAMG object empty!\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  if ((max_row_sum <= 0) || (max_row_sum > 1)) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (2 << 3));
    return hypre__global_error;
  }
  (amg_data)->max_row_sum = max_row_sum;
  return hypre__global_error;
}
int hypre_BoomerAMGSetTruncFactor(void* data, double trunc_factor) {
  hypre_ParAMGData* amg_data = data;
  if (!amg_data) {
    printf("Warning! BoomerAMG object empty!\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  if ((trunc_factor < 0) || (trunc_factor >= 1)) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (2 << 3));
    return hypre__global_error;
  }
  (amg_data)->trunc_factor = trunc_factor;
  return hypre__global_error;
}
int hypre_BoomerAMGSetAggTruncFactor(void* data, double agg_trunc_factor) {
  hypre_ParAMGData* amg_data = data;
  if (!amg_data) {
    printf("Warning! BoomerAMG object empty!\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  if ((agg_trunc_factor < 0) || (agg_trunc_factor >= 1)) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (2 << 3));
    return hypre__global_error;
  }
  (amg_data)->agg_trunc_factor = agg_trunc_factor;
  return hypre__global_error;
}
int hypre_BoomerAMGSetPMaxElmts(void* data, int P_max_elmts) {
  hypre_ParAMGData* amg_data = data;
  if (!amg_data) {
    printf("Warning! BoomerAMG object empty!\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  if (P_max_elmts < 0) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (2 << 3));
    return hypre__global_error;
  }
  (amg_data)->P_max_elmts = P_max_elmts;
  return hypre__global_error;
}
int hypre_BoomerAMGSetPMax1(void* data, int P_max1) {
  hypre_ParAMGData* amg_data = data;
  if (!amg_data) {
    printf("Warning! BoomerAMG object empty!\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  if (P_max1 < 0) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (2 << 3));
    return hypre__global_error;
  }
  (amg_data)->P_max1 = P_max1;
  return hypre__global_error;
}
int hypre_BoomerAMGSetPMax2(void* data, int P_max2) {
  hypre_ParAMGData* amg_data = data;
  if (!amg_data) {
    printf("Warning! BoomerAMG object empty!\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (2 << 3));
    return hypre__global_error;
  }
  if (P_max2 < 0) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (2 << 3));
    return hypre__global_error;
  }
  (amg_data)->P_max2 = P_max2;
  return hypre__global_error;
}
int hypre_BoomerAMGSetAggPMaxElmts(void* data, int agg_P_max_elmts) {
  hypre_ParAMGData* amg_data = data;
  if (!amg_data) {
    printf("Warning! BoomerAMG object empty!\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  if (agg_P_max_elmts < 0) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (2 << 3));
    return hypre__global_error;
  }
  (amg_data)->agg_P_max_elmts = agg_P_max_elmts;
  return hypre__global_error;
}
int hypre_BoomerAMGSetJacobiTruncThreshold(void* data, double jacobi_trunc_threshold) {
  hypre_ParAMGData* amg_data = data;
  if (!amg_data) {
    printf("Warning! BoomerAMG object empty!\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  if ((jacobi_trunc_threshold < 0) || (jacobi_trunc_threshold >= 1)) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (2 << 3));
    return hypre__global_error;
  }
  (amg_data)->jacobi_trunc_threshold = jacobi_trunc_threshold;
  return hypre__global_error;
}
int hypre_BoomerAMGSetPostInterpType(void* data, int post_interp_type) {
  hypre_ParAMGData* amg_data = data;
  if (!amg_data) {
    printf("Warning! BoomerAMG object empty!\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  if (post_interp_type < 0) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (2 << 3));
    return hypre__global_error;
  }
  (amg_data)->post_interp_type = post_interp_type;
  return hypre__global_error;
}
int hypre_BoomerAMGSetSCommPkgSwitch(void* data, double S_commpkg_switch) {
  hypre_ParAMGData* amg_data = data;
  if (!amg_data) {
    printf("Warning! BoomerAMG object empty!\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  (amg_data)->S_commpkg_switch = S_commpkg_switch;
  return hypre__global_error;
}
int hypre_BoomerAMGSetInterpType(void* data, int interp_type) {
  hypre_ParAMGData* amg_data = data;
  if (!amg_data) {
    printf("Warning! BoomerAMG object empty!\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  if ((interp_type < 0) || (interp_type > 35)) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (2 << 3));
    return hypre__global_error;
  }
  (amg_data)->interp_type = interp_type;
  return hypre__global_error;
}
int hypre_BoomerAMGSetAggInterpType(void* data, int agg_interp_type) {
  hypre_ParAMGData* amg_data = data;
  if (!amg_data) {
    printf("Warning! BoomerAMG object empty!\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  if ((agg_interp_type < 0) || (agg_interp_type > 35)) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (2 << 3));
    return hypre__global_error;
  }
  (amg_data)->agg_interp_type = agg_interp_type;
  return hypre__global_error;
}
int hypre_BoomerAMGSetMinIter(void* data, int min_iter) {
  hypre_ParAMGData* amg_data = data;
  if (!amg_data) {
    printf("Warning! BoomerAMG object empty!\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  (amg_data)->min_iter = min_iter;
  return hypre__global_error;
}
int hypre_BoomerAMGSetMaxIter(void* data, int max_iter) {
  hypre_ParAMGData* amg_data = data;
  if (!amg_data) {
    printf("Warning! BoomerAMG object empty!\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  if (max_iter < 0) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (2 << 3));
    return hypre__global_error;
  }
  (amg_data)->max_iter = max_iter;
  return hypre__global_error;
}
int hypre_BoomerAMGSetCoarsenType(void* data, int coarsen_type) {
  hypre_ParAMGData* amg_data = data;
  if (!amg_data) {
    printf("Warning! BoomerAMG object empty!\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  (amg_data)->coarsen_type = coarsen_type;
  return hypre__global_error;
}
int hypre_BoomerAMGSetMeasureType(void* data, int measure_type) {
  hypre_ParAMGData* amg_data = data;
  if (!amg_data) {
    printf("Warning! BoomerAMG object empty!\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  (amg_data)->measure_type = measure_type;
  return hypre__global_error;
}
int hypre_BoomerAMGSetSetupType(void* data, int setup_type) {
  hypre_ParAMGData* amg_data = data;
  if (!amg_data) {
    printf("Warning! BoomerAMG object empty!\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  (amg_data)->setup_type = setup_type;
  return hypre__global_error;
}
int hypre_BoomerAMGSetCycleType(void* data, int cycle_type) {
  hypre_ParAMGData* amg_data = data;
  if (!amg_data) {
    printf("Warning! BoomerAMG object empty!\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  if ((cycle_type < 0) || (cycle_type > 2)) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (2 << 3));
    return hypre__global_error;
  }
  (amg_data)->cycle_type = cycle_type;
  return hypre__global_error;
}
int hypre_BoomerAMGSetTol(void* data, double tol) {
  hypre_ParAMGData* amg_data = data;
  if (!amg_data) {
    printf("Warning! BoomerAMG object empty!\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  if ((tol < 0) || (tol > 1)) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (2 << 3));
    return hypre__global_error;
  }
  (amg_data)->tol = tol;
  return hypre__global_error;
}
int hypre_BoomerAMGSetNumSweeps(void* data, int num_sweeps) {
  int i;
  int* num_grid_sweeps;
  hypre_ParAMGData* amg_data = data;
  if (!amg_data) {
    printf("Warning! BoomerAMG object empty!\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  if (num_sweeps < 1) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (2 << 3));
    return hypre__global_error;
  }
  if ((amg_data)->num_grid_sweeps == (void*)0)
    (amg_data)->num_grid_sweeps = (int*)(hypre_CAlloc((unsigned)4, (unsigned)(sizeof(int))));
  num_grid_sweeps = (amg_data)->num_grid_sweeps;
  for (i = 0; i < 3; i++)
    num_grid_sweeps[i] = num_sweeps;
  num_grid_sweeps[3] = 1;
  return hypre__global_error;
}
int hypre_BoomerAMGSetCycleNumSweeps(void* data, int num_sweeps, int k) {
  int i;
  int* num_grid_sweeps;
  hypre_ParAMGData* amg_data = data;
  if (!amg_data) {
    printf("Warning! BoomerAMG object empty!\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  if (num_sweeps < 1) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (2 << 3));
    return hypre__global_error;
  }
  if ((k < 1) || (k > 3)) {
    printf(" Warning! Invalid cycle! num_sweeps not set!\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (3 << 3));
    return hypre__global_error;
  }
  if ((amg_data)->num_grid_sweeps == (void*)0) {
    num_grid_sweeps = (int*)(hypre_CAlloc((unsigned)4, (unsigned)(sizeof(int))));
    for (i = 0; i < 4; i++)
      num_grid_sweeps[i] = 1;
    (amg_data)->num_grid_sweeps = num_grid_sweeps;
  }
  (amg_data)->num_grid_sweeps[k] = num_sweeps;
  return hypre__global_error;
}
int hypre_BoomerAMGSetNumGridSweeps(void* data, int* num_grid_sweeps) {
  hypre_ParAMGData* amg_data = data;
  if (!amg_data) {
    printf("Warning! BoomerAMG object empty!\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  if (!num_grid_sweeps) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (2 << 3));
    return hypre__global_error;
  }
  if ((amg_data)->num_grid_sweeps)
    hypre_Free((char*)((amg_data)->num_grid_sweeps)), (amg_data)->num_grid_sweeps = (void*)0;
  (amg_data)->num_grid_sweeps = num_grid_sweeps;
  return hypre__global_error;
}
int hypre_BoomerAMGSetRelaxType(void* data, int relax_type) {
  int i;
  int* grid_relax_type;
  hypre_ParAMGData* amg_data = data;
  if (!amg_data) {
    printf("Warning! BoomerAMG object empty!\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  if (relax_type < 0) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (2 << 3));
    return hypre__global_error;
  }
  if ((amg_data)->grid_relax_type == (void*)0)
    (amg_data)->grid_relax_type = (int*)(hypre_CAlloc((unsigned)4, (unsigned)(sizeof(int))));
  grid_relax_type = (amg_data)->grid_relax_type;
  for (i = 0; i < 3; i++)
    grid_relax_type[i] = relax_type;
  grid_relax_type[3] = 9;
  (amg_data)->user_coarse_relax_type = 9;
  return hypre__global_error;
}
int hypre_BoomerAMGSetCycleRelaxType(void* data, int relax_type, int k) {
  int i;
  int* grid_relax_type;
  hypre_ParAMGData* amg_data = data;
  if (!amg_data) {
    printf("Warning! BoomerAMG object empty!\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  if ((k < 1) || (k > 3)) {
    printf(" Warning! Invalid cycle! relax_type not set!\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (3 << 3));
    return hypre__global_error;
  }
  if (relax_type < 0) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (2 << 3));
    return hypre__global_error;
  }
  if ((amg_data)->grid_relax_type == (void*)0) {
    grid_relax_type = (int*)(hypre_CAlloc((unsigned)4, (unsigned)(sizeof(int))));
    for (i = 0; i < 3; i++)
      grid_relax_type[i] = 3;
    grid_relax_type[3] = 9;
    (amg_data)->grid_relax_type = grid_relax_type;
  }
  (amg_data)->grid_relax_type[k] = relax_type;
  if (k == 3)
    (amg_data)->user_coarse_relax_type = relax_type;
  return hypre__global_error;
}
int hypre_BoomerAMGSetRelaxOrder(void* data, int relax_order) {
  hypre_ParAMGData* amg_data = data;
  if (!amg_data) {
    printf("Warning! BoomerAMG object empty!\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  (amg_data)->relax_order = relax_order;
  return hypre__global_error;
}
int hypre_BoomerAMGSetGridRelaxType(void* data, int* grid_relax_type) {
  hypre_ParAMGData* amg_data = data;
  if (!amg_data) {
    printf("Warning! BoomerAMG object empty!\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  if (!grid_relax_type) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (2 << 3));
    return hypre__global_error;
  }
  if ((amg_data)->grid_relax_type)
    hypre_Free((char*)((amg_data)->grid_relax_type)), (amg_data)->grid_relax_type = (void*)0;
  (amg_data)->grid_relax_type = grid_relax_type;
  (amg_data)->user_coarse_relax_type = grid_relax_type[3];
  return hypre__global_error;
}
int hypre_BoomerAMGSetGridRelaxPoints(void* data, int** grid_relax_points) {
  int i;
  hypre_ParAMGData* amg_data = data;
  if (!amg_data) {
    printf("Warning! BoomerAMG object empty!\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  if (!grid_relax_points) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (2 << 3));
    return hypre__global_error;
  }
  if ((amg_data)->grid_relax_points) {
    for (i = 0; i < 4; i++)
      hypre_Free((char*)((amg_data)->grid_relax_points[i])), (amg_data)->grid_relax_points[i] = (void*)0;
    hypre_Free((char*)((amg_data)->grid_relax_points)), (amg_data)->grid_relax_points = (void*)0;
  }
  (amg_data)->grid_relax_points = grid_relax_points;
  return hypre__global_error;
}
int hypre_BoomerAMGSetRelaxWeight(void* data, double* relax_weight) {
  hypre_ParAMGData* amg_data = data;
  if (!amg_data) {
    printf("Warning! BoomerAMG object empty!\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  if (!relax_weight) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (2 << 3));
    return hypre__global_error;
  }
  if ((amg_data)->relax_weight)
    hypre_Free((char*)((amg_data)->relax_weight)), (amg_data)->relax_weight = (void*)0;
  (amg_data)->relax_weight = relax_weight;
  return hypre__global_error;
}
int hypre_BoomerAMGSetRelaxWt(void* data, double relax_weight) {
  int i;
  int num_levels;
  double* relax_weight_array;
  hypre_ParAMGData* amg_data = data;
  if (!amg_data) {
    printf("Warning! BoomerAMG object empty!\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  num_levels = (amg_data)->max_levels;
  if ((amg_data)->relax_weight == (void*)0)
    (amg_data)->relax_weight = (double*)(hypre_CAlloc((unsigned)num_levels, (unsigned)(sizeof(double))));
  relax_weight_array = (amg_data)->relax_weight;
  for (i = 0; i < num_levels; i++)
    relax_weight_array[i] = relax_weight;
  return hypre__global_error;
}
int hypre_BoomerAMGSetOuterWt(void* data, double omega) {
  int i;
  int num_levels;
  double* omega_array;
  hypre_ParAMGData* amg_data = data;
  if (!amg_data) {
    printf("Warning! BoomerAMG object empty!\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  num_levels = (amg_data)->max_levels;
  if ((amg_data)->omega == (void*)0)
    (amg_data)->omega = (double*)(hypre_CAlloc((unsigned)num_levels, (unsigned)(sizeof(double))));
  omega_array = (amg_data)->omega;
  for (i = 0; i < num_levels; i++)
    omega_array[i] = omega;
  return hypre__global_error;
}
int hypre_BoomerAMGSetSmoothType(void* data, int smooth_type) {
  hypre_ParAMGData* amg_data = data;
  if (!amg_data) {
    printf("Warning! BoomerAMG object empty!\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  (amg_data)->smooth_type = smooth_type;
  return hypre__global_error;
}
int hypre_BoomerAMGSetSmoothNumLevels(void* data, int smooth_num_levels) {
  hypre_ParAMGData* amg_data = data;
  if (!amg_data) {
    printf("Warning! BoomerAMG object empty!\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  if (smooth_num_levels < 0) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (2 << 3));
    return hypre__global_error;
  }
  (amg_data)->smooth_num_levels = smooth_num_levels;
  return hypre__global_error;
}
int hypre_BoomerAMGSetSmoothNumSweeps(void* data, int smooth_num_sweeps) {
  hypre_ParAMGData* amg_data = data;
  if (!amg_data) {
    printf("Warning! BoomerAMG object empty!\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  if (smooth_num_sweeps < 0) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (2 << 3));
    return hypre__global_error;
  }
  (amg_data)->smooth_num_sweeps = smooth_num_sweeps;
  return hypre__global_error;
}
int hypre_BoomerAMGSetLogging(void* data, int logging) {
  hypre_ParAMGData* amg_data = data;
  if (!amg_data) {
    printf("Warning! BoomerAMG object empty!\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  (amg_data)->logging = logging;
  return hypre__global_error;
}
int hypre_BoomerAMGSetPrintLevel(void* data, int print_level) {
  hypre_ParAMGData* amg_data = data;
  if (!amg_data) {
    printf("Warning! BoomerAMG object empty!\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  (amg_data)->print_level = print_level;
  return hypre__global_error;
}
int hypre_BoomerAMGSetPrintFileName(void* data, char* print_file_name) {
  hypre_ParAMGData* amg_data = data;
  if (!amg_data) {
    printf("Warning! BoomerAMG object empty!\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  if (strlen(print_file_name) > 256) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (2 << 3));
    return hypre__global_error;
  }
  sprintf((amg_data)->log_file_name, "%s", print_file_name);
  return hypre__global_error;
}
int hypre_BoomerAMGSetNumIterations(void* data, int num_iterations) {
  hypre_ParAMGData* amg_data = data;
  if (!amg_data) {
    printf("Warning! BoomerAMG object empty!\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  (amg_data)->num_iterations = num_iterations;
  return hypre__global_error;
}
int hypre_BoomerAMGSetDebugFlag(void* data, int debug_flag) {
  hypre_ParAMGData* amg_data = data;
  if (!amg_data) {
    printf("Warning! BoomerAMG object empty!\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  (amg_data)->debug_flag = debug_flag;
  return hypre__global_error;
}
int hypre_BoomerAMGSetGSMG(void* data, int par) {
  hypre_ParAMGData* amg_data = data;
  if (!amg_data) {
    printf("Warning! BoomerAMG object empty!\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  (amg_data)->gsmg = par;
  return hypre__global_error;
}
int hypre_BoomerAMGSetNumSamples(void* data, int par) {
  hypre_ParAMGData* amg_data = data;
  if (!amg_data) {
    printf("Warning! BoomerAMG object empty!\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  (amg_data)->num_samples = par;
  return hypre__global_error;
}
int hypre_BoomerAMGSetNumFunctions(void* data, int num_functions) {
  hypre_ParAMGData* amg_data = data;
  if (!amg_data) {
    printf("Warning! BoomerAMG object empty!\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  if (num_functions < 1) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (2 << 3));
    return hypre__global_error;
  }
  (amg_data)->num_functions = num_functions;
  return hypre__global_error;
}
int hypre_BoomerAMGSetNodal(void* data, int nodal) {
  hypre_ParAMGData* amg_data = data;
  if (!amg_data) {
    printf("Warning! BoomerAMG object empty!\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  (amg_data)->nodal = nodal;
  return hypre__global_error;
}
int hypre_BoomerAMGSetNumPaths(void* data, int num_paths) {
  hypre_ParAMGData* amg_data = data;
  if (!amg_data) {
    printf("Warning! BoomerAMG object empty!\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  if (num_paths < 1) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (2 << 3));
    return hypre__global_error;
  }
  (amg_data)->num_paths = num_paths;
  return hypre__global_error;
}
int hypre_BoomerAMGSetAggNumLevels(void* data, int agg_num_levels) {
  hypre_ParAMGData* amg_data = data;
  if (!amg_data) {
    printf("Warning! BoomerAMG object empty!\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  if (agg_num_levels < 0) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (2 << 3));
    return hypre__global_error;
  }
  (amg_data)->agg_num_levels = agg_num_levels;
  return hypre__global_error;
}
int hypre_BoomerAMGSetNumCRRelaxSteps(void* data, int num_CR_relax_steps) {
  hypre_ParAMGData* amg_data = data;
  if (!amg_data) {
    printf("Warning! BoomerAMG object empty!\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  if (num_CR_relax_steps < 1) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (2 << 3));
    return hypre__global_error;
  }
  (amg_data)->num_CR_relax_steps = num_CR_relax_steps;
  return hypre__global_error;
}
int hypre_BoomerAMGSetCRRate(void* data, double CR_rate) {
  hypre_ParAMGData* amg_data = data;
  if (!amg_data) {
    printf("Warning! BoomerAMG object empty!\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  (amg_data)->CR_rate = CR_rate;
  return hypre__global_error;
}
int hypre_BoomerAMGSetISType(void* data, int IS_type) {
  hypre_ParAMGData* amg_data = data;
  if (!amg_data) {
    printf("Warning! BoomerAMG object empty!\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  if (IS_type < 0) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (2 << 3));
    return hypre__global_error;
  }
  (amg_data)->IS_type = IS_type;
  return hypre__global_error;
}
int hypre_BoomerAMGSetCRUseCG(void* data, int CR_use_CG) {
  hypre_ParAMGData* amg_data = data;
  if (!amg_data) {
    printf("Warning! BoomerAMG object empty!\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  (amg_data)->CR_use_CG = CR_use_CG;
  return hypre__global_error;
}
int hypre_BoomerAMGSetVariant(void* data, int variant) {
  hypre_ParAMGData* amg_data = data;
  if (!amg_data) {
    printf("Warning! BoomerAMG object empty!\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  if (variant < 0) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (2 << 3));
    return hypre__global_error;
  }
  (amg_data)->variant = variant;
  return hypre__global_error;
}
int hypre_BoomerAMGSetOverlap(void* data, int overlap) {
  hypre_ParAMGData* amg_data = data;
  if (!amg_data) {
    printf("Warning! BoomerAMG object empty!\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  if (overlap < 0) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (2 << 3));
    return hypre__global_error;
  }
  (amg_data)->overlap = overlap;
  return hypre__global_error;
}
int hypre_BoomerAMGSetChebyOrder(void* data, int order) {
  hypre_ParAMGData* amg_data = data;
  if (!amg_data) {
    printf("Warning! BoomerAMG object empty!\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  if (order < 1) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (2 << 3));
    return hypre__global_error;
  }
  (amg_data)->cheby_order = order;
  return hypre__global_error;
}
int hypre_BoomerAMGSetChebyEigRatio(void* data, double ratio) {
  hypre_ParAMGData* amg_data = data;
  if (!amg_data) {
    printf("Warning! BoomerAMG object empty!\n");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  if ((ratio <= 0.0) || (ratio > 1.0)) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg.c", 908, 4 | (2 << 3));
    return hypre__global_error;
  }
  (amg_data)->cheby_eig_ratio = ratio;
  return hypre__global_error;
}
//===================== par_amg_setup.c ====================
int hypre_BoomerAMGSetup(void* amg_vdata, hypre_ParCSRMatrix* A, hypre_ParVector* f, hypre_ParVector* u) {
  MPI_Comm comm = (A)->comm;
  hypre_ParAMGData* amg_data = amg_vdata;
  hypre_ParCSRMatrix** A_array;
  hypre_ParVector** F_array;
  hypre_ParVector** U_array;
  hypre_ParVector* Vtemp;
  hypre_ParVector* Rtemp;
  hypre_ParVector* Ptemp;
  hypre_ParVector* Ztemp;
  hypre_ParCSRMatrix** P_array;
  hypre_ParVector* Residual_array;
  int** CF_marker_array;
  int** dof_func_array;
  int* dof_func;
  int* dof_func1;
  int* col_offd_S_to_A;
  int* col_offd_SN_to_AN;
  double* relax_weight;
  double* omega;
  double strong_threshold;
  double max_row_sum;
  double trunc_factor;
  double jacobi_trunc_threshold;
  double agg_trunc_factor;
  double S_commpkg_switch;
  int max_levels;
  int amg_logging;
  int amg_print_level;
  int debug_flag;
  int local_num_vars;
  int P_max_elmts;
  int P_max1;
  int P_max2;
  int agg_P_max_elmts;
  int* CF_marker;
  int* CFN_marker;
  int* CF2_marker;
  hypre_ParCSRMatrix* S;
  hypre_ParCSRMatrix* S2;
  hypre_ParCSRMatrix* SN;
  hypre_ParCSRMatrix* P;
  hypre_ParCSRMatrix* P1;
  hypre_ParCSRMatrix* P2;
  hypre_ParCSRMatrix* PN;
  hypre_ParCSRMatrix* A_H;
  hypre_ParCSRMatrix* AN;
  double** l1_norms = (void*)0;
  int old_num_levels;
  int num_levels;
  int level;
  int local_size;
  int i;
  int first_local_row;
  int num_fun;
  int coarse_size;
  int coarsen_type;
  int measure_type;
  int setup_type;
  int fine_size;
  int rest;
  int tms;
  int indx;
  double size;
  int not_finished_coarsening = 1;
  int Setup_err_flag = 0;
  int seq_threshold = (amg_data)->seq_threshold;
  int coarse_threshold = (amg_data)->max_coarse_size;
  int j;
  int k;
  int num_procs;
  int my_id;
  int num_threads;
  int* grid_relax_type = (amg_data)->grid_relax_type;
  int num_functions = (amg_data)->num_functions;
  int nodal = (amg_data)->nodal;
  int num_paths = (amg_data)->num_paths;
  int agg_num_levels = (amg_data)->agg_num_levels;
  int* coarse_dof_func = (void*)0;
  int* coarse_pnts_global = (void*)0;
  int* coarse_pnts_global1 = (void*)0;
  int num_cg_sweeps;
  double* max_eig_est = (void*)0;
  double* min_eig_est = (void*)0;
  HYPRE_Solver* smoother = (void*)0;
  HYPRE_Solver* smoother_prec = (void*)0;
  int interp_type;
  int agg_interp_type;
  int post_interp_type;
  int block_mode = 0;
  double wall_time;
  MPI_Comm_size(comm, &(num_procs));
  MPI_Comm_rank(comm, &(my_id));
  num_threads = 1;
  old_num_levels = (amg_data)->num_levels;
  max_levels = (amg_data)->max_levels;
  amg_logging = (amg_data)->logging;
  amg_print_level = (amg_data)->print_level;
  coarsen_type = (amg_data)->coarsen_type;
  measure_type = (amg_data)->measure_type;
  setup_type = (amg_data)->setup_type;
  debug_flag = (amg_data)->debug_flag;
  relax_weight = (amg_data)->relax_weight;
  omega = (amg_data)->omega;
  dof_func = (amg_data)->dof_func;
  agg_interp_type = (amg_data)->agg_interp_type;
  interp_type = (amg_data)->interp_type;
  post_interp_type = (amg_data)->post_interp_type;
  hypre_ParCSRMatrixSetNumNonzeros(A);
  hypre_ParCSRMatrixSetDNumNonzeros(A);
  (amg_data)->num_variables = ((A)->diag)->num_rows;
  if (setup_type == 0)
    return Setup_err_flag;
  S = (void*)0;
  A_array = (amg_data)->A_array;
  P_array = (amg_data)->P_array;
  CF_marker_array = (amg_data)->CF_marker_array;
  dof_func_array = (amg_data)->dof_func_array;
  local_size = ((A)->diag)->num_rows;
  grid_relax_type[3] = (amg_data)->user_coarse_relax_type;
  (amg_data)->block_mode = block_mode;
  if (((A_array || P_array) || CF_marker_array) || dof_func_array) {
    for (j = 1; j < old_num_levels; j++) {
      if (A_array[j]) {
        hypre_ParCSRMatrixDestroy(A_array[j]);
        A_array[j] = (void*)0;
      }
      if (dof_func_array[j]) {
        hypre_Free((char*)(dof_func_array[j])), dof_func_array[j] = (void*)0;
        dof_func_array[j] = (void*)0;
      }
    }
    for (j = 0; j < (old_num_levels - 1); j++) {
      if (P_array[j]) {
        hypre_ParCSRMatrixDestroy(P_array[j]);
        P_array[j] = (void*)0;
      }
    }
    if (CF_marker_array[0]) {
      hypre_Free((char*)(CF_marker_array[0])), CF_marker_array[0] = (void*)0;
      CF_marker_array[0] = (void*)0;
    }
    for (j = 1; j < (old_num_levels - 1); j++) {
      if (CF_marker_array[j]) {
        hypre_Free((char*)(CF_marker_array[j])), CF_marker_array[j] = (void*)0;
        CF_marker_array[j] = (void*)0;
      }
    }
  }
  if (A_array == (void*)0)
    A_array = (hypre_ParCSRMatrix**)(hypre_CAlloc((unsigned)max_levels, (unsigned)(sizeof(hypre_ParCSRMatrix*))));
  if ((P_array == (void*)0) && (max_levels > 1))
    P_array = (hypre_ParCSRMatrix**)(hypre_CAlloc((unsigned)(max_levels - 1), (unsigned)(sizeof(hypre_ParCSRMatrix*))));
  if (CF_marker_array == (void*)0)
    CF_marker_array = (int**)(hypre_CAlloc((unsigned)max_levels, (unsigned)(sizeof(int*))));
  if (dof_func_array == (void*)0)
    dof_func_array = (int**)(hypre_CAlloc((unsigned)max_levels, (unsigned)(sizeof(int*))));
  if ((num_functions > 1) && (dof_func == (void*)0)) {
    first_local_row = (A)->first_row_index;
    dof_func = (int*)(hypre_CAlloc((unsigned)local_size, (unsigned)(sizeof(int))));
    num_fun = (int)num_functions;
    rest = (int)(first_local_row - ((first_local_row / num_fun) * num_fun));
    indx = num_functions - rest;
    if (rest == 0)
      indx = 0;
    k = num_functions - 1;
    for (j = indx - 1; j > (-1); j--)
      dof_func[j] = k--;
    tms = local_size / num_functions;
    if (((tms * num_functions) + indx) > local_size)
      tms--;
    for (j = 0; j < tms; j++) {
      for (k = 0; k < num_functions; k++)
        dof_func[indx++] = k;
    }
    k = 0;
    while (indx < local_size)
      dof_func[indx++] = k++;
    (amg_data)->dof_func = dof_func;
  }
  A_array[0] = A;
  dof_func_array[0] = dof_func;
  (amg_data)->CF_marker_array = CF_marker_array;
  (amg_data)->dof_func_array = dof_func_array;
  (amg_data)->A_array = A_array;
  (amg_data)->P_array = P_array;
  (amg_data)->R_array = P_array;
  Vtemp = (amg_data)->Vtemp;
  if (Vtemp != (void*)0) {
    hypre_ParVectorDestroy(Vtemp);
    Vtemp = (void*)0;
  }
  Vtemp = hypre_ParVectorCreate((A_array[0])->comm, (A_array[0])->global_num_rows, (A_array[0])->row_starts);
  hypre_ParVectorInitialize(Vtemp);
  hypre_ParVectorSetPartitioningOwner(Vtemp, 0);
  (amg_data)->Vtemp = Vtemp;
  if (((relax_weight[0]) < 0) || ((omega[0]) < 0)) {
    Ptemp = hypre_ParVectorCreate((A_array[0])->comm, (A_array[0])->global_num_rows, (A_array[0])->row_starts);
    hypre_ParVectorInitialize(Ptemp);
    hypre_ParVectorSetPartitioningOwner(Ptemp, 0);
    (amg_data)->Ptemp = Ptemp;
    Rtemp = hypre_ParVectorCreate((A_array[0])->comm, (A_array[0])->global_num_rows, (A_array[0])->row_starts);
    hypre_ParVectorInitialize(Rtemp);
    hypre_ParVectorSetPartitioningOwner(Rtemp, 0);
    (amg_data)->Rtemp = Rtemp;
  }
  if (((relax_weight[0]) < 0) || ((omega[0]) < 0)) {
    Ztemp = hypre_ParVectorCreate((A_array[0])->comm, (A_array[0])->global_num_rows, (A_array[0])->row_starts);
    hypre_ParVectorInitialize(Ztemp);
    hypre_ParVectorSetPartitioningOwner(Ztemp, 0);
    (amg_data)->Ztemp = Ztemp;
  }
  F_array = (amg_data)->F_array;
  U_array = (amg_data)->U_array;
  if ((F_array != (void*)0) || (U_array != (void*)0)) {
    for (j = 1; j < old_num_levels; j++) {
      if ((F_array[j]) != (void*)0) {
        hypre_ParVectorDestroy(F_array[j]);
        F_array[j] = (void*)0;
      }
      if ((U_array[j]) != (void*)0) {
        hypre_ParVectorDestroy(U_array[j]);
        U_array[j] = (void*)0;
      }
    }
  }
  if (F_array == (void*)0)
    F_array = (hypre_ParVector**)(hypre_CAlloc((unsigned)max_levels, (unsigned)(sizeof(hypre_ParVector*))));
  if (U_array == (void*)0)
    U_array = (hypre_ParVector**)(hypre_CAlloc((unsigned)max_levels, (unsigned)(sizeof(hypre_ParVector*))));
  F_array[0] = f;
  U_array[0] = u;
  (amg_data)->F_array = F_array;
  (amg_data)->U_array = U_array;
  not_finished_coarsening = 1;
  level = 0;
  strong_threshold = (amg_data)->strong_threshold;
  max_row_sum = (amg_data)->max_row_sum;
  trunc_factor = (amg_data)->trunc_factor;
  agg_trunc_factor = (amg_data)->agg_trunc_factor;
  P_max_elmts = (amg_data)->P_max_elmts;
  P_max1 = (amg_data)->P_max1;
  P_max2 = (amg_data)->P_max2;
  agg_P_max_elmts = (amg_data)->agg_P_max_elmts;
  jacobi_trunc_threshold = (amg_data)->jacobi_trunc_threshold;
  S_commpkg_switch = (amg_data)->S_commpkg_switch;
  while (not_finished_coarsening) {
    {
      fine_size = (A_array[level])->global_num_rows;
    }
    if (level > 0) {
      {
        F_array[level] = hypre_ParVectorCreate((A_array[level])->comm, (A_array[level])->global_num_rows, (A_array[level])->row_starts);
        hypre_ParVectorInitialize(F_array[level]);
        hypre_ParVectorSetPartitioningOwner(F_array[level], 0);
        U_array[level] = hypre_ParVectorCreate((A_array[level])->comm, (A_array[level])->global_num_rows, (A_array[level])->row_starts);
        hypre_ParVectorInitialize(U_array[level]);
        hypre_ParVectorSetPartitioningOwner(U_array[level], 0);
      }
    }
    if (debug_flag == 1)
      wall_time = time_getWallclockSeconds();
    if (debug_flag == 3) {
      printf("\n ===== Proc = %d     Level = %d  =====\n", my_id, level);
      fflush((void*)0);
    }
    if (max_levels > 1) {
      {
        local_num_vars = ((A_array[level])->diag)->num_rows;
      }
      if ((amg_data)->gsmg == 0) {
        if (nodal) {
          {
            hypre_BoomerAMGCreateNodalA(A_array[level], num_functions, dof_func_array[level], abs(nodal), &(AN));
          }
          if (((nodal == 3) || (nodal == (-3))) || (nodal == 7))
            hypre_BoomerAMGCreateS(AN, strong_threshold, max_row_sum, 1, (void*)0, &(SN));
          else
            hypre_BoomerAMGCreateSabs(AN, strong_threshold, max_row_sum, 1, (void*)0, &(SN));
          hypre_BoomerAMGCreateS(AN, strong_threshold, max_row_sum, 1, (void*)0, &(SN));
          col_offd_S_to_A = (void*)0;
          col_offd_SN_to_AN = (void*)0;
          if (strong_threshold > S_commpkg_switch)
            hypre_BoomerAMGCreateSCommPkg(AN, SN, &(col_offd_SN_to_AN));
        }
        else {
          hypre_BoomerAMGCreateS(A_array[level], strong_threshold, max_row_sum, num_functions, dof_func_array[level], &(S));
          col_offd_S_to_A = (void*)0;
          if (strong_threshold > S_commpkg_switch)
            hypre_BoomerAMGCreateSCommPkg(A_array[level], S, &(col_offd_S_to_A));
        }
      }
      if (coarsen_type == 6) {
        if (nodal == 0) {
          hypre_BoomerAMGCoarsenFalgout(S, A_array[level], measure_type, debug_flag, &(CF_marker));
          if ((level < agg_num_levels) && ((agg_interp_type < 30) || (agg_interp_type > 32))) {
            hypre_BoomerAMGCoarseParms(comm, local_num_vars, 1, dof_func_array[level], CF_marker, &(coarse_dof_func), &(coarse_pnts_global1));
            hypre_BoomerAMGCreate2ndS(S, CF_marker, num_paths, coarse_pnts_global1, &(S2));
            hypre_BoomerAMGCoarsenFalgout(S2, S2, measure_type, debug_flag, &(CFN_marker));
            hypre_ParCSRMatrixDestroy(S2);
            hypre_BoomerAMGCorrectCFMarker(CF_marker, local_num_vars, CFN_marker);
            hypre_Free((char*)coarse_pnts_global1), coarse_pnts_global1 = (void*)0;
            hypre_Free((char*)CFN_marker), CFN_marker = (void*)0;
          }
        }
        else
          if ((nodal < 0) || block_mode) {
            hypre_BoomerAMGCoarsenFalgout(SN, SN, measure_type, debug_flag, &(CF_marker));
          }
          else
            if (nodal > 0) {
              hypre_BoomerAMGCoarsenFalgout(SN, SN, measure_type, debug_flag, &(CFN_marker));
              if (level < agg_num_levels) {
                hypre_BoomerAMGCoarseParms(comm, local_num_vars, 1, dof_func_array[level], CFN_marker, &(coarse_dof_func), &(coarse_pnts_global1));
                hypre_BoomerAMGCreate2ndS(SN, CFN_marker, num_paths, coarse_pnts_global1, &(S2));
                hypre_BoomerAMGCoarsenFalgout(S2, S2, measure_type, debug_flag, &(CF2_marker));
                hypre_ParCSRMatrixDestroy(S2);
                hypre_BoomerAMGCorrectCFMarker(CFN_marker, local_num_vars, CF2_marker);
                hypre_Free((char*)coarse_pnts_global1), coarse_pnts_global1 = (void*)0;
                hypre_Free((char*)CF2_marker), CF2_marker = (void*)0;
              }
              col_offd_S_to_A = (void*)0;
              hypre_BoomerAMGCreateScalarCFS(SN, CFN_marker, col_offd_SN_to_AN, num_functions, nodal, 0, (void*)0, &(CF_marker), &(col_offd_S_to_A), &(S));
              if (col_offd_SN_to_AN == (void*)0)
                col_offd_S_to_A = (void*)0;
              hypre_Free((char*)CFN_marker), CFN_marker = (void*)0;
              hypre_Free((char*)col_offd_SN_to_AN), col_offd_SN_to_AN = (void*)0;
              hypre_ParCSRMatrixDestroy(AN);
              hypre_ParCSRMatrixDestroy(SN);
            }
      }
      else
        if (coarsen_type == 7) {
          if (nodal == 0) {
            hypre_BoomerAMGCoarsen(S, A_array[level], 2, debug_flag, &(CF_marker));
            if ((level < agg_num_levels) && ((agg_interp_type < 30) || (agg_interp_type > 32))) {
              hypre_BoomerAMGCoarseParms(comm, local_num_vars, 1, dof_func_array[level], CF_marker, &(coarse_dof_func), &(coarse_pnts_global1));
              hypre_BoomerAMGCreate2ndS(S, CF_marker, num_paths, coarse_pnts_global1, &(S2));
              hypre_BoomerAMGCoarsen(S2, S2, 2, debug_flag, &(CFN_marker));
              hypre_ParCSRMatrixDestroy(S2);
              hypre_BoomerAMGCorrectCFMarker(CF_marker, local_num_vars, CFN_marker);
              hypre_Free((char*)CFN_marker), CFN_marker = (void*)0;
              hypre_Free((char*)coarse_pnts_global1), coarse_pnts_global1 = (void*)0;
            }
          }
          else
            if ((nodal < 0) || block_mode) {
              hypre_BoomerAMGCoarsen(SN, SN, 2, debug_flag, &(CF_marker));
            }
            else
              if (nodal > 0) {
                hypre_BoomerAMGCoarsen(SN, SN, 2, debug_flag, &(CFN_marker));
                col_offd_S_to_A = (void*)0;
                hypre_BoomerAMGCreateScalarCFS(SN, CFN_marker, col_offd_SN_to_AN, num_functions, nodal, 0, (void*)0, &(CF_marker), &(col_offd_S_to_A), &(S));
                if (col_offd_SN_to_AN == (void*)0)
                  col_offd_S_to_A = (void*)0;
                hypre_Free((char*)CFN_marker), CFN_marker = (void*)0;
                hypre_Free((char*)col_offd_SN_to_AN), col_offd_SN_to_AN = (void*)0;
                hypre_ParCSRMatrixDestroy(AN);
                hypre_ParCSRMatrixDestroy(SN);
              }
        }
        else
          if (coarsen_type == 8) {
            if (nodal == 0) {
              hypre_BoomerAMGCoarsenPMIS(S, A_array[level], 0, debug_flag, &(CF_marker));
              if ((level < agg_num_levels) && ((agg_interp_type < 30) || (agg_interp_type > 32))) {
                hypre_BoomerAMGCoarseParms(comm, local_num_vars, 1, dof_func_array[level], CF_marker, &(coarse_dof_func), &(coarse_pnts_global1));
                hypre_BoomerAMGCreate2ndS(S, CF_marker, num_paths, coarse_pnts_global1, &(S2));
                hypre_BoomerAMGCoarsenPMIS(S2, S2, 0, debug_flag, &(CFN_marker));
                hypre_ParCSRMatrixDestroy(S2);
                hypre_BoomerAMGCorrectCFMarker(CF_marker, local_num_vars, CFN_marker);
                hypre_Free((char*)CFN_marker), CFN_marker = (void*)0;
                hypre_Free((char*)coarse_pnts_global1), coarse_pnts_global1 = (void*)0;
              }
            }
            else
              if ((nodal < 0) || block_mode) {
                hypre_BoomerAMGCoarsenPMIS(SN, SN, 0, debug_flag, &(CF_marker));
              }
              else
                if (nodal > 0) {
                  hypre_BoomerAMGCoarsenPMIS(SN, SN, 0, debug_flag, &(CFN_marker));
                  col_offd_S_to_A = (void*)0;
                  hypre_BoomerAMGCreateScalarCFS(SN, CFN_marker, col_offd_SN_to_AN, num_functions, nodal, 0, (void*)0, &(CF_marker), &(col_offd_S_to_A), &(S));
                  if (col_offd_SN_to_AN == (void*)0)
                    col_offd_S_to_A = (void*)0;
                  hypre_Free((char*)CFN_marker), CFN_marker = (void*)0;
                  hypre_Free((char*)col_offd_SN_to_AN), col_offd_SN_to_AN = (void*)0;
                  hypre_ParCSRMatrixDestroy(AN);
                  hypre_ParCSRMatrixDestroy(SN);
                }
          }
          else
            if (coarsen_type == 9) {
              if (nodal == 0) {
                hypre_BoomerAMGCoarsenPMIS(S, A_array[level], 2, debug_flag, &(CF_marker));
                if ((level < agg_num_levels) && ((agg_interp_type < 30) || (agg_interp_type > 32))) {
                  hypre_BoomerAMGCoarseParms(comm, local_num_vars, 1, dof_func_array[level], CF_marker, &(coarse_dof_func), &(coarse_pnts_global1));
                  hypre_BoomerAMGCreate2ndS(S, CF_marker, num_paths, coarse_pnts_global1, &(S2));
                  hypre_BoomerAMGCoarsenPMIS(S2, S2, 2, debug_flag, &(CFN_marker));
                  hypre_ParCSRMatrixDestroy(S2);
                  hypre_BoomerAMGCorrectCFMarker(CF_marker, local_num_vars, CFN_marker);
                  hypre_Free((char*)CFN_marker), CFN_marker = (void*)0;
                  hypre_Free((char*)coarse_pnts_global1), coarse_pnts_global1 = (void*)0;
                }
              }
              else
                if ((nodal < 0) || block_mode) {
                  hypre_BoomerAMGCoarsenPMIS(SN, SN, 2, debug_flag, &(CF_marker));
                }
                else
                  if (nodal > 0) {
                    hypre_BoomerAMGCoarsenPMIS(SN, SN, 2, debug_flag, &(CFN_marker));
                    col_offd_S_to_A = (void*)0;
                    hypre_BoomerAMGCreateScalarCFS(SN, CFN_marker, col_offd_SN_to_AN, num_functions, nodal, 0, (void*)0, &(CF_marker), &(col_offd_S_to_A), &(S));
                    if (col_offd_SN_to_AN == (void*)0)
                      col_offd_S_to_A = (void*)0;
                    hypre_Free((char*)CFN_marker), CFN_marker = (void*)0;
                    hypre_Free((char*)col_offd_SN_to_AN), col_offd_SN_to_AN = (void*)0;
                    hypre_ParCSRMatrixDestroy(AN);
                    hypre_ParCSRMatrixDestroy(SN);
                  }
            }
            else
              if (coarsen_type == 10) {
                if (nodal == 0) {
                  hypre_BoomerAMGCoarsenHMIS(S, A_array[level], measure_type, debug_flag, &(CF_marker));
                  if ((level < agg_num_levels) && ((agg_interp_type < 30) || (agg_interp_type > 32))) {
                    hypre_BoomerAMGCoarseParms(comm, local_num_vars, 1, dof_func_array[level], CF_marker, &(coarse_dof_func), &(coarse_pnts_global1));
                    hypre_BoomerAMGCreate2ndS(S, CF_marker, num_paths, coarse_pnts_global1, &(S2));
                    hypre_BoomerAMGCoarsenHMIS(S2, S2, measure_type, debug_flag, &(CFN_marker));
                    hypre_ParCSRMatrixDestroy(S2);
                    hypre_BoomerAMGCorrectCFMarker(CF_marker, local_num_vars, CFN_marker);
                    hypre_Free((char*)CFN_marker), CFN_marker = (void*)0;
                    hypre_Free((char*)coarse_pnts_global1), coarse_pnts_global1 = (void*)0;
                  }
                }
                else
                  if ((nodal < 0) || block_mode) {
                    hypre_BoomerAMGCoarsenHMIS(SN, SN, measure_type, debug_flag, &(CF_marker));
                  }
                  else
                    if (nodal > 0) {
                      hypre_BoomerAMGCoarsenHMIS(SN, SN, measure_type, debug_flag, &(CFN_marker));
                      if (level < agg_num_levels) {
                        hypre_BoomerAMGCoarseParms(comm, local_num_vars, 1, dof_func_array[level], CFN_marker, &(coarse_dof_func), &(coarse_pnts_global1));
                        hypre_BoomerAMGCreate2ndS(SN, CFN_marker, num_paths, coarse_pnts_global1, &(S2));
                        hypre_BoomerAMGCoarsenHMIS(S2, S2, measure_type, debug_flag, &(CF2_marker));
                        hypre_ParCSRMatrixDestroy(S2);
                        hypre_BoomerAMGCorrectCFMarker(CFN_marker, local_num_vars, CF2_marker);
                        hypre_Free((char*)CF2_marker), CF2_marker = (void*)0;
                        hypre_Free((char*)coarse_pnts_global1), coarse_pnts_global1 = (void*)0;
                      }
                      col_offd_S_to_A = (void*)0;
                      hypre_BoomerAMGCreateScalarCFS(SN, CFN_marker, col_offd_SN_to_AN, num_functions, nodal, 0, (void*)0, &(CF_marker), &(col_offd_S_to_A), &(S));
                      if (col_offd_SN_to_AN == (void*)0)
                        col_offd_S_to_A = (void*)0;
                      hypre_Free((char*)CFN_marker), CFN_marker = (void*)0;
                      hypre_Free((char*)col_offd_SN_to_AN), col_offd_SN_to_AN = (void*)0;
                      hypre_ParCSRMatrixDestroy(AN);
                      hypre_ParCSRMatrixDestroy(SN);
                    }
              }
              else
                if (coarsen_type) {
                  if (nodal == 0) {
                    hypre_BoomerAMGCoarsenRuge(S, A_array[level], measure_type, coarsen_type, debug_flag, &(CF_marker));
                    if ((level < agg_num_levels) && ((agg_interp_type < 30) || (agg_interp_type > 32))) {
                      hypre_BoomerAMGCoarseParms(comm, local_num_vars, 1, dof_func_array[level], CF_marker, &(coarse_dof_func), &(coarse_pnts_global1));
                      hypre_BoomerAMGCreate2ndS(S, CF_marker, num_paths, coarse_pnts_global1, &(S2));
                      hypre_BoomerAMGCoarsenRuge(S2, S2, measure_type, coarsen_type, debug_flag, &(CFN_marker));
                      hypre_ParCSRMatrixDestroy(S2);
                      hypre_BoomerAMGCorrectCFMarker(CF_marker, local_num_vars, CFN_marker);
                      hypre_Free((char*)CFN_marker), CFN_marker = (void*)0;
                      hypre_Free((char*)coarse_pnts_global1), coarse_pnts_global1 = (void*)0;
                    }
                  }
                  else
                    if ((nodal < 0) || block_mode) {
                      hypre_BoomerAMGCoarsenRuge(SN, SN, measure_type, coarsen_type, debug_flag, &(CF_marker));
                    }
                    else
                      if (nodal > 0) {
                        hypre_BoomerAMGCoarsenRuge(SN, SN, measure_type, coarsen_type, debug_flag, &(CFN_marker));
                        col_offd_S_to_A = (void*)0;
                        hypre_BoomerAMGCreateScalarCFS(SN, CFN_marker, col_offd_SN_to_AN, num_functions, nodal, 0, (void*)0, &(CF_marker), &(col_offd_S_to_A), &(S));
                        if (col_offd_SN_to_AN == (void*)0)
                          col_offd_S_to_A = (void*)0;
                        hypre_Free((char*)CFN_marker), CFN_marker = (void*)0;
                        hypre_Free((char*)col_offd_SN_to_AN), col_offd_SN_to_AN = (void*)0;
                        hypre_ParCSRMatrixDestroy(AN);
                        hypre_ParCSRMatrixDestroy(SN);
                      }
                }
                else {
                  if (nodal == 0) {
                    hypre_BoomerAMGCoarsen(S, A_array[level], 0, debug_flag, &(CF_marker));
                    if ((level < agg_num_levels) && ((agg_interp_type < 30) || (agg_interp_type > 32))) {
                      hypre_BoomerAMGCoarseParms(comm, local_num_vars, 1, dof_func_array[level], CF_marker, &(coarse_dof_func), &(coarse_pnts_global1));
                      hypre_BoomerAMGCreate2ndS(S, CF_marker, num_paths, coarse_pnts_global1, &(S2));
                      hypre_BoomerAMGCoarsen(S2, S2, 0, debug_flag, &(CFN_marker));
                      hypre_ParCSRMatrixDestroy(S2);
                      hypre_BoomerAMGCorrectCFMarker(CF_marker, local_num_vars, CFN_marker);
                      hypre_Free((char*)CFN_marker), CFN_marker = (void*)0;
                      hypre_Free((char*)coarse_pnts_global1), coarse_pnts_global1 = (void*)0;
                    }
                  }
                  else
                    if ((nodal < 0) || block_mode) {
                      hypre_BoomerAMGCoarsen(SN, SN, 0, debug_flag, &(CF_marker));
                    }
                    else
                      if (nodal > 0) {
                        hypre_BoomerAMGCoarsen(SN, SN, 0, debug_flag, &(CFN_marker));
                        col_offd_S_to_A = (void*)0;
                        hypre_BoomerAMGCreateScalarCFS(SN, CFN_marker, col_offd_SN_to_AN, num_functions, nodal, 0, (void*)0, &(CF_marker), &(col_offd_S_to_A), &(S));
                        if (col_offd_SN_to_AN == (void*)0)
                          col_offd_S_to_A = (void*)0;
                        hypre_Free((char*)CFN_marker), CFN_marker = (void*)0;
                        hypre_Free((char*)col_offd_SN_to_AN), col_offd_SN_to_AN = (void*)0;
                        hypre_ParCSRMatrixDestroy(AN);
                        hypre_ParCSRMatrixDestroy(SN);
                      }
                }
      CF_marker_array[level] = CF_marker;
      if ((relax_weight[level]) == 0.0) {
        hypre_ParCSRMatrixScaledNorm(A_array[level], &(relax_weight[level]));
        if ((relax_weight[level]) != 0.0)
          relax_weight[level] = (4.0 / 3.0) / (relax_weight[level]);
        else
          printf(" Warning ! Matrix norm is zero !!!");
      }
      if ((relax_weight[level]) < 0) {
        num_cg_sweeps = (int)(-(relax_weight[level]));
        hypre_BoomerAMGCGRelaxWt(amg_data, level, num_cg_sweeps, &(relax_weight[level]));
      }
      if ((omega[level]) < 0) {
        num_cg_sweeps = (int)(-(omega[level]));
        hypre_BoomerAMGCGRelaxWt(amg_data, level, num_cg_sweeps, &(omega[level]));
      }
      if (debug_flag == 1) {
        wall_time = time_getWallclockSeconds() - wall_time;
        printf("Proc = %d    Level = %d    Coarsen Time = %f\n", my_id, level, wall_time);
        fflush((void*)0);
      }
      if ((nodal < 0) || block_mode) {
        hypre_BoomerAMGCoarseParms(comm, ((AN)->diag)->num_rows, 1, (void*)0, CF_marker, (void*)0, &(coarse_pnts_global));
      }
      else {
        hypre_BoomerAMGCoarseParms(comm, local_num_vars, num_functions, dof_func_array[level], CF_marker, &(coarse_dof_func), &(coarse_pnts_global));
      }
      dof_func_array[level + 1] = (void*)0;
      if (((num_functions > 1) && (nodal > (-1))) && (!block_mode))
        dof_func_array[level + 1] = coarse_dof_func;
      coarse_size = coarse_pnts_global[num_procs];
    }
    else {
      S = (void*)0;
      coarse_pnts_global = (void*)0;
      CF_marker = (int*)(hypre_CAlloc((unsigned)local_size, (unsigned)(sizeof(int))));
      for (i = 0; i < local_size; i++)
        CF_marker[i] = 1;
      CF_marker_array[level] = CF_marker;
      coarse_size = fine_size;
    }
    if ((coarse_size == 0) || (coarse_size == fine_size)) {
      int* num_grid_sweeps = (amg_data)->num_grid_sweeps;
      int** grid_relax_points = (amg_data)->grid_relax_points;
      if ((grid_relax_type[3]) == 9) {
        grid_relax_type[3] = grid_relax_type[0];
        num_grid_sweeps[3] = 1;
        if (grid_relax_points)
          grid_relax_points[3][0] = 0;
      }
      if (S)
        hypre_ParCSRMatrixDestroy(S);
      hypre_Free((char*)coarse_pnts_global), coarse_pnts_global = (void*)0;
      if (level > 0) {
        hypre_Free((char*)(CF_marker_array[level])), CF_marker_array[level] = (void*)0;
        hypre_ParVectorDestroy(F_array[level]);
        hypre_ParVectorDestroy(U_array[level]);
      }
      break;
    }
    if (debug_flag == 1)
      wall_time = time_getWallclockSeconds();
    if (((amg_data)->agg_interp_type == 30) && ((level < agg_num_levels) && (!block_mode))) {
      hypre_BoomerAMGBuildExtPIInterp(A_array[level], CF_marker_array[level], S, coarse_pnts_global, num_functions, dof_func_array[level], debug_flag, 0, P_max1, col_offd_S_to_A, &(P1));
      hypre_Free((char*)col_offd_S_to_A), col_offd_S_to_A = (void*)0;
      hypre_BoomerAMGCreate2ndS(S, CF_marker, num_paths, coarse_pnts_global, &(S2));
      if (coarsen_type == 10)
        hypre_BoomerAMGCoarsenHMIS(S2, S2, measure_type, debug_flag, &(CFN_marker));
      else
        if (coarsen_type == 8)
          hypre_BoomerAMGCoarsenPMIS(S2, S2, 3, debug_flag, &(CFN_marker));
        else
          if (coarsen_type == 9)
            hypre_BoomerAMGCoarsenHMIS(S2, S2, measure_type + 3, debug_flag, &(CFN_marker));
          else
            if (coarsen_type == 11)
              hypre_BoomerAMGCoarsenPMIS(S2, S2, 4, debug_flag, &(CFN_marker));
            else
              if (coarsen_type == 6)
                hypre_BoomerAMGCoarsenFalgout(S2, S2, measure_type, debug_flag, &(CFN_marker));
              else
                if (coarsen_type == 0)
                  hypre_BoomerAMGCoarsen(S2, S2, 0, debug_flag, &(CFN_marker));
      hypre_ParCSRMatrixDestroy(S2);
      hypre_BoomerAMGCorrectCFMarker2(CF_marker, local_num_vars, CFN_marker);
      hypre_Free((char*)CFN_marker), CFN_marker = (void*)0;
      hypre_Free((char*)coarse_dof_func), coarse_dof_func = (void*)0;
      coarse_dof_func = (void*)0;
      hypre_BoomerAMGCoarseParms(comm, local_num_vars, num_functions, dof_func_array[level], CF_marker, &(coarse_dof_func), &(coarse_pnts_global1));
      if (((num_functions > 1) && (nodal > (-1))) && (!block_mode))
        dof_func_array[level + 1] = coarse_dof_func;
      hypre_BoomerAMGBuildPartialExtPIInterp(A_array[level], CF_marker_array[level], S, coarse_pnts_global1, coarse_pnts_global, num_functions, dof_func_array[level], debug_flag, 0, P_max2, col_offd_S_to_A, &(P2));
      P = hypre_ParMatmul(P1, P2);
      hypre_BoomerAMGInterpTruncation(P, agg_trunc_factor, agg_P_max_elmts);
      hypre_ParCSRMatrixDestroy(P1);
      (P2)->owns_col_starts = 0;
      hypre_ParCSRMatrixDestroy(P2);
      (P)->owns_col_starts = 1;
      coarse_pnts_global = coarse_pnts_global1;
      hypre_MatvecCommPkgCreate(P);
      coarse_size = coarse_pnts_global[num_procs];
    }
    else
      if (((amg_data)->agg_interp_type == 31) && ((level < agg_num_levels) && (!block_mode))) {
        hypre_BoomerAMGBuildExtInterp(A_array[level], CF_marker_array[level], S, coarse_pnts_global, num_functions, dof_func_array[level], debug_flag, 0, P_max1, col_offd_S_to_A, &(P1));
        hypre_Free((char*)col_offd_S_to_A), col_offd_S_to_A = (void*)0;
        hypre_BoomerAMGCreate2ndS(S, CF_marker, num_paths, coarse_pnts_global, &(S2));
        if (coarsen_type == 10)
          hypre_BoomerAMGCoarsenHMIS(S2, S2, measure_type, debug_flag, &(CFN_marker));
        else
          if (coarsen_type == 8)
            hypre_BoomerAMGCoarsenPMIS(S2, S2, 3, debug_flag, &(CFN_marker));
          else
            if (coarsen_type == 9)
              hypre_BoomerAMGCoarsenHMIS(S2, S2, measure_type + 3, debug_flag, &(CFN_marker));
            else
              if (coarsen_type == 11)
                hypre_BoomerAMGCoarsenPMIS(S2, S2, 4, debug_flag, &(CFN_marker));
              else
                if (coarsen_type == 6)
                  hypre_BoomerAMGCoarsenFalgout(S2, S2, measure_type, debug_flag, &(CFN_marker));
                else
                  if (coarsen_type == 0)
                    hypre_BoomerAMGCoarsen(S2, S2, 0, debug_flag, &(CFN_marker));
        hypre_ParCSRMatrixDestroy(S2);
        hypre_BoomerAMGCorrectCFMarker2(CF_marker, local_num_vars, CFN_marker);
        hypre_Free((char*)CFN_marker), CFN_marker = (void*)0;
        hypre_Free((char*)coarse_dof_func), coarse_dof_func = (void*)0;
        coarse_dof_func = (void*)0;
        hypre_BoomerAMGCoarseParms(comm, local_num_vars, num_functions, dof_func_array[level], CF_marker, &(coarse_dof_func), &(coarse_pnts_global1));
        if (((num_functions > 1) && (nodal > (-1))) && (!block_mode))
          dof_func_array[level + 1] = coarse_dof_func;
        hypre_BoomerAMGBuildPartialExtInterp(A_array[level], CF_marker_array[level], S, coarse_pnts_global1, coarse_pnts_global, num_functions, dof_func_array[level], debug_flag, 0, P_max2, col_offd_S_to_A, &(P2));
        P = hypre_ParMatmul(P1, P2);
        hypre_BoomerAMGInterpTruncation(P, agg_trunc_factor, agg_P_max_elmts);
        hypre_ParCSRMatrixDestroy(P1);
        (P2)->owns_col_starts = 0;
        hypre_ParCSRMatrixDestroy(P2);
        (P)->owns_col_starts = 1;
        coarse_pnts_global = coarse_pnts_global1;
        hypre_MatvecCommPkgCreate(P);
        coarse_size = coarse_pnts_global[num_procs];
      }
      else
        if (((amg_data)->agg_interp_type == 32) && ((level < agg_num_levels) && (!block_mode))) {
          hypre_BoomerAMGBuildStdInterp(A_array[level], CF_marker_array[level], S, coarse_pnts_global, num_functions, dof_func_array[level], debug_flag, 0, P_max1, 0, col_offd_S_to_A, &(P1));
          hypre_Free((char*)col_offd_S_to_A), col_offd_S_to_A = (void*)0;
          hypre_BoomerAMGCreate2ndS(S, CF_marker, num_paths, coarse_pnts_global, &(S2));
          if (coarsen_type == 10)
            hypre_BoomerAMGCoarsenHMIS(S2, S2, measure_type, debug_flag, &(CFN_marker));
          else
            if (coarsen_type == 8)
              hypre_BoomerAMGCoarsenPMIS(S2, S2, 3, debug_flag, &(CFN_marker));
            else
              if (coarsen_type == 9)
                hypre_BoomerAMGCoarsenHMIS(S2, S2, measure_type + 3, debug_flag, &(CFN_marker));
              else
                if (coarsen_type == 11)
                  hypre_BoomerAMGCoarsenPMIS(S2, S2, 4, debug_flag, &(CFN_marker));
                else
                  if (coarsen_type == 6)
                    hypre_BoomerAMGCoarsenFalgout(S2, S2, measure_type, debug_flag, &(CFN_marker));
                  else
                    if (coarsen_type == 0)
                      hypre_BoomerAMGCoarsen(S2, S2, 0, debug_flag, &(CFN_marker));
          hypre_ParCSRMatrixDestroy(S2);
          hypre_BoomerAMGCorrectCFMarker2(CF_marker, local_num_vars, CFN_marker);
          hypre_Free((char*)CFN_marker), CFN_marker = (void*)0;
          hypre_Free((char*)coarse_dof_func), coarse_dof_func = (void*)0;
          coarse_dof_func = (void*)0;
          hypre_BoomerAMGCoarseParms(comm, local_num_vars, num_functions, dof_func_array[level], CF_marker, &(coarse_dof_func), &(coarse_pnts_global1));
          if (((num_functions > 1) && (nodal > (-1))) && (!block_mode))
            dof_func_array[level + 1] = coarse_dof_func;
          hypre_BoomerAMGBuildPartialStdInterp(A_array[level], CF_marker_array[level], S, coarse_pnts_global1, coarse_pnts_global, num_functions, dof_func_array[level], debug_flag, 0, P_max2, 0, col_offd_S_to_A, &(P2));
          P = hypre_ParMatmul(P1, P2);
          hypre_BoomerAMGInterpTruncation(P, agg_trunc_factor, agg_P_max_elmts);
          hypre_ParCSRMatrixDestroy(P1);
          (P2)->owns_col_starts = 0;
          hypre_ParCSRMatrixDestroy(P2);
          (P)->owns_col_starts = 1;
          coarse_pnts_global = coarse_pnts_global1;
          hypre_MatvecCommPkgCreate(P);
          coarse_size = coarse_pnts_global[num_procs];
        }
        else
          if ((((amg_data)->agg_interp_type == 4) && ((level < agg_num_levels) && (!block_mode))) || (((amg_data)->interp_type == 4) && (level >= agg_num_levels))) {
            if (nodal > (-1)) {
              hypre_BoomerAMGBuildMultipass(A_array[level], CF_marker_array[level], S, coarse_pnts_global, num_functions, dof_func_array[level], debug_flag, agg_trunc_factor, agg_P_max_elmts, 0, col_offd_S_to_A, &(P));
              hypre_Free((char*)col_offd_S_to_A), col_offd_S_to_A = (void*)0;
            }
            else {
              CFN_marker = CF_marker_array[level];
              hypre_BoomerAMGBuildMultipass(AN, CFN_marker, SN, coarse_pnts_global, 1, (void*)0, debug_flag, agg_trunc_factor, agg_P_max_elmts, 0, col_offd_SN_to_AN, &(PN));
              hypre_Free((char*)col_offd_SN_to_AN), col_offd_SN_to_AN = (void*)0;
              hypre_BoomerAMGCreateScalarCFS(PN, CFN_marker, (void*)0, num_functions, nodal, 1, &(dof_func1), &(CF_marker), (void*)0, &(P));
              dof_func_array[level + 1] = dof_func1;
              CF_marker_array[level] = CF_marker;
              hypre_Free((char*)CFN_marker), CFN_marker = (void*)0;
              hypre_ParCSRMatrixDestroy(AN);
              hypre_ParCSRMatrixDestroy(PN);
              hypre_ParCSRMatrixDestroy(SN);
            }
          }
          else
            if ((amg_data)->interp_type == 5) {
              if (nodal > (-1)) {
                hypre_BoomerAMGBuildMultipass(A_array[level], CF_marker_array[level], S, coarse_pnts_global, num_functions, dof_func_array[level], debug_flag, trunc_factor, P_max_elmts, 1, col_offd_S_to_A, &(P));
                hypre_Free((char*)col_offd_S_to_A), col_offd_S_to_A = (void*)0;
              }
              else {
                CFN_marker = CF_marker_array[level];
                hypre_BoomerAMGBuildMultipass(AN, CFN_marker, SN, coarse_pnts_global, 1, (void*)0, debug_flag, trunc_factor, P_max_elmts, 1, col_offd_SN_to_AN, &(PN));
                hypre_Free((char*)col_offd_SN_to_AN), col_offd_SN_to_AN = (void*)0;
                hypre_BoomerAMGCreateScalarCFS(PN, CFN_marker, (void*)0, num_functions, nodal, 1, &(dof_func1), &(CF_marker), (void*)0, &(P));
                dof_func_array[level + 1] = dof_func1;
                CF_marker_array[level] = CF_marker;
                hypre_Free((char*)CFN_marker), CFN_marker = (void*)0;
                hypre_ParCSRMatrixDestroy(AN);
                hypre_ParCSRMatrixDestroy(PN);
                hypre_ParCSRMatrixDestroy(SN);
              }
            }
            else
              if ((amg_data)->interp_type == 6) {
                hypre_BoomerAMGBuildExtPIInterp(A_array[level], CF_marker_array[level], S, coarse_pnts_global, num_functions, dof_func_array[level], debug_flag, trunc_factor, P_max_elmts, col_offd_S_to_A, &(P));
                hypre_Free((char*)col_offd_S_to_A), col_offd_S_to_A = (void*)0;
              }
              else
                if ((amg_data)->interp_type == 7) {
                  hypre_BoomerAMGBuildExtPICCInterp(A_array[level], CF_marker_array[level], S, coarse_pnts_global, num_functions, dof_func_array[level], debug_flag, trunc_factor, P_max_elmts, col_offd_S_to_A, &(P));
                  hypre_Free((char*)col_offd_S_to_A), col_offd_S_to_A = (void*)0;
                }
                else
                  if ((amg_data)->interp_type == 13) {
                    hypre_BoomerAMGBuildFF1Interp(A_array[level], CF_marker_array[level], S, coarse_pnts_global, num_functions, dof_func_array[level], debug_flag, trunc_factor, P_max_elmts, col_offd_S_to_A, &(P));
                    hypre_Free((char*)col_offd_S_to_A), col_offd_S_to_A = (void*)0;
                  }
                  else
                    if ((amg_data)->gsmg == 0) {
                      {
                        if (nodal > (-1)) {
                          hypre_BoomerAMGBuildInterp(A_array[level], CF_marker_array[level], S, coarse_pnts_global, num_functions, dof_func_array[level], debug_flag, trunc_factor, P_max_elmts, col_offd_S_to_A, &(P));
                          hypre_Free((char*)col_offd_S_to_A), col_offd_S_to_A = (void*)0;
                        }
                        else {
                          CFN_marker = CF_marker_array[level];
                          hypre_BoomerAMGBuildInterp(AN, CFN_marker, SN, coarse_pnts_global, 1, (void*)0, debug_flag, trunc_factor, P_max_elmts, col_offd_SN_to_AN, &(PN));
                          hypre_Free((char*)col_offd_SN_to_AN), col_offd_SN_to_AN = (void*)0;
                          hypre_BoomerAMGCreateScalarCFS(PN, CFN_marker, (void*)0, num_functions, nodal, 1, &(dof_func1), &(CF_marker), (void*)0, &(P));
                          dof_func_array[level + 1] = dof_func1;
                          CF_marker_array[level] = CF_marker;
                          hypre_Free((char*)CFN_marker), CFN_marker = (void*)0;
                          hypre_ParCSRMatrixDestroy(AN);
                          hypre_ParCSRMatrixDestroy(PN);
                          hypre_ParCSRMatrixDestroy(SN);
                        }
                      }
                    }
    for (i = 0; i < post_interp_type; i++)
      hypre_BoomerAMGJacobiInterp(A_array[level], &(P), S, num_functions, dof_func, CF_marker_array[level], level, jacobi_trunc_threshold, 0.5 * jacobi_trunc_threshold);
    if (debug_flag == 1) {
      wall_time = time_getWallclockSeconds() - wall_time;
      printf("Proc = %d    Level = %d    Build Interp Time = %f\n", my_id, level, wall_time);
      fflush((void*)0);
    }
    if (!block_mode) {
      P_array[level] = P;
    }
    if (S)
      hypre_ParCSRMatrixDestroy(S);
    S = (void*)0;
    if (debug_flag == 1)
      wall_time = time_getWallclockSeconds();
    hypre_BoomerAMGBuildCoarseOperator(P_array[level], A_array[level], P_array[level], &(A_H));
    if (debug_flag == 1) {
      wall_time = time_getWallclockSeconds() - wall_time;
      printf("Proc = %d    Level = %d    Build Coarse Operator Time = %f\n", my_id, level, wall_time);
      fflush((void*)0);
    }
    ++level;
    if (!block_mode) {
      hypre_ParCSRMatrixSetNumNonzeros(A_H);
      hypre_ParCSRMatrixSetDNumNonzeros(A_H);
      A_array[level] = A_H;
    }
    size = (double)fine_size * .75;
    if ((coarsen_type > 0) && (coarse_size >= (int)size)) {
      coarsen_type = 0;
    }
    {
      int thresh = coarse_threshold < seq_threshold ? seq_threshold : coarse_threshold;
      if ((level == (max_levels - 1)) || (coarse_size <= (int)thresh)) {
        not_finished_coarsening = 0;
      }
    }
  }
  if (((seq_threshold > coarse_threshold) && (coarse_size > coarse_threshold)) && (level != (max_levels - 1))) {
    hypre_seqAMGSetup(amg_data, level, coarse_threshold);
  }
  if (level > 0) {
    F_array[level] = hypre_ParVectorCreate((A_array[level])->comm, (A_array[level])->global_num_rows, (A_array[level])->row_starts);
    hypre_ParVectorInitialize(F_array[level]);
    hypre_ParVectorSetPartitioningOwner(F_array[level], 0);
    U_array[level] = hypre_ParVectorCreate((A_array[level])->comm, (A_array[level])->global_num_rows, (A_array[level])->row_starts);
    hypre_ParVectorInitialize(U_array[level]);
    hypre_ParVectorSetPartitioningOwner(U_array[level], 0);
  }
  num_levels = level + 1;
  (amg_data)->num_levels = num_levels;
  if ((((grid_relax_type[1]) == 8) || ((grid_relax_type[1]) == 19)) || ((grid_relax_type[1]) == 20)) {
    l1_norms = (double**)(hypre_CAlloc((unsigned)num_levels, (unsigned)(sizeof(double*))));
    (amg_data)->l1_norms = l1_norms;
    Ztemp = hypre_ParVectorCreate((A_array[0])->comm, (A_array[0])->global_num_rows, (A_array[0])->row_starts);
    hypre_ParVectorInitialize(Ztemp);
    hypre_ParVectorSetPartitioningOwner(Ztemp, 0);
    (amg_data)->Ztemp = Ztemp;
  }
  else
    if ((grid_relax_type[1]) == 18) {
      l1_norms = (double**)(hypre_CAlloc((unsigned)num_levels, (unsigned)(sizeof(double*))));
      (amg_data)->l1_norms = l1_norms;
    }
  if (((((grid_relax_type[1]) == 11) || ((grid_relax_type[1]) == 15)) || ((grid_relax_type[1]) == 16)) || ((grid_relax_type[1]) == 17)) {
    max_eig_est = (double*)(hypre_CAlloc((unsigned)num_levels, (unsigned)(sizeof(double))));
    min_eig_est = (double*)(hypre_CAlloc((unsigned)num_levels, (unsigned)(sizeof(double))));
    (amg_data)->max_eig_est = max_eig_est;
    (amg_data)->min_eig_est = min_eig_est;
    Ztemp = hypre_ParVectorCreate((A_array[0])->comm, (A_array[0])->global_num_rows, (A_array[0])->row_starts);
    hypre_ParVectorInitialize(Ztemp);
    hypre_ParVectorSetPartitioningOwner(Ztemp, 0);
    (amg_data)->Ztemp = Ztemp;
  }
  if (((((grid_relax_type[1]) == 13) || ((grid_relax_type[3]) == 13)) || ((grid_relax_type[1]) == 14)) || ((grid_relax_type[3]) == 14)) {
    smoother = (HYPRE_Solver*)(hypre_CAlloc((unsigned)num_levels, (unsigned)(sizeof(HYPRE_Solver))));
    (amg_data)->smoother = smoother;
    if (((grid_relax_type[1]) == 14) || ((grid_relax_type[3]) == 14)) {
      smoother_prec = (HYPRE_Solver*)(hypre_CAlloc((unsigned)num_levels, (unsigned)(sizeof(HYPRE_Solver))));
      (amg_data)->smoother_prec = smoother_prec;
    }
  }
  if (((grid_relax_type[1]) == 3) || ((grid_relax_type[1]) == 6)) {
    Ztemp = hypre_ParVectorCreate((A_array[0])->comm, (A_array[0])->global_num_rows, (A_array[0])->row_starts);
    hypre_ParVectorInitialize(Ztemp);
    hypre_ParVectorSetPartitioningOwner(Ztemp, 0);
    (amg_data)->Ztemp = Ztemp;
  }
  for (j = 0; j < num_levels; j++) {
    if (num_threads == 1) {
      if (((grid_relax_type[1]) == 8) && (j < (num_levels - 1))) {
        hypre_ParCSRComputeL1Norms(A_array[j], 4, (void*)0, &(l1_norms[j]));
      }
      else
        if (((grid_relax_type[3]) == 8) && (j == (num_levels - 1))) {
          hypre_ParCSRComputeL1Norms(A_array[j], 4, (void*)0, &(l1_norms[j]));
        }
      if (((grid_relax_type[1]) == 18) && (j < (num_levels - 1))) {
        if ((amg_data)->relax_order)
          hypre_ParCSRComputeL1Norms(A_array[j], 4, CF_marker_array[j], &(l1_norms[j]));
        else
          hypre_ParCSRComputeL1Norms(A_array[j], 1, (void*)0, &(l1_norms[j]));
      }
      else
        if (((grid_relax_type[3]) == 18) && (j == (num_levels - 1))) {
          hypre_ParCSRComputeL1Norms(A_array[j], 1, (void*)0, &(l1_norms[j]));
        }
    }
    else {
      if (((grid_relax_type[1]) == 8) && (j < (num_levels - 1))) {
        hypre_ParCSRComputeL1NormsThreads(A_array[j], 4, num_threads, (void*)0, &(l1_norms[j]));
      }
      else
        if (((grid_relax_type[3]) == 8) && (j == (num_levels - 1))) {
          hypre_ParCSRComputeL1NormsThreads(A_array[j], 4, num_threads, (void*)0, &(l1_norms[j]));
        }
      if (((grid_relax_type[1]) == 18) && (j < (num_levels - 1))) {
        if ((amg_data)->relax_order)
          hypre_ParCSRComputeL1NormsThreads(A_array[j], 4, num_threads, CF_marker_array[j], &(l1_norms[j]));
        else
          hypre_ParCSRComputeL1NormsThreads(A_array[j], 1, num_threads, (void*)0, &(l1_norms[j]));
      }
      else
        if (((grid_relax_type[3]) == 18) && (j == (num_levels - 1))) {
          hypre_ParCSRComputeL1NormsThreads(A_array[j], 1, num_threads, (void*)0, &(l1_norms[j]));
        }
    }
    if (((((grid_relax_type[1]) == 11) || ((grid_relax_type[1]) == 15)) || ((grid_relax_type[1]) == 16)) || ((grid_relax_type[1]) == 17)) {
      int scale = 0;
      double temp_d;
      double temp_d2;
      if (((grid_relax_type[1]) == 16) || ((grid_relax_type[1]) == 17))
        scale = 1;
      hypre_ParCSRMaxEigEstimateCG(A_array[j], scale, 10, &(temp_d), &(temp_d2));
      max_eig_est[j] = temp_d;
      min_eig_est[j] = temp_d2;
    }
    if (((grid_relax_type[1]) == 13) || (((grid_relax_type[3]) == 13) && (j == (num_levels - 1)))) {
      HYPRE_ParCSRPCGCreate(comm, &(smoother[j]));
      HYPRE_ParCSRPCGSetup(smoother[j], (HYPRE_ParCSRMatrix)(A_array[j]), (HYPRE_ParVector)(F_array[j]), (HYPRE_ParVector)(U_array[j]));
      HYPRE_PCGSetTol(smoother[j], 1e-9);
      HYPRE_PCGSetTwoNorm(smoother[j], 1);
      HYPRE_ParCSRPCGSetup(smoother[j], (HYPRE_ParCSRMatrix)(A_array[j]), (HYPRE_ParVector)(F_array[j]), (HYPRE_ParVector)(U_array[j]));
    }
    if (((grid_relax_type[1]) == 14) || (((grid_relax_type[3]) == 14) && (j == (num_levels - 1)))) {
      HYPRE_ParCSRPCGCreate(comm, &(smoother[j]));
      HYPRE_ParCSRPCGSetup(smoother[j], (HYPRE_ParCSRMatrix)(A_array[j]), (HYPRE_ParVector)(F_array[j]), (HYPRE_ParVector)(U_array[j]));
      HYPRE_PCGSetTol(smoother[j], 1e-9);
      HYPRE_PCGSetTwoNorm(smoother[j], 1);
      HYPRE_BoomerAMGCreate(&(smoother_prec[j]));
      HYPRE_BoomerAMGSetCoarsenType(smoother_prec[j], 10);
      HYPRE_BoomerAMGSetInterpType(smoother_prec[j], 6);
      HYPRE_BoomerAMGSetPMaxElmts(smoother_prec[j], 5);
      HYPRE_BoomerAMGSetRelaxType(smoother_prec[j], 8);
      HYPRE_BoomerAMGSetMaxIter(smoother_prec[j], 1);
      HYPRE_BoomerAMGSetup(smoother_prec[j], (HYPRE_ParCSRMatrix)(A_array[j]), (HYPRE_ParVector)(F_array[j]), (HYPRE_ParVector)(U_array[j]));
      HYPRE_PCGSetPrecond(smoother[j], (HYPRE_PtrToSolverFcn)HYPRE_BoomerAMGSolve, (HYPRE_PtrToSolverFcn)HYPRE_BoomerAMGSetup, smoother_prec[j]);
      HYPRE_ParCSRPCGSetup(smoother[j], (HYPRE_ParCSRMatrix)(A_array[j]), (HYPRE_ParVector)(F_array[j]), (HYPRE_ParVector)(U_array[j]));
    }
  }
  if (amg_logging > 1) {
    Residual_array = hypre_ParVectorCreate((A_array[0])->comm, (A_array[0])->global_num_rows, (A_array[0])->row_starts);
    hypre_ParVectorInitialize(Residual_array);
    hypre_ParVectorSetPartitioningOwner(Residual_array, 0);
    (amg_data)->residual = Residual_array;
  }
  else
    (amg_data)->residual = (void*)0;
  if ((amg_print_level == 1) || (amg_print_level == 3))
    hypre_BoomerAMGSetupStats(amg_data, A);
  return Setup_err_flag;
}
//===================== par_amg_solve.c ====================
int hypre_BoomerAMGSolve(void* amg_vdata, hypre_ParCSRMatrix* A, hypre_ParVector* f, hypre_ParVector* u) {
  MPI_Comm comm = (A)->comm;
  hypre_ParAMGData* amg_data = amg_vdata;
  int amg_print_level;
  int amg_logging;
  int cycle_count;
  int num_levels;
  double tol;
  hypre_ParCSRMatrix** A_array;
  hypre_ParVector** F_array;
  hypre_ParVector** U_array;
  int j;
  int Solve_err_flag;
  int min_iter;
  int max_iter;
  int num_procs;
  int my_id;
  double alpha = 1.0;
  double beta = -1.0;
  double cycle_op_count;
  double total_coeffs;
  double total_variables;
  double* num_coeffs;
  double* num_variables;
  double cycle_cmplxty;
  double operat_cmplxty;
  double grid_cmplxty;
  double conv_factor;
  double resid_nrm;
  double resid_nrm_init;
  double relative_resid;
  double rhs_norm;
  double old_resid;
  double ieee_check = 0.;
  hypre_ParVector* Vtemp;
  hypre_ParVector* Residual;
  MPI_Comm_size(comm, &(num_procs));
  MPI_Comm_rank(comm, &(my_id));
  amg_print_level = (amg_data)->print_level;
  amg_logging = (amg_data)->logging;
  if (amg_logging > 1)
    Residual = (amg_data)->residual;
  num_levels = (amg_data)->num_levels;
  A_array = (amg_data)->A_array;
  F_array = (amg_data)->F_array;
  U_array = (amg_data)->U_array;
  tol = (amg_data)->tol;
  min_iter = (amg_data)->min_iter;
  max_iter = (amg_data)->max_iter;
  num_coeffs = (double*)(hypre_CAlloc((unsigned)num_levels, (unsigned)(sizeof(double))));
  num_variables = (double*)(hypre_CAlloc((unsigned)num_levels, (unsigned)(sizeof(double))));
  num_coeffs[0] = (A)->d_num_nonzeros;
  num_variables[0] = (A)->global_num_rows;
  A_array[0] = A;
  F_array[0] = f;
  U_array[0] = u;
  Vtemp = (amg_data)->Vtemp;
  for (j = 1; j < num_levels; j++) {
    num_coeffs[j] = (double)((A_array[j])->num_nonzeros);
    num_variables[j] = (double)((A_array[j])->global_num_rows);
  }
  if ((my_id == 0) && (amg_print_level > 1))
    hypre_BoomerAMGWriteSolverParams(amg_data);
  Solve_err_flag = 0;
  total_coeffs = 0;
  total_variables = 0;
  cycle_count = 0;
  operat_cmplxty = 0;
  grid_cmplxty = 0;
  if (((my_id == 0) && (amg_print_level > 1)) && (tol > 0.))
    printf("\n\nAMG SOLUTION INFO:\n");
  if (tol >= 0.) {
    if (amg_logging > 1) {
      hypre_ParVectorCopy(F_array[0], Residual);
      hypre_ParCSRMatrixMatvec(alpha, A_array[0], U_array[0], beta, Residual);
      resid_nrm = sqrt(hypre_ParVectorInnerProd(Residual, Residual));
    }
    else {
      hypre_ParVectorCopy(F_array[0], Vtemp);
      hypre_ParCSRMatrixMatvec(alpha, A_array[0], U_array[0], beta, Vtemp);
      resid_nrm = sqrt(hypre_ParVectorInnerProd(Vtemp, Vtemp));
    }
    if (resid_nrm != 0.)
      ieee_check = resid_nrm / resid_nrm;
    if (ieee_check != ieee_check) {
      if (amg_print_level > 0) {
        printf("\n\nERROR detected by Hypre ...  BEGIN\n");
        printf("ERROR -- hypre_BoomerAMGSolve: INFs and/or NaNs detected in input.\n");
        printf("User probably placed non-numerics in supplied A, x_0, or b.\n");
        printf("ERROR detected by Hypre ...  END\n\n\n");
      }
      hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg_solve.c", 908, 1);
      return hypre__global_error;
    }
    resid_nrm_init = resid_nrm;
    rhs_norm = sqrt(hypre_ParVectorInnerProd(f, f));
    if (rhs_norm) {
      relative_resid = resid_nrm_init / rhs_norm;
    }
    else {
      relative_resid = resid_nrm_init;
    }
  }
  else {
    relative_resid = 1.;
  }
  if (((my_id == 0) && (amg_print_level > 1)) && (tol >= 0.)) {
    printf("                                            relative\n");
    printf("               residual        factor       residual\n");
    printf("               --------        ------       --------\n");
    printf("    Initial    %e                 %e\n", resid_nrm_init, relative_resid);
  }
  while (((relative_resid >= tol) || (cycle_count < min_iter)) && (cycle_count < max_iter)) {
    (amg_data)->cycle_op_count = 0;
    hypre_BoomerAMGCycle(amg_data, F_array, U_array);
    if (tol >= 0.) {
      old_resid = resid_nrm;
      if (amg_logging > 1) {
        hypre_ParVectorCopy(F_array[0], Residual);
        hypre_ParCSRMatrixMatvec(alpha, A_array[0], U_array[0], beta, Residual);
        resid_nrm = sqrt(hypre_ParVectorInnerProd(Residual, Residual));
      }
      else {
        hypre_ParVectorCopy(F_array[0], Vtemp);
        hypre_ParCSRMatrixMatvec(alpha, A_array[0], U_array[0], beta, Vtemp);
        resid_nrm = sqrt(hypre_ParVectorInnerProd(Vtemp, Vtemp));
      }
      conv_factor = resid_nrm / old_resid;
      if (rhs_norm) {
        relative_resid = resid_nrm / rhs_norm;
      }
      else {
        relative_resid = resid_nrm;
      }
      (amg_data)->rel_resid_norm = relative_resid;
    }
    ++cycle_count;
    (amg_data)->num_iterations = cycle_count;
    ++(amg_data)->cum_num_iterations;
    if (((my_id == 0) && (amg_print_level > 1)) && (tol >= 0.)) {
      printf("    Cycle %2d   %e    %f     %e \n", cycle_count, resid_nrm, conv_factor, relative_resid);
    }
  }
  if ((cycle_count == max_iter) && (tol > 0.)) {
    Solve_err_flag = 1;
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_amg_solve.c", 908, 256);
  }
  if ((cycle_count > 0) && (tol >= 0.))
    conv_factor = pow(resid_nrm / resid_nrm_init, 1.0 / (double)cycle_count);
  else
    conv_factor = 1.;
  for (j = 0; j < (amg_data)->num_levels; j++) {
    total_coeffs += num_coeffs[j];
    total_variables += num_variables[j];
  }
  cycle_op_count = (amg_data)->cycle_op_count;
  if (num_variables[0])
    grid_cmplxty = total_variables / (num_variables[0]);
  if (num_coeffs[0]) {
    operat_cmplxty = total_coeffs / (num_coeffs[0]);
    cycle_cmplxty = cycle_op_count / (num_coeffs[0]);
  }
  if ((my_id == 0) && (amg_print_level > 1)) {
    if (Solve_err_flag == 1) {
      printf("\n\n==============================================");
      printf("\n NOTE: Convergence tolerance was not achieved\n");
      printf("      within the allowed %d V-cycles\n", max_iter);
      printf("==============================================");
    }
    if (tol >= 0.)
      printf("\n\n Average Convergence Factor = %f", conv_factor);
    printf("\n\n     Complexity:    grid = %f\n", grid_cmplxty);
    printf("                operator = %f\n", operat_cmplxty);
    printf("                   cycle = %f\n\n\n\n", cycle_cmplxty);
  }
  hypre_Free((char*)num_coeffs), num_coeffs = (void*)0;
  hypre_Free((char*)num_variables), num_variables = (void*)0;
  return hypre__global_error;
}
//==================== par_cg_relax_wt.c ===================
int hypre_BoomerAMGCGRelaxWt(void* amg_vdata, int level, int num_cg_sweeps, double* rlx_wt_ptr) {
  hypre_ParAMGData* amg_data = amg_vdata;
  MPI_Comm comm;
  HYPRE_Solver* smoother;
  hypre_ParCSRMatrix* A = (amg_data)->A_array[level];
  hypre_ParVector* Utemp;
  hypre_ParVector* Vtemp;
  hypre_ParVector* Ptemp;
  hypre_ParVector* Rtemp;
  hypre_ParVector* Ztemp;
  hypre_ParVector* Qtemp;
  int* CF_marker = (amg_data)->CF_marker_array[level];
  double* Ptemp_data;
  double* Ztemp_data;
  int* grid_relax_type;
  int Solve_err_flag;
  int i;
  int j;
  int jj;
  int num_sweeps;
  int relax_type;
  int local_size;
  int old_size;
  int my_id = 0;
  int smooth_type;
  int smooth_num_levels;
  int smooth_option = 0;
  double alpha;
  double beta;
  double gamma = 1.0;
  double gammaold;
  double* tridiag;
  double* trioffd;
  double alphinv;
  double row_sum = 0;
  double max_row_sum = 0;
  double rlx_wt = 0;
  double rlx_wt_old = 0;
  double lambda_max;
  double lambda_max_old;
  tridiag = (double*)(hypre_CAlloc((unsigned)(num_cg_sweeps + 1), (unsigned)(sizeof(double))));
  trioffd = (double*)(hypre_CAlloc((unsigned)(num_cg_sweeps + 1), (unsigned)(sizeof(double))));
  for (i = 0; i < (num_cg_sweeps + 1); i++) {
    tridiag[i] = 0;
    trioffd[i] = 0;
  }
  Vtemp = (amg_data)->Vtemp;
  Rtemp = hypre_ParVectorCreate((A)->comm, (A)->global_num_rows, (A)->row_starts);
  hypre_ParVectorInitialize(Rtemp);
  hypre_ParVectorSetPartitioningOwner(Rtemp, 0);
  Ptemp = hypre_ParVectorCreate((A)->comm, (A)->global_num_rows, (A)->row_starts);
  hypre_ParVectorInitialize(Ptemp);
  hypre_ParVectorSetPartitioningOwner(Ptemp, 0);
  Ztemp = hypre_ParVectorCreate((A)->comm, (A)->global_num_rows, (A)->row_starts);
  hypre_ParVectorInitialize(Ztemp);
  hypre_ParVectorSetPartitioningOwner(Ztemp, 0);
  Qtemp = hypre_ParVectorCreate((A)->comm, (A)->global_num_rows, (A)->row_starts);
  hypre_ParVectorInitialize(Qtemp);
  hypre_ParVectorSetPartitioningOwner(Qtemp, 0);
  grid_relax_type = (amg_data)->grid_relax_type;
  smooth_type = (amg_data)->smooth_type;
  smooth_num_levels = (amg_data)->smooth_num_levels;
  Solve_err_flag = 0;
  comm = (A)->comm;
  MPI_Comm_rank(comm, &(my_id));
  if (smooth_num_levels > level) {
    smoother = (amg_data)->smoother;
    smooth_option = smooth_type;
    if ((smooth_type > 6) && (smooth_type < 10)) {
      Utemp = hypre_ParVectorCreate((A)->comm, (A)->global_num_rows, (A)->row_starts);
      (Utemp)->owns_partitioning = 0;
      hypre_ParVectorInitialize(Utemp);
    }
  }
  relax_type = grid_relax_type[1];
  num_sweeps = 1;
  local_size = ((A)->diag)->num_rows;
  old_size = ((Vtemp)->local_vector)->size;
  ((Vtemp)->local_vector)->size = ((A)->diag)->num_rows;
  Ptemp_data = ((Ptemp)->local_vector)->data;
  Ztemp_data = ((Ztemp)->local_vector)->data;
  hypre_ParVectorSetRandomValues(Rtemp, 5128);
  for (jj = 0; jj < num_cg_sweeps; jj++) {
    hypre_ParVectorSetConstantValues(Ztemp, 0.0);
    for (j = 0; j < num_sweeps; j++) {
      {
        Solve_err_flag = hypre_BoomerAMGRelax(A, Rtemp, CF_marker, relax_type, 0, 1.0, 1.0, (void*)0, Ztemp, Vtemp, Qtemp);
      }
      if (Solve_err_flag != 0)
        return Solve_err_flag;
    }
    gammaold = gamma;
    gamma = hypre_ParVectorInnerProd(Rtemp, Ztemp);
    if (jj == 0) {
      hypre_ParVectorCopy(Ztemp, Ptemp);
      beta = 1.0;
    }
    else {
      beta = gamma / gammaold;
      for (i = 0; i < local_size; i++)
        Ptemp_data[i] = (Ztemp_data[i]) + (beta * (Ptemp_data[i]));
    }
    hypre_ParCSRMatrixMatvec(1.0, A, Ptemp, 0.0, Vtemp);
    alpha = gamma / hypre_ParVectorInnerProd(Ptemp, Vtemp);
    alphinv = 1.0 / alpha;
    tridiag[jj + 1] = alphinv;
    (tridiag[jj]) -= beta;
    tridiag[jj] += alphinv;
    (trioffd[jj]) -= sqrt(beta);
    trioffd[jj + 1] = -alphinv;
    row_sum = fabs(tridiag[jj]) + fabs(trioffd[jj]);
    if (row_sum > max_row_sum)
      max_row_sum = row_sum;
    if (jj > 0) {
      row_sum = (fabs(tridiag[jj - 1]) + fabs(trioffd[jj - 1])) + fabs(trioffd[jj]);
      if (row_sum > max_row_sum)
        max_row_sum = row_sum;
      lambda_max_old = lambda_max;
      rlx_wt_old = rlx_wt;
      hypre_Bisection(jj + 1, tridiag, trioffd, lambda_max_old, max_row_sum, 1.e-3, jj + 1, &(lambda_max));
      rlx_wt = 1.0 / lambda_max;
      if (fabs(rlx_wt - rlx_wt_old) < 1.e-3) {
        break;
      }
    }
    else {
      lambda_max = tridiag[0];
    }
    hypre_ParVectorAxpy(-alpha, Vtemp, Rtemp);
  }
  ((Vtemp)->local_vector)->size = old_size;
  hypre_ParVectorDestroy(Ztemp);
  hypre_ParVectorDestroy(Ptemp);
  hypre_ParVectorDestroy(Rtemp);
  hypre_ParVectorDestroy(Qtemp);
  hypre_Free((char*)tridiag), tridiag = (void*)0;
  hypre_Free((char*)trioffd), trioffd = (void*)0;
  if ((smooth_option > 6) && (smooth_option < 10)) {
    hypre_ParVectorDestroy(Utemp);
  }
  *rlx_wt_ptr = rlx_wt;
  return Solve_err_flag;
}
int hypre_Bisection(int n, double* diag, double* offd, double y, double z, double tol, int k, double* ev_ptr) {
  double x;
  double eigen_value;
  int ierr = 0;
  int sign_change = 0;
  int i;
  double p0;
  double p1;
  double p2;
  while (fabs(y - z) > (tol * (fabs(y) + fabs(z)))) {
    x = (y + z) / 2;
    sign_change = 0;
    p0 = 1;
    p1 = (diag[0]) - x;
    if ((p0 * p1) <= 0)
      sign_change++;
    for (i = 1; i < n; i++) {
      p2 = (((diag[i]) - x) * p1) - (((offd[i]) * (offd[i])) * p0);
      p0 = p1;
      p1 = p2;
      if ((p0 * p1) <= 0)
        sign_change++;
    }
    if (sign_change >= k)
      z = x;
    else
      y = x;
  }
  eigen_value = (y + z) / 2;
  *ev_ptr = eigen_value;
  return ierr;
}
//=================== par_coarse_parms.c ===================
int hypre_BoomerAMGCoarseParms(MPI_Comm comm, int local_num_variables, int num_functions, int* dof_func, int* CF_marker, int** coarse_dof_func_ptr, int** coarse_pnts_global_ptr) {
  int i;
  int lcs = 0;
  int ierr = 0;
  int num_procs;
  int local_coarse_size = 0;
  int* coarse_dof_func;
  int* coarse_pnts_global;
  MPI_Comm_size(comm, &(num_procs));
  for (i = 0; i < local_num_variables; i++) {
    if ((CF_marker[i]) == 1)
      lcs++;
  }
  if (num_functions > 1) {
    coarse_dof_func = (int*)(hypre_CAlloc((unsigned)lcs, (unsigned)(sizeof(int))));
    local_coarse_size = 0;
    for (i = 0; i < local_num_variables; i++) {
      if ((CF_marker[i]) == 1)
        coarse_dof_func[lcs++] = dof_func[i];
    }
    *coarse_dof_func_ptr = coarse_dof_func;
  }
  local_coarse_size = (int)lcs;
  coarse_pnts_global = (int*)(hypre_CAlloc((unsigned)(num_procs + 1), (unsigned)(sizeof(int))));
  MPI_Allgather(&(local_coarse_size), 1, MPI_INT, &(coarse_pnts_global[1]), 1, MPI_INT, comm);
  for (i = 2; i < (num_procs + 1); i++)
    coarse_pnts_global[i] += coarse_pnts_global[i - 1];
  *coarse_pnts_global_ptr = coarse_pnts_global;
  return ierr;
}
//====================== par_coarsen.c =====================
int hypre_BoomerAMGCoarsen(hypre_ParCSRMatrix* S, hypre_ParCSRMatrix* A, int CF_init, int debug_flag, int** CF_marker_ptr) {
  MPI_Comm comm = (S)->comm;
  hypre_ParCSRCommPkg* comm_pkg = (S)->comm_pkg;
  hypre_ParCSRCommHandle* comm_handle;
  hypre_CSRMatrix* S_diag = (S)->diag;
  int* S_diag_i = (S_diag)->i;
  int* S_diag_j = (S_diag)->j;
  hypre_CSRMatrix* S_offd = (S)->offd;
  int* S_offd_i = (S_offd)->i;
  int* S_offd_j;
  int num_variables = (S_diag)->num_rows;
  int num_cols_offd = 0;
  hypre_CSRMatrix* S_ext;
  int* S_ext_i;
  int* S_ext_j;
  int num_sends = 0;
  int* int_buf_data;
  double* buf_data;
  int* CF_marker;
  int* CF_marker_offd;
  double* measure_array;
  int* graph_array;
  int* graph_array_offd;
  int graph_size;
  int big_graph_size;
  int graph_offd_size;
  int global_graph_size;
  int i;
  int j;
  int k;
  int kc;
  int jS;
  int kS;
  int ig;
  int elmt;
  int index;
  int start;
  int my_id;
  int num_procs;
  int jrow;
  int cnt;
  int ierr = 0;
  int use_commpkg_A = 0;
  int break_var = 1;
  double wall_time;
  int iter = 0;
  S_ext = (void*)0;
  if (debug_flag == 3)
    wall_time = time_getWallclockSeconds();
  MPI_Comm_size(comm, &(num_procs));
  MPI_Comm_rank(comm, &(my_id));
  if (!comm_pkg) {
    use_commpkg_A = 1;
    comm_pkg = (A)->comm_pkg;
  }
  if (!comm_pkg) {
    hypre_MatvecCommPkgCreate(A);
    comm_pkg = (A)->comm_pkg;
  }
  num_sends = (comm_pkg)->num_sends;
  int_buf_data = (int*)(hypre_CAlloc((unsigned)((comm_pkg)->send_map_starts[num_sends]), (unsigned)(sizeof(int))));
  buf_data = (double*)(hypre_CAlloc((unsigned)((comm_pkg)->send_map_starts[num_sends]), (unsigned)(sizeof(double))));
  num_cols_offd = (S_offd)->num_cols;
  S_diag_j = (S_diag)->j;
  if (num_cols_offd) {
    S_offd_j = (S_offd)->j;
  }
  measure_array = (double*)(hypre_CAlloc((unsigned)(num_variables + num_cols_offd), (unsigned)(sizeof(double))));
  for (i = 0; i < (S_offd_i[num_variables]); i++) {
    measure_array[num_variables + (S_offd_j[i])] += 1.0;
  }
  if (num_procs > 1)
    comm_handle = hypre_ParCSRCommHandleCreate(2, comm_pkg, &(measure_array[num_variables]), buf_data);
  for (i = 0; i < (S_diag_i[num_variables]); i++) {
    measure_array[S_diag_j[i]] += 1.0;
  }
  if (num_procs > 1)
    hypre_ParCSRCommHandleDestroy(comm_handle);
  index = 0;
  for (i = 0; i < num_sends; i++) {
    start = (comm_pkg)->send_map_starts[i];
    for (j = start; j < ((comm_pkg)->send_map_starts[i + 1]); j++)
      measure_array[(comm_pkg)->send_map_elmts[j]] += buf_data[index++];
  }
  for (i = num_variables; i < (num_variables + num_cols_offd); i++) {
    measure_array[i] = 0;
  }
  if (CF_init == 2)
    hypre_BoomerAMGIndepSetInit(S, measure_array, 1);
  else
    hypre_BoomerAMGIndepSetInit(S, measure_array, 0);
  graph_array = (int*)(hypre_CAlloc((unsigned)num_variables, (unsigned)(sizeof(int))));
  if (num_cols_offd)
    graph_array_offd = (int*)(hypre_CAlloc((unsigned)num_cols_offd, (unsigned)(sizeof(int))));
  else
    graph_array_offd = (void*)0;
  for (ig = 0; ig < num_cols_offd; ig++)
    graph_array_offd[ig] = ig;
  graph_offd_size = num_cols_offd;
  if (CF_init == 1) {
    CF_marker = *CF_marker_ptr;
    cnt = 0;
    for (i = 0; i < num_variables; i++) {
      if ((((S_offd_i[i + 1]) - (S_offd_i[i])) > 0) || ((CF_marker[i]) == (-1))) {
        CF_marker[i] = 0;
      }
      if ((CF_marker[i]) == (-2)) {
        if (((measure_array[i]) >= 1.0) || (((S_diag_i[i + 1]) - (S_diag_i[i])) > 0)) {
          CF_marker[i] = 0;
          graph_array[cnt++] = i;
        }
        else {
          CF_marker[i] = -1;
        }
      }
      else
        if ((CF_marker[i]) == (-3))
          measure_array[i] = 0;
        else
          graph_array[cnt++] = i;
    }
  }
  else {
    CF_marker = (int*)(hypre_CAlloc((unsigned)num_variables, (unsigned)(sizeof(int))));
    cnt = 0;
    for (i = 0; i < num_variables; i++) {
      CF_marker[i] = 0;
      if ((((S_diag_i[i + 1]) - (S_diag_i[i])) == 0) && (((S_offd_i[i + 1]) - (S_offd_i[i])) == 0)) {
        CF_marker[i] = -3;
        measure_array[i] = 0;
      }
      else
        graph_array[cnt++] = i;
    }
  }
  graph_size = cnt;
  if (num_cols_offd)
    CF_marker_offd = (int*)(hypre_CAlloc((unsigned)num_cols_offd, (unsigned)(sizeof(int))));
  else
    CF_marker_offd = (void*)0;
  for (i = 0; i < num_cols_offd; i++)
    CF_marker_offd[i] = 0;
  if (num_procs > 1) {
    if (use_commpkg_A)
      S_ext = hypre_ParCSRMatrixExtractConvBExt(S, A, 0);
    else
      S_ext = hypre_ParCSRMatrixExtractConvBExt(S, S, 0);
    S_ext_i = (S_ext)->i;
    S_ext_j = (S_ext)->j;
  }
  if (debug_flag == 3) {
    wall_time = time_getWallclockSeconds() - wall_time;
    printf("Proc = %d    Initialize CLJP phase = %f\n", my_id, wall_time);
  }
  while (1) {
    if (num_procs > 1)
      comm_handle = hypre_ParCSRCommHandleCreate(2, comm_pkg, &(measure_array[num_variables]), buf_data);
    if (num_procs > 1)
      hypre_ParCSRCommHandleDestroy(comm_handle);
    index = 0;
    for (i = 0; i < num_sends; i++) {
      start = (comm_pkg)->send_map_starts[i];
      for (j = start; j < ((comm_pkg)->send_map_starts[i + 1]); j++)
        measure_array[(comm_pkg)->send_map_elmts[j]] += buf_data[index++];
    }
    if (iter || (CF_init != 1)) {
      for (ig = 0; ig < graph_size; ig++) {
        i = graph_array[ig];
        if (((CF_marker[i]) != 1) && ((measure_array[i]) < 1)) {
          CF_marker[i] = -1;
          for (jS = S_diag_i[i]; jS < (S_diag_i[i + 1]); jS++) {
            if ((S_diag_j[jS]) > (-1)) {
              CF_marker[i] = 0;
            }
          }
          for (jS = S_offd_i[i]; jS < (S_offd_i[i + 1]); jS++) {
            if ((S_offd_j[jS]) > (-1)) {
              CF_marker[i] = 0;
            }
          }
        }
        if (CF_marker[i]) {
          measure_array[i] = 0;
          graph_size--;
          graph_array[ig] = graph_array[graph_size];
          graph_array[graph_size] = i;
          ig--;
        }
      }
    }
    if (debug_flag == 3)
      wall_time = time_getWallclockSeconds();
    index = 0;
    for (i = 0; i < num_sends; i++) {
      start = (comm_pkg)->send_map_starts[i];
      for (j = start; j < ((comm_pkg)->send_map_starts[i + 1]); j++) {
        jrow = (comm_pkg)->send_map_elmts[j];
        buf_data[index++] = measure_array[jrow];
      }
    }
    if (num_procs > 1) {
      comm_handle = hypre_ParCSRCommHandleCreate(1, comm_pkg, buf_data, &(measure_array[num_variables]));
      hypre_ParCSRCommHandleDestroy(comm_handle);
    }
    big_graph_size = (int)graph_size;
    MPI_Allreduce(&(big_graph_size), &(global_graph_size), 1, MPI_INT, _SUM, comm);
    if (global_graph_size == 0)
      break;
    if (iter || (CF_init != 1)) {
      hypre_BoomerAMGIndepSet(S, measure_array, graph_array, graph_size, graph_array_offd, graph_offd_size, CF_marker, CF_marker_offd);
      if (num_procs > 1) {
        comm_handle = hypre_ParCSRCommHandleCreate(12, comm_pkg, CF_marker_offd, int_buf_data);
        hypre_ParCSRCommHandleDestroy(comm_handle);
      }
      index = 0;
      for (i = 0; i < num_sends; i++) {
        start = (comm_pkg)->send_map_starts[i];
        for (j = start; j < ((comm_pkg)->send_map_starts[i + 1]); j++) {
          elmt = (comm_pkg)->send_map_elmts[j];
          if ((!(int_buf_data[index++])) && ((CF_marker[elmt]) > 0)) {
            CF_marker[elmt] = 0;
          }
        }
      }
    }
    iter++;
    index = 0;
    for (i = 0; i < num_sends; i++) {
      start = (comm_pkg)->send_map_starts[i];
      for (j = start; j < ((comm_pkg)->send_map_starts[i + 1]); j++) {
        elmt = (comm_pkg)->send_map_elmts[j];
        int_buf_data[index++] = CF_marker[elmt];
      }
    }
    if (num_procs > 1) {
      comm_handle = hypre_ParCSRCommHandleCreate(11, comm_pkg, int_buf_data, CF_marker_offd);
      hypre_ParCSRCommHandleDestroy(comm_handle);
    }
    for (ig = 0; ig < graph_offd_size; ig++) {
      i = graph_array_offd[ig];
      if ((CF_marker_offd[i]) < 0) {
        graph_offd_size--;
        graph_array_offd[ig] = graph_array_offd[graph_offd_size];
        graph_array_offd[graph_offd_size] = i;
        ig--;
      }
    }
    if (debug_flag == 3) {
      wall_time = time_getWallclockSeconds() - wall_time;
      printf("Proc = %d  iter %d  comm. and subgraph update = %f\n", my_id, iter, wall_time);
    }
    for (i = num_variables; i < (num_variables + num_cols_offd); i++) {
      measure_array[i] = 0;
    }
    if (debug_flag == 3)
      wall_time = time_getWallclockSeconds();
    for (ig = 0; ig < graph_size; ig++) {
      i = graph_array[ig];
      if ((CF_marker[i]) > 0) {
        CF_marker[i] = 1;
        for (jS = S_diag_i[i]; jS < (S_diag_i[i + 1]); jS++) {
          j = S_diag_j[jS];
          if (j > (-1)) {
            S_diag_j[jS] = (-(S_diag_j[jS])) - 1;
            if (!(CF_marker[j])) {
              measure_array[j]--;
            }
          }
        }
        for (jS = S_offd_i[i]; jS < (S_offd_i[i + 1]); jS++) {
          j = S_offd_j[jS];
          if (j > (-1)) {
            S_offd_j[jS] = (-(S_offd_j[jS])) - 1;
            if (!(CF_marker_offd[j])) {
              measure_array[j + num_variables]--;
            }
          }
        }
      }
      else {
        for (jS = S_diag_i[i]; jS < (S_diag_i[i + 1]); jS++) {
          j = S_diag_j[jS];
          if (j < 0)
            j = (-j) - 1;
          if ((CF_marker[j]) > 0) {
            if ((S_diag_j[jS]) > (-1)) {
              S_diag_j[jS] = (-(S_diag_j[jS])) - 1;
            }
            CF_marker[j] = 2;
          }
          else
            if ((CF_marker[j]) == (-3)) {
              if ((S_diag_j[jS]) > (-1)) {
                S_diag_j[jS] = (-(S_diag_j[jS])) - 1;
              }
            }
        }
        for (jS = S_offd_i[i]; jS < (S_offd_i[i + 1]); jS++) {
          j = S_offd_j[jS];
          if (j < 0)
            j = (-j) - 1;
          if ((CF_marker_offd[j]) > 0) {
            if ((S_offd_j[jS]) > (-1)) {
              S_offd_j[jS] = (-(S_offd_j[jS])) - 1;
            }
            CF_marker_offd[j] = 2;
          }
          else
            if ((CF_marker_offd[j]) == (-3)) {
              if ((S_offd_j[jS]) > (-1)) {
                S_offd_j[jS] = (-(S_offd_j[jS])) - 1;
              }
            }
        }
        for (jS = S_diag_i[i]; jS < (S_diag_i[i + 1]); jS++) {
          if ((S_diag_j[jS]) > (-1)) {
            j = S_diag_j[jS];
            break_var = 1;
            for (kS = S_diag_i[j]; kS < (S_diag_i[j + 1]); kS++) {
              k = S_diag_j[kS];
              if (k < 0)
                k = (-k) - 1;
              if ((CF_marker[k]) == 2) {
                S_diag_j[jS] = (-(S_diag_j[jS])) - 1;
                measure_array[j]--;
                break_var = 0;
                break;
              }
            }
            if (break_var) {
              for (kS = S_offd_i[j]; kS < (S_offd_i[j + 1]); kS++) {
                k = S_offd_j[kS];
                if (k < 0)
                  k = (-k) - 1;
                if ((CF_marker_offd[k]) == 2) {
                  S_diag_j[jS] = (-(S_diag_j[jS])) - 1;
                  measure_array[j]--;
                  break;
                }
              }
            }
          }
        }
        for (jS = S_offd_i[i]; jS < (S_offd_i[i + 1]); jS++) {
          if ((S_offd_j[jS]) > (-1)) {
            j = S_offd_j[jS];
            for (kS = S_ext_i[j]; kS < (S_ext_i[j + 1]); kS++) {
              k = S_ext_j[kS];
              if (k >= 0) {
                if ((CF_marker[k]) == 2) {
                  S_offd_j[jS] = (-(S_offd_j[jS])) - 1;
                  measure_array[j + num_variables]--;
                  break;
                }
              }
              else {
                kc = (-k) - 1;
                if ((kc > (-1)) && ((CF_marker_offd[kc]) == 2)) {
                  S_offd_j[jS] = (-(S_offd_j[jS])) - 1;
                  measure_array[j + num_variables]--;
                  break;
                }
              }
            }
          }
        }
      }
      for (jS = S_diag_i[i]; jS < (S_diag_i[i + 1]); jS++) {
        j = S_diag_j[jS];
        if (j < 0)
          j = (-j) - 1;
        if ((CF_marker[j]) == 2) {
          CF_marker[j] = 1;
        }
      }
      for (jS = S_offd_i[i]; jS < (S_offd_i[i + 1]); jS++) {
        j = S_offd_j[jS];
        if (j < 0)
          j = (-j) - 1;
        if ((CF_marker_offd[j]) == 2) {
          CF_marker_offd[j] = 1;
        }
      }
    }
    if (debug_flag == 3) {
      wall_time = time_getWallclockSeconds() - wall_time;
      printf("Proc = %d    CLJP phase = %f graph_size = %d nc_offd = %d\n", my_id, wall_time, graph_size, num_cols_offd);
    }
  }
  for (i = 0; i < (S_diag_i[num_variables]); i++) {
    if ((S_diag_j[i]) < 0)
      S_diag_j[i] = (-(S_diag_j[i])) - 1;
  }
  for (i = 0; i < (S_offd_i[num_variables]); i++) {
    if ((S_offd_j[i]) < 0)
      S_offd_j[i] = (-(S_offd_j[i])) - 1;
  }
  hypre_Free((char*)measure_array), measure_array = (void*)0;
  hypre_Free((char*)graph_array), graph_array = (void*)0;
  if (num_cols_offd)
    hypre_Free((char*)graph_array_offd), graph_array_offd = (void*)0;
  hypre_Free((char*)buf_data), buf_data = (void*)0;
  hypre_Free((char*)int_buf_data), int_buf_data = (void*)0;
  hypre_Free((char*)CF_marker_offd), CF_marker_offd = (void*)0;
  if (num_procs > 1)
    hypre_CSRMatrixDestroy(S_ext);
  *CF_marker_ptr = CF_marker;
  return ierr;
}
int hypre_BoomerAMGCoarsenRuge(hypre_ParCSRMatrix* S, hypre_ParCSRMatrix* A, int measure_type, int coarsen_type, int debug_flag, int** CF_marker_ptr) {
  MPI_Comm comm = (S)->comm;
  hypre_ParCSRCommPkg* comm_pkg = (S)->comm_pkg;
  hypre_ParCSRCommHandle* comm_handle;
  hypre_CSRMatrix* S_diag = (S)->diag;
  hypre_CSRMatrix* S_offd = (S)->offd;
  int* S_i = (S_diag)->i;
  int* S_j = (S_diag)->j;
  int* S_offd_i = (S_offd)->i;
  int* S_offd_j;
  int num_variables = (S_diag)->num_rows;
  int num_cols_offd = (S_offd)->num_cols;
  hypre_CSRMatrix* S_ext;
  int* S_ext_i;
  int* S_ext_j;
  hypre_CSRMatrix* ST;
  int* ST_i;
  int* ST_j;
  int* CF_marker;
  int* CF_marker_offd;
  int ci_tilde = -1;
  int ci_tilde_mark = -1;
  int ci_tilde_offd = -1;
  int ci_tilde_offd_mark = -1;
  int* measure_array;
  int* graph_array;
  int* int_buf_data = (void*)0;
  int* ci_array;
  int i;
  int j;
  int k;
  int jS;
  int ji;
  int jj;
  int jk;
  int jm;
  int index;
  int set_empty = 1;
  int C_i_nonempty = 0;
  int num_procs;
  int my_id;
  int num_sends = 0;
  int start;
  hypre_LinkList LoL_head;
  hypre_LinkList LoL_tail;
  int* lists;
  int* where;
  int measure;
  int new_meas;
  int meas_type = 0;
  int agg_2 = 0;
  int num_left;
  int elmt;
  int nabor;
  int nabor_two;
  int ierr = 0;
  int use_commpkg_A = 0;
  int break_var = 0;
  int f_pnt = -1;
  double wall_time;
  if (coarsen_type < 0)
    coarsen_type = -coarsen_type;
  if ((measure_type == 1) || (measure_type == 4))
    meas_type = 1;
  if ((measure_type == 4) || (measure_type == 3))
    agg_2 = 1;
  LoL_head = (void*)0;
  LoL_tail = (void*)0;
  lists = (int*)(hypre_CAlloc((unsigned)num_variables, (unsigned)(sizeof(int))));
  where = (int*)(hypre_CAlloc((unsigned)num_variables, (unsigned)(sizeof(int))));
  if (debug_flag == 3)
    wall_time = time_getWallclockSeconds();
  MPI_Comm_size(comm, &(num_procs));
  MPI_Comm_rank(comm, &(my_id));
  if (!comm_pkg) {
    use_commpkg_A = 1;
    comm_pkg = (A)->comm_pkg;
  }
  if (!comm_pkg) {
    hypre_MatvecCommPkgCreate(A);
    comm_pkg = (A)->comm_pkg;
  }
  num_sends = (comm_pkg)->num_sends;
  if (num_cols_offd)
    S_offd_j = (S_offd)->j;
  jS = S_i[num_variables];
  ST = hypre_CSRMatrixCreate(num_variables, num_variables, jS);
  ST_i = (int*)(hypre_CAlloc((unsigned)(num_variables + 1), (unsigned)(sizeof(int))));
  ST_j = (int*)(hypre_CAlloc((unsigned)jS, (unsigned)(sizeof(int))));
  (ST)->i = ST_i;
  (ST)->j = ST_j;
  for (i = 0; i <= num_variables; i++)
    ST_i[i] = 0;
  for (i = 0; i < jS; i++) {
    ST_i[(S_j[i]) + 1]++;
  }
  for (i = 0; i < num_variables; i++) {
    ST_i[i + 1] += ST_i[i];
  }
  for (i = 0; i < num_variables; i++) {
    for (j = S_i[i]; j < (S_i[i + 1]); j++) {
      index = S_j[j];
      ST_j[ST_i[index]] = i;
      ST_i[index]++;
    }
  }
  for (i = num_variables; i > 0; i--) {
    ST_i[i] = ST_i[i - 1];
  }
  ST_i[0] = 0;
  measure_array = (int*)(hypre_CAlloc((unsigned)num_variables, (unsigned)(sizeof(int))));
  for (i = 0; i < num_variables; i++) {
    measure_array[i] = (ST_i[i + 1]) - (ST_i[i]);
  }
  if (coarsen_type == 6) {
    f_pnt = -2;
    coarsen_type = 1;
  }
  if (coarsen_type == 10) {
    f_pnt = -2;
    coarsen_type = 11;
  }
  if (meas_type && (num_procs > 1)) {
    int* measure_offd;
    measure_offd = (int*)(hypre_CAlloc((unsigned)num_cols_offd, (unsigned)(sizeof(int))));
    int_buf_data = (int*)(hypre_CAlloc((unsigned)((comm_pkg)->send_map_starts[num_sends]), (unsigned)(sizeof(int))));
    for (i = 0; i < (S_offd_i[num_variables]); i++)
      measure_offd[S_offd_j[i]]++;
    comm_handle = hypre_ParCSRCommHandleCreate(12, comm_pkg, measure_offd, int_buf_data);
    hypre_ParCSRCommHandleDestroy(comm_handle);
    index = 0;
    for (i = 0; i < num_sends; i++) {
      start = (comm_pkg)->send_map_starts[i];
      for (j = start; j < ((comm_pkg)->send_map_starts[i + 1]); j++)
        measure_array[(comm_pkg)->send_map_elmts[j]] += int_buf_data[index++];
    }
    hypre_Free((char*)measure_offd), measure_offd = (void*)0;
  }
  if (((coarsen_type != 1) && (coarsen_type != 11)) && (num_procs > 1)) {
    if (use_commpkg_A)
      S_ext = hypre_ParCSRMatrixExtractConvBExt(S, A, 0);
    else
      S_ext = hypre_ParCSRMatrixExtractConvBExt(S, S, 0);
    S_ext_i = (S_ext)->i;
    S_ext_j = (S_ext)->j;
  }
  if (debug_flag == 3)
    wall_time = time_getWallclockSeconds();
  CF_marker = (int*)(hypre_CAlloc((unsigned)num_variables, (unsigned)(sizeof(int))));
  num_left = 0;
  for (j = 0; j < num_variables; j++) {
    if ((((S_i[j + 1]) - (S_i[j])) == 0) && (((S_offd_i[j + 1]) - (S_offd_i[j])) == 0)) {
      CF_marker[j] = -3;
      if (agg_2)
        CF_marker[j] = 3;
      measure_array[j] = 0;
    }
    else {
      CF_marker[j] = 0;
      num_left++;
    }
  }
  for (j = 0; j < num_variables; j++) {
    measure = measure_array[j];
    if (((CF_marker[j]) != (-3)) && ((CF_marker[j]) != 3)) {
      if (measure > 0) {
        enter_on_lists(&(LoL_head), &(LoL_tail), measure, j, lists, where);
      }
      else {
        if (measure < 0)
          printf("negative measure!\n");
        CF_marker[j] = f_pnt;
        for (k = S_i[j]; k < (S_i[j + 1]); k++) {
          nabor = S_j[k];
          if (((CF_marker[nabor]) != (-3)) && ((CF_marker[nabor]) != 3)) {
            if (nabor < j) {
              new_meas = measure_array[nabor];
              if (new_meas > 0)
                remove_point(&(LoL_head), &(LoL_tail), new_meas, nabor, lists, where);
              new_meas = ++measure_array[nabor];
              enter_on_lists(&(LoL_head), &(LoL_tail), new_meas, nabor, lists, where);
            }
            else {
              new_meas = ++measure_array[nabor];
            }
          }
        }
        --num_left;
      }
    }
  }
  while (num_left > 0) {
    index = (LoL_head)->head;
    CF_marker[index] = 1;
    measure = measure_array[index];
    measure_array[index] = 0;
    --num_left;
    remove_point(&(LoL_head), &(LoL_tail), measure, index, lists, where);
    for (j = ST_i[index]; j < (ST_i[index + 1]); j++) {
      nabor = ST_j[j];
      if ((CF_marker[nabor]) == 0) {
        CF_marker[nabor] = -1;
        measure = measure_array[nabor];
        remove_point(&(LoL_head), &(LoL_tail), measure, nabor, lists, where);
        --num_left;
        for (k = S_i[nabor]; k < (S_i[nabor + 1]); k++) {
          nabor_two = S_j[k];
          if ((CF_marker[nabor_two]) == 0) {
            measure = measure_array[nabor_two];
            remove_point(&(LoL_head), &(LoL_tail), measure, nabor_two, lists, where);
            new_meas = ++measure_array[nabor_two];
            enter_on_lists(&(LoL_head), &(LoL_tail), new_meas, nabor_two, lists, where);
          }
        }
      }
    }
    for (j = S_i[index]; j < (S_i[index + 1]); j++) {
      nabor = S_j[j];
      if ((CF_marker[nabor]) == 0) {
        measure = measure_array[nabor];
        remove_point(&(LoL_head), &(LoL_tail), measure, nabor, lists, where);
        measure_array[nabor] = --measure;
        if (measure > 0)
          enter_on_lists(&(LoL_head), &(LoL_tail), measure, nabor, lists, where);
        else {
          CF_marker[nabor] = -1;
          --num_left;
          for (k = S_i[nabor]; k < (S_i[nabor + 1]); k++) {
            nabor_two = S_j[k];
            if ((CF_marker[nabor_two]) == 0) {
              new_meas = measure_array[nabor_two];
              remove_point(&(LoL_head), &(LoL_tail), new_meas, nabor_two, lists, where);
              new_meas = ++measure_array[nabor_two];
              enter_on_lists(&(LoL_head), &(LoL_tail), new_meas, nabor_two, lists, where);
            }
          }
        }
      }
    }
  }
  hypre_Free((char*)measure_array), measure_array = (void*)0;
  hypre_CSRMatrixDestroy(ST);
  if (debug_flag == 3) {
    wall_time = time_getWallclockSeconds() - wall_time;
    printf("Proc = %d    Coarsen 1st pass = %f\n", my_id, wall_time);
  }
  hypre_Free((char*)lists), lists = (void*)0;
  hypre_Free((char*)where), where = (void*)0;
  hypre_Free((char*)LoL_head), LoL_head = (void*)0;
  hypre_Free((char*)LoL_tail), LoL_tail = (void*)0;
  for (i = 0; i < num_variables; i++)
    if ((CF_marker[i]) == 3)
      CF_marker[i] = 1;
  if (coarsen_type == 11) {
    hypre_Free((char*)int_buf_data), int_buf_data = (void*)0;
    int_buf_data = (void*)0;
    *CF_marker_ptr = CF_marker;
    return 0;
  }
  graph_array = (int*)(hypre_CAlloc((unsigned)num_variables, (unsigned)(sizeof(int))));
  for (i = 0; i < num_variables; i++) {
    graph_array[i] = -1;
  }
  if (debug_flag == 3)
    wall_time = time_getWallclockSeconds();
  if (coarsen_type == 2) {
    CF_marker_offd = (int*)(hypre_CAlloc((unsigned)num_cols_offd, (unsigned)(sizeof(int))));
    if (int_buf_data == (void*)0)
      int_buf_data = (int*)(hypre_CAlloc((unsigned)((comm_pkg)->send_map_starts[num_sends]), (unsigned)(sizeof(int))));
    index = 0;
    for (i = 0; i < num_sends; i++) {
      start = (comm_pkg)->send_map_starts[i];
      for (j = start; j < ((comm_pkg)->send_map_starts[i + 1]); j++)
        int_buf_data[index++] = CF_marker[(comm_pkg)->send_map_elmts[j]];
    }
    if (num_procs > 1) {
      comm_handle = hypre_ParCSRCommHandleCreate(11, comm_pkg, int_buf_data, CF_marker_offd);
      hypre_ParCSRCommHandleDestroy(comm_handle);
    }
    ci_array = (int*)(hypre_CAlloc((unsigned)num_cols_offd, (unsigned)(sizeof(int))));
    for (i = 0; i < num_cols_offd; i++)
      ci_array[i] = -1;
    for (i = 0; i < num_variables; i++) {
      if (ci_tilde_mark |= i)
        ci_tilde = -1;
      if (ci_tilde_offd_mark |= i)
        ci_tilde_offd = -1;
      if ((CF_marker[i]) == (-1)) {
        break_var = 1;
        for (ji = S_i[i]; ji < (S_i[i + 1]); ji++) {
          j = S_j[ji];
          if ((CF_marker[j]) > 0)
            graph_array[j] = i;
        }
        for (ji = S_offd_i[i]; ji < (S_offd_i[i + 1]); ji++) {
          j = S_offd_j[ji];
          if ((CF_marker_offd[j]) > 0)
            ci_array[j] = i;
        }
        for (ji = S_i[i]; ji < (S_i[i + 1]); ji++) {
          j = S_j[ji];
          if ((CF_marker[j]) == (-1)) {
            set_empty = 1;
            for (jj = S_i[j]; jj < (S_i[j + 1]); jj++) {
              index = S_j[jj];
              if ((graph_array[index]) == i) {
                set_empty = 0;
                break;
              }
            }
            if (set_empty) {
              for (jj = S_offd_i[j]; jj < (S_offd_i[j + 1]); jj++) {
                index = S_offd_j[jj];
                if ((ci_array[index]) == i) {
                  set_empty = 0;
                  break;
                }
              }
            }
            if (set_empty) {
              if (C_i_nonempty) {
                CF_marker[i] = 1;
                if (ci_tilde > (-1)) {
                  CF_marker[ci_tilde] = -1;
                  ci_tilde = -1;
                }
                if (ci_tilde_offd > (-1)) {
                  CF_marker_offd[ci_tilde_offd] = -1;
                  ci_tilde_offd = -1;
                }
                C_i_nonempty = 0;
                break_var = 0;
                break;
              }
              else {
                ci_tilde = j;
                ci_tilde_mark = i;
                CF_marker[j] = 1;
                C_i_nonempty = 1;
                i--;
                break_var = 0;
                break;
              }
            }
          }
        }
        if (break_var) {
          for (ji = S_offd_i[i]; ji < (S_offd_i[i + 1]); ji++) {
            j = S_offd_j[ji];
            if ((CF_marker_offd[j]) == (-1)) {
              set_empty = 1;
              for (jj = S_ext_i[j]; jj < (S_ext_i[j + 1]); jj++) {
                index = S_ext_j[jj];
                if (index >= 0) {
                  if ((graph_array[index]) == i) {
                    set_empty = 0;
                    break;
                  }
                }
                else {
                  jk = (-index) - 1;
                  if ((ci_array[jk]) == i) {
                    set_empty = 0;
                    break;
                  }
                }
              }
              if (set_empty) {
                if (C_i_nonempty) {
                  CF_marker[i] = 1;
                  if (ci_tilde > (-1)) {
                    CF_marker[ci_tilde] = -1;
                    ci_tilde = -1;
                  }
                  if (ci_tilde_offd > (-1)) {
                    CF_marker_offd[ci_tilde_offd] = -1;
                    ci_tilde_offd = -1;
                  }
                  C_i_nonempty = 0;
                  break;
                }
                else {
                  ci_tilde_offd = j;
                  ci_tilde_offd_mark = i;
                  CF_marker_offd[j] = 1;
                  C_i_nonempty = 1;
                  i--;
                  break;
                }
              }
            }
          }
        }
      }
    }
  }
  else {
    for (i = 0; i < num_variables; i++) {
      if (ci_tilde_mark |= i)
        ci_tilde = -1;
      if ((CF_marker[i]) == (-1)) {
        for (ji = S_i[i]; ji < (S_i[i + 1]); ji++) {
          j = S_j[ji];
          if ((CF_marker[j]) > 0)
            graph_array[j] = i;
        }
        for (ji = S_i[i]; ji < (S_i[i + 1]); ji++) {
          j = S_j[ji];
          if ((CF_marker[j]) == (-1)) {
            set_empty = 1;
            for (jj = S_i[j]; jj < (S_i[j + 1]); jj++) {
              index = S_j[jj];
              if ((graph_array[index]) == i) {
                set_empty = 0;
                break;
              }
            }
            if (set_empty) {
              if (C_i_nonempty) {
                CF_marker[i] = 1;
                if (ci_tilde > (-1)) {
                  CF_marker[ci_tilde] = -1;
                  ci_tilde = -1;
                }
                C_i_nonempty = 0;
                break;
              }
              else {
                ci_tilde = j;
                ci_tilde_mark = i;
                CF_marker[j] = 1;
                C_i_nonempty = 1;
                i--;
                break;
              }
            }
          }
        }
      }
    }
  }
  if ((debug_flag == 3) && (coarsen_type != 2)) {
    wall_time = time_getWallclockSeconds() - wall_time;
    printf("Proc = %d    Coarsen 2nd pass = %f\n", my_id, wall_time);
  }
  if ((coarsen_type == 3) || (coarsen_type == 4)) {
    if (debug_flag == 3)
      wall_time = time_getWallclockSeconds();
    CF_marker_offd = (int*)(hypre_CAlloc((unsigned)num_cols_offd, (unsigned)(sizeof(int))));
    if (int_buf_data == (void*)0)
      int_buf_data = (int*)(hypre_CAlloc((unsigned)((comm_pkg)->send_map_starts[num_sends]), (unsigned)(sizeof(int))));
    index = 0;
    for (i = 0; i < num_sends; i++) {
      start = (comm_pkg)->send_map_starts[i];
      for (j = start; j < ((comm_pkg)->send_map_starts[i + 1]); j++)
        int_buf_data[index++] = CF_marker[(comm_pkg)->send_map_elmts[j]];
    }
    if (num_procs > 1) {
      comm_handle = hypre_ParCSRCommHandleCreate(11, comm_pkg, int_buf_data, CF_marker_offd);
      hypre_ParCSRCommHandleDestroy(comm_handle);
    }
    ci_array = (int*)(hypre_CAlloc((unsigned)num_cols_offd, (unsigned)(sizeof(int))));
    for (i = 0; i < num_cols_offd; i++)
      ci_array[i] = -1;
  }
  if ((coarsen_type > 1) && (coarsen_type < 5)) {
    for (i = 0; i < num_variables; i++)
      graph_array[i] = -1;
    for (i = 0; i < num_cols_offd; i++) {
      if (ci_tilde_mark |= i)
        ci_tilde = -1;
      if (ci_tilde_offd_mark |= i)
        ci_tilde_offd = -1;
      if ((CF_marker_offd[i]) == (-1)) {
        for (ji = S_ext_i[i]; ji < (S_ext_i[i + 1]); ji++) {
          j = S_ext_j[ji];
          if (j >= 0) {
            if ((CF_marker[j]) > 0)
              graph_array[j] = i;
          }
          else {
            jj = (-j) - 1;
            if ((CF_marker_offd[jj]) > 0)
              ci_array[jj] = i;
          }
        }
        for (ji = S_ext_i[i]; ji < (S_ext_i[i + 1]); ji++) {
          j = S_ext_j[ji];
          if (j >= 0) {
            if ((CF_marker[j]) == (-1)) {
              set_empty = 1;
              for (jj = S_i[j]; jj < (S_i[j + 1]); jj++) {
                index = S_j[jj];
                if ((graph_array[index]) == i) {
                  set_empty = 0;
                  break;
                }
              }
              for (jj = S_offd_i[j]; jj < (S_offd_i[j + 1]); jj++) {
                index = S_offd_j[jj];
                if ((ci_array[index]) == i) {
                  set_empty = 0;
                  break;
                }
              }
              if (set_empty) {
                if (C_i_nonempty) {
                  CF_marker_offd[i] = 1;
                  if (ci_tilde > (-1)) {
                    CF_marker[ci_tilde] = -1;
                    ci_tilde = -1;
                  }
                  if (ci_tilde_offd > (-1)) {
                    CF_marker_offd[ci_tilde_offd] = -1;
                    ci_tilde_offd = -1;
                  }
                  C_i_nonempty = 0;
                  break;
                }
                else {
                  ci_tilde = j;
                  ci_tilde_mark = i;
                  CF_marker[j] = 1;
                  C_i_nonempty = 1;
                  i--;
                  break;
                }
              }
            }
          }
          else {
            jm = (-j) - 1;
            if ((CF_marker_offd[jm]) == (-1)) {
              set_empty = 1;
              for (jj = S_ext_i[jm]; jj < (S_ext_i[jm + 1]); jj++) {
                index = S_ext_j[jj];
                if (index >= 0) {
                  if ((graph_array[index]) == i) {
                    set_empty = 0;
                    break;
                  }
                }
                else {
                  jk = (-index) - 1;
                  if ((ci_array[jk]) == i) {
                    set_empty = 0;
                    break;
                  }
                }
              }
              if (set_empty) {
                if (C_i_nonempty) {
                  CF_marker_offd[i] = 1;
                  if (ci_tilde > (-1)) {
                    CF_marker[ci_tilde] = -1;
                    ci_tilde = -1;
                  }
                  if (ci_tilde_offd > (-1)) {
                    CF_marker_offd[ci_tilde_offd] = -1;
                    ci_tilde_offd = -1;
                  }
                  C_i_nonempty = 0;
                  break;
                }
                else {
                  ci_tilde_offd = jm;
                  ci_tilde_offd_mark = i;
                  CF_marker_offd[jm] = 1;
                  C_i_nonempty = 1;
                  i--;
                  break;
                }
              }
            }
          }
        }
      }
    }
    if (num_procs > 1) {
      comm_handle = hypre_ParCSRCommHandleCreate(12, comm_pkg, CF_marker_offd, int_buf_data);
      hypre_ParCSRCommHandleDestroy(comm_handle);
    }
    index = 0;
    if (coarsen_type != 4) {
      for (i = 0; i < num_sends; i++) {
        start = (comm_pkg)->send_map_starts[i];
        if (((comm_pkg)->send_procs[i]) > my_id) {
          for (j = start; j < ((comm_pkg)->send_map_starts[i + 1]); j++)
            CF_marker[(comm_pkg)->send_map_elmts[j]] = int_buf_data[index++];
        }
        else {
          index += ((comm_pkg)->send_map_starts[i + 1]) - start;
        }
      }
    }
    else {
      for (i = 0; i < num_sends; i++) {
        start = (comm_pkg)->send_map_starts[i];
        if (((comm_pkg)->send_procs[i]) > my_id) {
          for (j = start; j < ((comm_pkg)->send_map_starts[i + 1]); j++) {
            elmt = (comm_pkg)->send_map_elmts[j];
            if ((CF_marker[elmt]) != 1)
              CF_marker[elmt] = int_buf_data[index];
            index++;
          }
        }
        else {
          index += ((comm_pkg)->send_map_starts[i + 1]) - start;
        }
      }
    }
    if (debug_flag == 3) {
      wall_time = time_getWallclockSeconds() - wall_time;
      if (coarsen_type == 4)
        printf("Proc = %d    Coarsen 3rd pass = %f\n", my_id, wall_time);
      if (coarsen_type == 3)
        printf("Proc = %d    Coarsen 3rd pass = %f\n", my_id, wall_time);
      if (coarsen_type == 2)
        printf("Proc = %d    Coarsen 2nd pass = %f\n", my_id, wall_time);
    }
  }
  if (coarsen_type == 5) {
    if (debug_flag == 3)
      wall_time = time_getWallclockSeconds();
    CF_marker_offd = (int*)(hypre_CAlloc((unsigned)num_cols_offd, (unsigned)(sizeof(int))));
    if (int_buf_data == (void*)0)
      int_buf_data = (int*)(hypre_CAlloc((unsigned)((comm_pkg)->send_map_starts[num_sends]), (unsigned)(sizeof(int))));
    index = 0;
    for (i = 0; i < num_sends; i++) {
      start = (comm_pkg)->send_map_starts[i];
      for (j = start; j < ((comm_pkg)->send_map_starts[i + 1]); j++)
        int_buf_data[index++] = CF_marker[(comm_pkg)->send_map_elmts[j]];
    }
    if (num_procs > 1) {
      comm_handle = hypre_ParCSRCommHandleCreate(11, comm_pkg, int_buf_data, CF_marker_offd);
      hypre_ParCSRCommHandleDestroy(comm_handle);
    }
    ci_array = (int*)(hypre_CAlloc((unsigned)num_cols_offd, (unsigned)(sizeof(int))));
    for (i = 0; i < num_cols_offd; i++)
      ci_array[i] = -1;
    for (i = 0; i < num_variables; i++)
      graph_array[i] = -1;
    for (i = 0; i < num_variables; i++) {
      if (((CF_marker[i]) == (-1)) && (((S_offd_i[i + 1]) - (S_offd_i[i])) > 0)) {
        break_var = 1;
        for (ji = S_i[i]; ji < (S_i[i + 1]); ji++) {
          j = S_j[ji];
          if ((CF_marker[j]) > 0)
            graph_array[j] = i;
        }
        for (ji = S_offd_i[i]; ji < (S_offd_i[i + 1]); ji++) {
          j = S_offd_j[ji];
          if ((CF_marker_offd[j]) > 0)
            ci_array[j] = i;
        }
        for (ji = S_offd_i[i]; ji < (S_offd_i[i + 1]); ji++) {
          j = S_offd_j[ji];
          if ((CF_marker_offd[j]) == (-1)) {
            set_empty = 1;
            for (jj = S_ext_i[j]; jj < (S_ext_i[j + 1]); jj++) {
              index = S_ext_j[jj];
              if (index >= 0) {
                if ((graph_array[index]) == i) {
                  set_empty = 0;
                  break;
                }
              }
              else {
                jk = (-index) - 1;
                if ((ci_array[jk]) == i) {
                  set_empty = 0;
                  break;
                }
              }
            }
            if (set_empty) {
              if (C_i_nonempty) {
                CF_marker[i] = -2;
                C_i_nonempty = 0;
                break;
              }
              else {
                C_i_nonempty = 1;
                i--;
                break;
              }
            }
          }
        }
      }
    }
    if (debug_flag == 3) {
      wall_time = time_getWallclockSeconds() - wall_time;
      printf("Proc = %d    Coarsen special points = %f\n", my_id, wall_time);
    }
  }
  hypre_Free((char*)int_buf_data), int_buf_data = (void*)0;
  if (coarsen_type != 1) {
    hypre_Free((char*)CF_marker_offd), CF_marker_offd = (void*)0;
    hypre_Free((char*)ci_array), ci_array = (void*)0;
  }
  hypre_Free((char*)graph_array), graph_array = (void*)0;
  if ((meas_type || (coarsen_type != 1)) && (num_procs > 1))
    hypre_CSRMatrixDestroy(S_ext);
  *CF_marker_ptr = CF_marker;
  return ierr;
}
int hypre_BoomerAMGCoarsenFalgout(hypre_ParCSRMatrix* S, hypre_ParCSRMatrix* A, int measure_type, int debug_flag, int** CF_marker_ptr) {
  int ierr = 0;
  ierr += hypre_BoomerAMGCoarsenRuge(S, A, measure_type, 6, debug_flag, CF_marker_ptr);
  ierr += hypre_BoomerAMGCoarsen(S, A, 1, debug_flag, CF_marker_ptr);
  return ierr;
}
int hypre_BoomerAMGCoarsenHMIS(hypre_ParCSRMatrix* S, hypre_ParCSRMatrix* A, int measure_type, int debug_flag, int** CF_marker_ptr) {
  int ierr = 0;
  ierr += hypre_BoomerAMGCoarsenRuge(S, A, measure_type, 10, debug_flag, CF_marker_ptr);
  ierr += hypre_BoomerAMGCoarsenPMIS(S, A, 1, debug_flag, CF_marker_ptr);
  return ierr;
}
int hypre_BoomerAMGCoarsenPMIS(hypre_ParCSRMatrix* S, hypre_ParCSRMatrix* A, int CF_init, int debug_flag, int** CF_marker_ptr) {
  MPI_Comm comm = (S)->comm;
  hypre_ParCSRCommPkg* comm_pkg = (S)->comm_pkg;
  hypre_ParCSRCommHandle* comm_handle;
  hypre_CSRMatrix* S_diag = (S)->diag;
  int* S_diag_i = (S_diag)->i;
  int* S_diag_j = (S_diag)->j;
  hypre_CSRMatrix* S_offd = (S)->offd;
  int* S_offd_i = (S_offd)->i;
  int* S_offd_j;
  int num_variables = (S_diag)->num_rows;
  int num_cols_offd = 0;
  int num_sends = 0;
  int* int_buf_data;
  double* buf_data;
  int* CF_marker;
  int* CF_marker_offd;
  double* measure_array;
  int* graph_array;
  int* graph_array_offd;
  int graph_size;
  int big_graph_size;
  int graph_offd_size;
  int global_graph_size;
  int i;
  int j;
  int jS;
  int ig;
  int index;
  int start;
  int my_id;
  int num_procs;
  int jrow;
  int cnt;
  int elmt;
  int ierr = 0;
  double wall_time;
  int iter = 0;
  if (debug_flag == 3)
    wall_time = time_getWallclockSeconds();
  MPI_Comm_size(comm, &(num_procs));
  MPI_Comm_rank(comm, &(my_id));
  if (!comm_pkg) {
    comm_pkg = (A)->comm_pkg;
  }
  if (!comm_pkg) {
    hypre_MatvecCommPkgCreate(A);
    comm_pkg = (A)->comm_pkg;
  }
  num_sends = (comm_pkg)->num_sends;
  int_buf_data = (int*)(hypre_CAlloc((unsigned)((comm_pkg)->send_map_starts[num_sends]), (unsigned)(sizeof(int))));
  buf_data = (double*)(hypre_CAlloc((unsigned)((comm_pkg)->send_map_starts[num_sends]), (unsigned)(sizeof(double))));
  num_cols_offd = (S_offd)->num_cols;
  S_diag_j = (S_diag)->j;
  if (num_cols_offd) {
    S_offd_j = (S_offd)->j;
  }
  measure_array = (double*)(hypre_CAlloc((unsigned)(num_variables + num_cols_offd), (unsigned)(sizeof(double))));
  for (i = 0; i < (S_offd_i[num_variables]); i++) {
    measure_array[num_variables + (S_offd_j[i])] += 1.0;
  }
  if (num_procs > 1)
    comm_handle = hypre_ParCSRCommHandleCreate(2, comm_pkg, &(measure_array[num_variables]), buf_data);
  for (i = 0; i < (S_diag_i[num_variables]); i++) {
    measure_array[S_diag_j[i]] += 1.0;
  }
  if (num_procs > 1)
    hypre_ParCSRCommHandleDestroy(comm_handle);
  index = 0;
  for (i = 0; i < num_sends; i++) {
    start = (comm_pkg)->send_map_starts[i];
    for (j = start; j < ((comm_pkg)->send_map_starts[i + 1]); j++)
      measure_array[(comm_pkg)->send_map_elmts[j]] += buf_data[index++];
  }
  for (i = num_variables; i < (num_variables + num_cols_offd); i++) {
    measure_array[i] = 0;
  }
  if ((CF_init == 2) || (CF_init == 4))
    hypre_BoomerAMGIndepSetInit(S, measure_array, 1);
  else
    hypre_BoomerAMGIndepSetInit(S, measure_array, 0);
  if (num_cols_offd)
    graph_array_offd = (int*)(hypre_CAlloc((unsigned)num_cols_offd, (unsigned)(sizeof(int))));
  else
    graph_array_offd = (void*)0;
  for (ig = 0; ig < num_cols_offd; ig++)
    graph_array_offd[ig] = ig;
  graph_offd_size = num_cols_offd;
  graph_array = (int*)(hypre_CAlloc((unsigned)num_variables, (unsigned)(sizeof(int))));
  if (CF_init == 1) {
    CF_marker = *CF_marker_ptr;
    cnt = 0;
    for (i = 0; i < num_variables; i++) {
      if ((((S_offd_i[i + 1]) - (S_offd_i[i])) > 0) || ((CF_marker[i]) == (-1))) {
        CF_marker[i] = 0;
      }
      if ((CF_marker[i]) == (-2)) {
        if (((measure_array[i]) >= 1.0) || (((S_diag_i[i + 1]) - (S_diag_i[i])) > 0)) {
          CF_marker[i] = 0;
          graph_array[cnt++] = i;
        }
        else {
          CF_marker[i] = -1;
        }
      }
      else
        if ((CF_marker[i]) == (-3))
          measure_array[i] = 0;
        else
          graph_array[cnt++] = i;
    }
  }
  else {
    CF_marker = (int*)(hypre_CAlloc((unsigned)num_variables, (unsigned)(sizeof(int))));
    cnt = 0;
    for (i = 0; i < num_variables; i++) {
      CF_marker[i] = 0;
      if ((((S_diag_i[i + 1]) - (S_diag_i[i])) == 0) && (((S_offd_i[i + 1]) - (S_offd_i[i])) == 0)) {
        CF_marker[i] = -3;
        if ((CF_init == 3) || (CF_init == 4))
          CF_marker[i] = 1;
        measure_array[i] = 0;
      }
      else
        graph_array[cnt++] = i;
    }
  }
  graph_size = cnt;
  if (num_cols_offd)
    CF_marker_offd = (int*)(hypre_CAlloc((unsigned)num_cols_offd, (unsigned)(sizeof(int))));
  else
    CF_marker_offd = (void*)0;
  for (i = 0; i < num_cols_offd; i++)
    CF_marker_offd[i] = 0;
  index = 0;
  for (i = 0; i < num_sends; i++) {
    start = (comm_pkg)->send_map_starts[i];
    for (j = start; j < ((comm_pkg)->send_map_starts[i + 1]); j++) {
      jrow = (comm_pkg)->send_map_elmts[j];
      buf_data[index++] = measure_array[jrow];
    }
  }
  if (num_procs > 1) {
    comm_handle = hypre_ParCSRCommHandleCreate(1, comm_pkg, buf_data, &(measure_array[num_variables]));
    hypre_ParCSRCommHandleDestroy(comm_handle);
  }
  if (debug_flag == 3) {
    wall_time = time_getWallclockSeconds() - wall_time;
    printf("Proc = %d    Initialize CLJP phase = %f\n", my_id, wall_time);
  }
  while (1) {
    big_graph_size = (int)graph_size;
    MPI_Allreduce(&(big_graph_size), &(global_graph_size), 1, MPI_INT, _SUM, comm);
    if (global_graph_size == 0)
      break;
    if ((!CF_init) || iter) {
      hypre_BoomerAMGIndepSet(S, measure_array, graph_array, graph_size, graph_array_offd, graph_offd_size, CF_marker, CF_marker_offd);
      if (num_procs > 1) {
        comm_handle = hypre_ParCSRCommHandleCreate(12, comm_pkg, CF_marker_offd, int_buf_data);
        hypre_ParCSRCommHandleDestroy(comm_handle);
      }
      index = 0;
      for (i = 0; i < num_sends; i++) {
        start = (comm_pkg)->send_map_starts[i];
        for (j = start; j < ((comm_pkg)->send_map_starts[i + 1]); j++) {
          elmt = (comm_pkg)->send_map_elmts[j];
          if ((!(int_buf_data[index])) && ((CF_marker[elmt]) > 0)) {
            CF_marker[elmt] = 0;
            index++;
          }
          else {
            int_buf_data[index++] = CF_marker[elmt];
          }
        }
      }
      if (num_procs > 1) {
        comm_handle = hypre_ParCSRCommHandleCreate(11, comm_pkg, int_buf_data, CF_marker_offd);
        hypre_ParCSRCommHandleDestroy(comm_handle);
      }
    }
    iter++;
    for (ig = 0; ig < graph_size; ig++) {
      i = graph_array[ig];
      if ((measure_array[i]) < 1.) {
        CF_marker[i] = -1;
      }
      if ((CF_marker[i]) > 0) {
        CF_marker[i] = 1;
      }
      else {
        for (jS = S_diag_i[i]; jS < (S_diag_i[i + 1]); jS++) {
          j = S_diag_j[jS];
          if ((CF_marker[j]) > 0) {
            CF_marker[i] = -1;
          }
        }
        for (jS = S_offd_i[i]; jS < (S_offd_i[i + 1]); jS++) {
          j = S_offd_j[jS];
          if ((CF_marker_offd[j]) > 0) {
            CF_marker[i] = -1;
          }
        }
      }
    }
    index = 0;
    for (i = 0; i < num_sends; i++) {
      start = (comm_pkg)->send_map_starts[i];
      for (j = start; j < ((comm_pkg)->send_map_starts[i + 1]); j++)
        int_buf_data[index++] = CF_marker[(comm_pkg)->send_map_elmts[j]];
    }
    if (num_procs > 1) {
      comm_handle = hypre_ParCSRCommHandleCreate(11, comm_pkg, int_buf_data, CF_marker_offd);
      hypre_ParCSRCommHandleDestroy(comm_handle);
    }
    for (ig = 0; ig < graph_size; ig++) {
      i = graph_array[ig];
      if ((!(CF_marker[i])) == 0) {
        measure_array[i] = 0;
        graph_size--;
        graph_array[ig] = graph_array[graph_size];
        graph_array[graph_size] = i;
        ig--;
      }
    }
    for (ig = 0; ig < graph_offd_size; ig++) {
      i = graph_array_offd[ig];
      if ((!(CF_marker_offd[i])) == 0) {
        measure_array[i + num_variables] = 0;
        graph_offd_size--;
        graph_array_offd[ig] = graph_array_offd[graph_offd_size];
        graph_array_offd[graph_offd_size] = i;
        ig--;
      }
    }
  }
  hypre_Free((char*)measure_array), measure_array = (void*)0;
  hypre_Free((char*)graph_array), graph_array = (void*)0;
  if (num_cols_offd)
    hypre_Free((char*)graph_array_offd), graph_array_offd = (void*)0;
  hypre_Free((char*)buf_data), buf_data = (void*)0;
  hypre_Free((char*)int_buf_data), int_buf_data = (void*)0;
  hypre_Free((char*)CF_marker_offd), CF_marker_offd = (void*)0;
  *CF_marker_ptr = CF_marker;
  return ierr;
}
//======================= par_cycle.c ======================
int hypre_BoomerAMGCycle(void* amg_vdata, hypre_ParVector** F_array, hypre_ParVector** U_array) {
  hypre_ParAMGData* amg_data = amg_vdata;
  hypre_SeqAMGData* seq_data = (amg_data)->seq_data;
  MPI_Comm comm;
  HYPRE_Solver* smoother;
  hypre_ParCSRMatrix** A_array;
  hypre_ParCSRMatrix** P_array;
  hypre_ParCSRMatrix** R_array;
  hypre_ParVector* Vtemp;
  hypre_ParVector* Rtemp;
  hypre_ParVector* Ptemp;
  hypre_ParVector* Ztemp;
  hypre_ParVector* Aux_U;
  hypre_ParVector* Aux_F;
  int** CF_marker_array;
  double cycle_op_count;
  int cycle_type;
  int num_levels;
  int max_levels;
  double* num_coeffs;
  int* num_grid_sweeps;
  int* grid_relax_type;
  int** grid_relax_points;
  double* max_eig_est;
  double* min_eig_est;
  int cheby_order;
  double cheby_eig_ratio;
  int* lev_counter;
  int Solve_err_flag;
  int k;
  int j;
  int jj;
  int level;
  int cycle_param;
  int coarse_grid;
  int fine_grid;
  int Not_Finished;
  int num_sweep;
  int cg_num_sweep = 1;
  int relax_type;
  int relax_points;
  int relax_order;
  int relax_local;
  int old_version = 0;
  double* relax_weight;
  double* omega;
  double beta;
  int local_size;
  double alpha;
  double** l1_norms = (void*)0;
  double* l1_norms_level;
  int myid;
  int seq_cg = 0;
  if (seq_data)
    seq_cg = 1;
  MPI_Comm_rank(MPI_COMM_WORLD, &(myid));
  A_array = (amg_data)->A_array;
  P_array = (amg_data)->P_array;
  R_array = (amg_data)->R_array;
  CF_marker_array = (amg_data)->CF_marker_array;
  Vtemp = (amg_data)->Vtemp;
  Rtemp = (amg_data)->Rtemp;
  Ptemp = (amg_data)->Ptemp;
  Ztemp = (amg_data)->Ztemp;
  num_levels = (amg_data)->num_levels;
  max_levels = (amg_data)->max_levels;
  cycle_type = (amg_data)->cycle_type;
  num_grid_sweeps = (amg_data)->num_grid_sweeps;
  grid_relax_type = (amg_data)->grid_relax_type;
  grid_relax_points = (amg_data)->grid_relax_points;
  relax_order = (amg_data)->relax_order;
  relax_weight = (amg_data)->relax_weight;
  omega = (amg_data)->omega;
  l1_norms = (amg_data)->l1_norms;
  max_eig_est = (amg_data)->max_eig_est;
  min_eig_est = (amg_data)->min_eig_est;
  cheby_order = (amg_data)->cheby_order;
  cheby_eig_ratio = (amg_data)->cheby_eig_ratio;
  cycle_op_count = (amg_data)->cycle_op_count;
  lev_counter = (int*)(hypre_CAlloc((unsigned)num_levels, (unsigned)(sizeof(int))));
  Solve_err_flag = 0;
  if (grid_relax_points)
    old_version = 1;
  num_coeffs = (double*)(hypre_CAlloc((unsigned)num_levels, (unsigned)(sizeof(double))));
  num_coeffs[0] = (A_array[0])->d_num_nonzeros;
  comm = (A_array[0])->comm;
  for (j = 1; j < num_levels; j++)
    num_coeffs[j] = (A_array[j])->d_num_nonzeros;
  Not_Finished = 1;
  smoother = (amg_data)->smoother;
  lev_counter[0] = 1;
  for (k = 1; k < num_levels; ++k) {
    lev_counter[k] = cycle_type;
  }
  level = 0;
  cycle_param = 1;
  while (Not_Finished) {
    if (num_levels > 1) {
      local_size = ((F_array[level])->local_vector)->size;
      ((Vtemp)->local_vector)->size = local_size;
      cg_num_sweep = 1;
      num_sweep = num_grid_sweeps[cycle_param];
      Aux_U = U_array[level];
      Aux_F = F_array[level];
      relax_type = grid_relax_type[cycle_param];
    }
    else {
      Aux_U = U_array[level];
      Aux_F = F_array[level];
      num_sweep = 1;
      relax_type = 0;
    }
    if (l1_norms != (void*)0)
      l1_norms_level = l1_norms[level];
    else
      l1_norms_level = (void*)0;
    if ((cycle_param == 3) && seq_cg) {
      hypre_seqAMGCycle(amg_data, level, F_array, U_array);
    }
    else {
      for (jj = 0; jj < cg_num_sweep; jj++) {
        for (j = 0; j < num_sweep; j++) {
          if ((num_levels == 1) && (max_levels > 1)) {
            relax_points = 0;
            relax_local = 0;
          }
          else {
            if (old_version)
              relax_points = grid_relax_points[cycle_param][j];
            relax_local = relax_order;
          }
          if (old_version && (level < (num_levels - 1))) {
            switch (relax_points) {
              case 1:
                cycle_op_count += num_coeffs[level + 1];
                break;
              case -1:
                cycle_op_count += (num_coeffs[level]) - (num_coeffs[level + 1]);
                break;
            }
          }
          else {
            cycle_op_count += num_coeffs[level];
          }
          if ((((relax_type == 11) || (relax_type == 15)) || (relax_type == 16)) || (relax_type == 17)) {
            int scale = 0;
            int variant = 0;
            if ((relax_type == 15) || (relax_type == 17)) {
              variant = 1;
            }
            if ((relax_type == 16) || (relax_type == 17)) {
              scale = 1;
            }
            hypre_ParCSRRelax_Cheby(A_array[level], Aux_F, max_eig_est[level], min_eig_est[level], cheby_eig_ratio, cheby_order, scale, variant, Aux_U, Vtemp, Ztemp);
          }
          else
            if (relax_type == 12) {
              hypre_BoomerAMGRelax_FCFJacobi(A_array[level], Aux_F, CF_marker_array[level], relax_weight[level], Aux_U, Vtemp);
            }
            else
              if ((relax_type == 13) || (relax_type == 14)) {
                if (j == 0)
                  hypre_ParCSRRelax_CG(smoother[level], A_array[level], Aux_F, Aux_U, num_sweep);
              }
              else
                if (relax_type == 8) {
                  hypre_ParCSRRelax_L1(A_array[level], Aux_F, relax_weight[level], omega[level], l1_norms_level, Aux_U, Vtemp, Ztemp);
                }
                else
                  if (relax_type == 19) {
                    hypre_ParCSRRelax_L1_GS(A_array[level], Aux_F, relax_weight[level], omega[level], l1_norms_level, Aux_U, Vtemp, Ztemp);
                  }
                  else
                    if (relax_type == 18) {
                      if ((relax_order == 1) && (cycle_type < 3)) {
                        int i;
                        int  loc_relax_points[2];
                        if (cycle_type < 2) {
                          loc_relax_points[0] = 1;
                          loc_relax_points[1] = -1;
                        }
                        else {
                          loc_relax_points[0] = -1;
                          loc_relax_points[1] = 1;
                        }
                        for (i = 0; i < 2; i++)
                          hypre_ParCSRRelax_L1_Jacobi(A_array[level], Aux_F, CF_marker_array[level], loc_relax_points[i], relax_weight[level], l1_norms_level, Aux_U, Vtemp);
                      }
                      else {
                        hypre_ParCSRRelax_L1_Jacobi(A_array[level], Aux_F, CF_marker_array[level], 0, relax_weight[level], l1_norms_level, Aux_U, Vtemp);
                      }
                    }
                    else {
                      if (old_version) {
                        Solve_err_flag = hypre_BoomerAMGRelax(A_array[level], Aux_F, CF_marker_array[level], relax_type, relax_points, relax_weight[level], omega[level], l1_norms_level, Aux_U, Vtemp, Ztemp);
                      }
                      else {
                        Solve_err_flag = hypre_BoomerAMGRelaxIF(A_array[level], Aux_F, CF_marker_array[level], relax_type, relax_local, cycle_param, relax_weight[level], omega[level], l1_norms_level, Aux_U, Vtemp, Ztemp);
                      }
                    }
          if (Solve_err_flag != 0)
            return Solve_err_flag;
        }
      }
    }
    --lev_counter[level];
    if (((lev_counter[level]) >= 0) && (level != (num_levels - 1))) {
      fine_grid = level;
      coarse_grid = level + 1;
      hypre_ParVectorSetConstantValues(U_array[coarse_grid], 0.0);
      hypre_ParVectorCopy(F_array[fine_grid], Vtemp);
      alpha = -1.0;
      beta = 1.0;
      hypre_ParCSRMatrixMatvec(alpha, A_array[fine_grid], U_array[fine_grid], beta, Vtemp);
      alpha = 1.0;
      beta = 0.0;
      hypre_ParCSRMatrixMatvecT(alpha, R_array[fine_grid], Vtemp, beta, F_array[coarse_grid]);
      ++level;
      lev_counter[level] = (lev_counter[level]) < cycle_type ? cycle_type : lev_counter[level];
      cycle_param = 1;
      if (level == (num_levels - 1))
        cycle_param = 3;
    }
    else
      if (level != 0) {
        fine_grid = level - 1;
        coarse_grid = level;
        alpha = 1.0;
        beta = 1.0;
        hypre_ParCSRMatrixMatvec(alpha, P_array[fine_grid], U_array[coarse_grid], beta, U_array[fine_grid]);
        --level;
        cycle_param = 2;
      }
      else {
        Not_Finished = 0;
      }
  }
  (amg_data)->cycle_op_count = cycle_op_count;
  hypre_Free((char*)lev_counter), lev_counter = (void*)0;
  hypre_Free((char*)num_coeffs), num_coeffs = (void*)0;
  return Solve_err_flag;
}
//===================== par_indepset.c =====================
int hypre_BoomerAMGIndepSetInit(hypre_ParCSRMatrix* S, double* measure_array, int seq_rand) {
  hypre_CSRMatrix* S_diag = (S)->diag;
  MPI_Comm comm = (S)->comm;
  int S_num_nodes = (S_diag)->num_rows;
  int i;
  int j;
  int my_id;
  int ierr = 0;
  MPI_Comm_rank(comm, &(my_id));
  j = 2747 + my_id;
  if (seq_rand)
    j = 2747;
  hypre_SeedRand(j);
  if (seq_rand) {
    for (i = 0; i < (S)->first_row_index; i++)
      hypre_Rand();
  }
  for (j = 0; j < S_num_nodes; j++) {
    measure_array[j] += hypre_Rand();
  }
  return ierr;
}
int hypre_BoomerAMGIndepSet(hypre_ParCSRMatrix* S, double* measure_array, int* graph_array, int graph_array_size, int* graph_array_offd, int graph_array_offd_size, int* IS_marker, int* IS_marker_offd) {
  hypre_CSRMatrix* S_diag = (S)->diag;
  int* S_diag_i = (S_diag)->i;
  int* S_diag_j = (S_diag)->j;
  hypre_CSRMatrix* S_offd = (S)->offd;
  int* S_offd_i = (S_offd)->i;
  int* S_offd_j;
  int local_num_vars = (S_diag)->num_rows;
  int i;
  int j;
  int ig;
  int jS;
  int jj;
  int ierr = 0;
  if ((S_offd)->num_cols) {
    S_offd_j = (S_offd)->j;
  }
  for (ig = 0; ig < graph_array_size; ig++) {
    i = graph_array[ig];
    if ((measure_array[i]) > 1) {
      IS_marker[i] = 1;
    }
  }
  for (ig = 0; ig < graph_array_offd_size; ig++) {
    i = graph_array_offd[ig];
    if ((measure_array[i + local_num_vars]) > 1) {
      IS_marker_offd[i] = 1;
    }
  }
  for (ig = 0; ig < graph_array_size; ig++) {
    i = graph_array[ig];
    if ((measure_array[i]) > 1) {
      for (jS = S_diag_i[i]; jS < (S_diag_i[i + 1]); jS++) {
        j = S_diag_j[jS];
        if (j < 0)
          j = (-j) - 1;
        if ((measure_array[j]) > 1) {
          if ((measure_array[i]) > (measure_array[j])) {
            IS_marker[j] = 0;
          }
          else
            if ((measure_array[j]) > (measure_array[i])) {
              IS_marker[i] = 0;
            }
        }
      }
      for (jS = S_offd_i[i]; jS < (S_offd_i[i + 1]); jS++) {
        jj = S_offd_j[jS];
        if (jj < 0)
          jj = (-jj) - 1;
        j = local_num_vars + jj;
        if ((measure_array[j]) > 1) {
          if ((measure_array[i]) > (measure_array[j])) {
            IS_marker_offd[jj] = 0;
          }
          else
            if ((measure_array[j]) > (measure_array[i])) {
              IS_marker[i] = 0;
            }
        }
      }
    }
  }
  return ierr;
}
//====================== par_interp.c ======================
int hypre_BoomerAMGBuildInterp(hypre_ParCSRMatrix* A, int* CF_marker, hypre_ParCSRMatrix* S, int* num_cpts_global, int num_functions, int* dof_func, int debug_flag, double trunc_factor, int max_elmts, int* col_offd_S_to_A, hypre_ParCSRMatrix** P_ptr) {
  MPI_Comm comm = (A)->comm;
  hypre_ParCSRCommPkg* comm_pkg = (A)->comm_pkg;
  hypre_ParCSRCommHandle* comm_handle;
  hypre_CSRMatrix* A_diag = (A)->diag;
  double* A_diag_data = (A_diag)->data;
  int* A_diag_i = (A_diag)->i;
  int* A_diag_j = (A_diag)->j;
  hypre_CSRMatrix* A_offd = (A)->offd;
  double* A_offd_data = (A_offd)->data;
  int* A_offd_i = (A_offd)->i;
  int* A_offd_j = (A_offd)->j;
  int num_cols_A_offd = (A_offd)->num_cols;
  hypre_CSRMatrix* S_diag = (S)->diag;
  int* S_diag_i = (S_diag)->i;
  int* S_diag_j = (S_diag)->j;
  hypre_CSRMatrix* S_offd = (S)->offd;
  int* S_offd_i = (S_offd)->i;
  int* S_offd_j = (S_offd)->j;
  hypre_ParCSRMatrix* P;
  int* col_map_offd_P = (void*)0;
  int* tmp_map_offd = (void*)0;
  int* CF_marker_offd = (void*)0;
  int* dof_func_offd = (void*)0;
  hypre_CSRMatrix* A_ext;
  double* A_ext_data;
  int* A_ext_i;
  int* A_ext_j;
  hypre_CSRMatrix* P_diag;
  hypre_CSRMatrix* P_offd;
  double* P_diag_data = (void*)0;
  int* P_diag_i;
  int* P_diag_j = (void*)0;
  double* P_offd_data = (void*)0;
  int* P_offd_i;
  int* P_offd_j = (void*)0;
  int P_diag_size;
  int P_offd_size;
  int* P_marker = (void*)0;
  int* P_marker_offd = (void*)0;
  int jj_counter;
  int jj_counter_offd;
  int* jj_count;
  int* jj_count_offd;
  int jj_begin_row;
  int jj_begin_row_offd;
  int jj_end_row;
  int jj_end_row_offd;
  int start_indexing = 0;
  int n_fine = (A_diag)->num_rows;
  int strong_f_marker;
  int* fine_to_coarse;
  int* coarse_counter;
  int coarse_shift;
  int total_global_cpts;
  int my_first_cpt;
  int num_cols_P_offd;
  int i;
  int i1;
  int i2;
  int j;
  int jl;
  int jj;
  int jj1;
  int start;
  int sgn;
  int c_num;
  double diagonal;
  double sum;
  double distribute;
  double zero = 0.0;
  double one = 1.0;
  int my_id;
  int num_procs;
  int num_threads;
  int num_sends;
  int index;
  int ns;
  int ne;
  int size;
  int rest;
  int* int_buf_data = (void*)0;
  double wall_time;
  MPI_Comm_size(comm, &(num_procs));
  MPI_Comm_rank(comm, &(my_id));
  num_threads = 1;
  my_first_cpt = num_cpts_global[my_id];
  total_global_cpts = num_cpts_global[num_procs];
  if (debug_flag == 4)
    wall_time = time_getWallclockSeconds();
  if (num_cols_A_offd)
    CF_marker_offd = (int*)(hypre_CAlloc((unsigned)num_cols_A_offd, (unsigned)(sizeof(int))));
  if ((num_functions > 1) && num_cols_A_offd)
    dof_func_offd = (int*)(hypre_CAlloc((unsigned)num_cols_A_offd, (unsigned)(sizeof(int))));
  if (!comm_pkg) {
    hypre_MatvecCommPkgCreate(A);
    comm_pkg = (A)->comm_pkg;
  }
  num_sends = (comm_pkg)->num_sends;
  if ((comm_pkg)->send_map_starts[num_sends])
    int_buf_data = (int*)(hypre_CAlloc((unsigned)((comm_pkg)->send_map_starts[num_sends]), (unsigned)(sizeof(int))));
  index = 0;
  for (i = 0; i < num_sends; i++) {
    start = (comm_pkg)->send_map_starts[i];
    for (j = start; j < ((comm_pkg)->send_map_starts[i + 1]); j++)
      int_buf_data[index++] = CF_marker[(comm_pkg)->send_map_elmts[j]];
  }
  comm_handle = hypre_ParCSRCommHandleCreate(11, comm_pkg, int_buf_data, CF_marker_offd);
  hypre_ParCSRCommHandleDestroy(comm_handle);
  if (num_functions > 1) {
    index = 0;
    for (i = 0; i < num_sends; i++) {
      start = (comm_pkg)->send_map_starts[i];
      for (j = start; j < ((comm_pkg)->send_map_starts[i + 1]); j++)
        int_buf_data[index++] = dof_func[(comm_pkg)->send_map_elmts[j]];
    }
    comm_handle = hypre_ParCSRCommHandleCreate(11, comm_pkg, int_buf_data, dof_func_offd);
    hypre_ParCSRCommHandleDestroy(comm_handle);
  }
  if (debug_flag == 4) {
    wall_time = time_getWallclockSeconds() - wall_time;
    printf("Proc = %d     Interp: Comm 1 CF_marker =    %f\n", my_id, wall_time);
    fflush((void*)0);
  }
  if (debug_flag == 4)
    wall_time = time_getWallclockSeconds();
  if (num_procs > 1) {
    A_ext = hypre_ParCSRMatrixExtractConvBExt(A, A, 1);
    A_ext_i = (A_ext)->i;
    A_ext_j = (A_ext)->j;
    A_ext_data = (A_ext)->data;
  }
  if (debug_flag == 4) {
    wall_time = time_getWallclockSeconds() - wall_time;
    printf("Proc = %d  Interp: Comm 2   Get A_ext =  %f\n", my_id, wall_time);
    fflush((void*)0);
  }
  coarse_counter = (int*)(hypre_CAlloc((unsigned)num_threads, (unsigned)(sizeof(int))));
  jj_count = (int*)(hypre_CAlloc((unsigned)num_threads, (unsigned)(sizeof(int))));
  jj_count_offd = (int*)(hypre_CAlloc((unsigned)num_threads, (unsigned)(sizeof(int))));
  fine_to_coarse = (int*)(hypre_CAlloc((unsigned)n_fine, (unsigned)(sizeof(int))));
  for (i = 0; i < n_fine; i++)
    fine_to_coarse[i] = -1;
  jj_counter = start_indexing;
  jj_counter_offd = start_indexing;
  for (j = 0; j < num_threads; j++) {
    size = n_fine / num_threads;
    rest = n_fine - (size * num_threads);
    if (j < rest) {
      ns = (j * size) + j;
      ne = (((j + 1) * size) + j) + 1;
    }
    else {
      ns = (j * size) + rest;
      ne = ((j + 1) * size) + rest;
    }
    for (i = ns; i < ne; i++) {
      if ((CF_marker[i]) >= 0) {
        jj_count[j]++;
        fine_to_coarse[i] = coarse_counter[j];
        coarse_counter[j]++;
      }
      else {
        for (jj = S_diag_i[i]; jj < (S_diag_i[i + 1]); jj++) {
          i1 = S_diag_j[jj];
          if ((CF_marker[i1]) >= 0) {
            jj_count[j]++;
          }
        }
        if (num_procs > 1) {
          if (col_offd_S_to_A) {
            for (jj = S_offd_i[i]; jj < (S_offd_i[i + 1]); jj++) {
              i1 = col_offd_S_to_A[S_offd_j[jj]];
              if ((CF_marker_offd[i1]) >= 0) {
                jj_count_offd[j]++;
              }
            }
          }
          else {
            for (jj = S_offd_i[i]; jj < (S_offd_i[i + 1]); jj++) {
              i1 = S_offd_j[jj];
              if ((CF_marker_offd[i1]) >= 0) {
                jj_count_offd[j]++;
              }
            }
          }
        }
      }
    }
  }
  for (i = 0; i < (num_threads - 1); i++) {
    coarse_counter[i + 1] += coarse_counter[i];
    jj_count[i + 1] += jj_count[i];
    jj_count_offd[i + 1] += jj_count_offd[i];
  }
  i = num_threads - 1;
  jj_counter = jj_count[i];
  jj_counter_offd = jj_count_offd[i];
  P_diag_size = jj_counter;
  P_diag_i = (int*)(hypre_CAlloc((unsigned)(n_fine + 1), (unsigned)(sizeof(int))));
  if (P_diag_size) {
    P_diag_j = (int*)(hypre_CAlloc((unsigned)P_diag_size, (unsigned)(sizeof(int))));
    P_diag_data = (double*)(hypre_CAlloc((unsigned)P_diag_size, (unsigned)(sizeof(double))));
  }
  P_diag_i[n_fine] = jj_counter;
  P_offd_size = jj_counter_offd;
  P_offd_i = (int*)(hypre_CAlloc((unsigned)(n_fine + 1), (unsigned)(sizeof(int))));
  if (P_offd_size) {
    P_offd_j = (int*)(hypre_CAlloc((unsigned)P_offd_size, (unsigned)(sizeof(int))));
    P_offd_data = (double*)(hypre_CAlloc((unsigned)P_offd_size, (unsigned)(sizeof(double))));
  }
  jj_counter = start_indexing;
  jj_counter_offd = start_indexing;
  if (debug_flag == 4) {
    wall_time = time_getWallclockSeconds() - wall_time;
    printf("Proc = %d     Interp: Internal work 1 =     %f\n", my_id, wall_time);
    fflush((void*)0);
  }
  if (debug_flag == 4)
    wall_time = time_getWallclockSeconds();
  for (j = 0; j < num_threads; j++) {
    coarse_shift = 0;
    if (j > 0)
      coarse_shift = coarse_counter[j - 1];
    size = n_fine / num_threads;
    rest = n_fine - (size * num_threads);
    if (j < rest) {
      ns = (j * size) + j;
      ne = (((j + 1) * size) + j) + 1;
    }
    else {
      ns = (j * size) + rest;
      ne = ((j + 1) * size) + rest;
    }
    for (i = ns; i < ne; i++)
      fine_to_coarse[i] += coarse_shift;
  }
  if (debug_flag == 4)
    wall_time = time_getWallclockSeconds();
  for (jl = 0; jl < num_threads; jl++) {
    size = n_fine / num_threads;
    rest = n_fine - (size * num_threads);
    if (jl < rest) {
      ns = (jl * size) + jl;
      ne = (((jl + 1) * size) + jl) + 1;
    }
    else {
      ns = (jl * size) + rest;
      ne = ((jl + 1) * size) + rest;
    }
    jj_counter = 0;
    if (jl > 0)
      jj_counter = jj_count[jl - 1];
    jj_counter_offd = 0;
    if (jl > 0)
      jj_counter_offd = jj_count_offd[jl - 1];
    if (n_fine)
      P_marker = (int*)(hypre_CAlloc((unsigned)n_fine, (unsigned)(sizeof(int))));
    else
      P_marker = (void*)0;
    if (num_cols_A_offd)
      P_marker_offd = (int*)(hypre_CAlloc((unsigned)num_cols_A_offd, (unsigned)(sizeof(int))));
    else
      P_marker_offd = (void*)0;
    for (i = 0; i < n_fine; i++) {
      P_marker[i] = -1;
    }
    for (i = 0; i < num_cols_A_offd; i++) {
      P_marker_offd[i] = -1;
    }
    strong_f_marker = -2;
    for (i = ns; i < ne; i++) {
      if ((CF_marker[i]) >= 0) {
        P_diag_i[i] = jj_counter;
        P_diag_j[jj_counter] = fine_to_coarse[i];
        P_diag_data[jj_counter] = one;
        jj_counter++;
      }
      else {
        P_diag_i[i] = jj_counter;
        jj_begin_row = jj_counter;
        for (jj = S_diag_i[i]; jj < (S_diag_i[i + 1]); jj++) {
          i1 = S_diag_j[jj];
          if ((CF_marker[i1]) >= 0) {
            P_marker[i1] = jj_counter;
            P_diag_j[jj_counter] = fine_to_coarse[i1];
            P_diag_data[jj_counter] = zero;
            jj_counter++;
          }
          else
            if ((CF_marker[i1]) != (-3)) {
              P_marker[i1] = strong_f_marker;
            }
        }
        jj_end_row = jj_counter;
        P_offd_i[i] = jj_counter_offd;
        jj_begin_row_offd = jj_counter_offd;
        if (num_procs > 1) {
          if (col_offd_S_to_A) {
            for (jj = S_offd_i[i]; jj < (S_offd_i[i + 1]); jj++) {
              i1 = col_offd_S_to_A[S_offd_j[jj]];
              if ((CF_marker_offd[i1]) >= 0) {
                P_marker_offd[i1] = jj_counter_offd;
                P_offd_j[jj_counter_offd] = i1;
                P_offd_data[jj_counter_offd] = zero;
                jj_counter_offd++;
              }
              else
                if ((CF_marker_offd[i1]) != (-3)) {
                  P_marker_offd[i1] = strong_f_marker;
                }
            }
          }
          else {
            for (jj = S_offd_i[i]; jj < (S_offd_i[i + 1]); jj++) {
              i1 = S_offd_j[jj];
              if ((CF_marker_offd[i1]) >= 0) {
                P_marker_offd[i1] = jj_counter_offd;
                P_offd_j[jj_counter_offd] = i1;
                P_offd_data[jj_counter_offd] = zero;
                jj_counter_offd++;
              }
              else
                if ((CF_marker_offd[i1]) != (-3)) {
                  P_marker_offd[i1] = strong_f_marker;
                }
            }
          }
        }
        jj_end_row_offd = jj_counter_offd;
        diagonal = A_diag_data[A_diag_i[i]];
        for (jj = (A_diag_i[i]) + 1; jj < (A_diag_i[i + 1]); jj++) {
          i1 = A_diag_j[jj];
          if ((P_marker[i1]) >= jj_begin_row) {
            P_diag_data[P_marker[i1]] += A_diag_data[jj];
          }
          else
            if ((P_marker[i1]) == strong_f_marker) {
              sum = zero;
              sgn = 1;
              if ((A_diag_data[A_diag_i[i1]]) < 0)
                sgn = -1;
              for (jj1 = A_diag_i[i1]; jj1 < (A_diag_i[i1 + 1]); jj1++) {
                i2 = A_diag_j[jj1];
                if (((P_marker[i2]) >= jj_begin_row) && ((sgn * (A_diag_data[jj1])) < 0)) {
                  sum += A_diag_data[jj1];
                }
              }
              if (num_procs > 1) {
                for (jj1 = A_offd_i[i1]; jj1 < (A_offd_i[i1 + 1]); jj1++) {
                  i2 = A_offd_j[jj1];
                  if (((P_marker_offd[i2]) >= jj_begin_row_offd) && ((sgn * (A_offd_data[jj1])) < 0)) {
                    sum += A_offd_data[jj1];
                  }
                }
              }
              if (sum != 0) {
                distribute = (A_diag_data[jj]) / sum;
                for (jj1 = A_diag_i[i1]; jj1 < (A_diag_i[i1 + 1]); jj1++) {
                  i2 = A_diag_j[jj1];
                  if (((P_marker[i2]) >= jj_begin_row) && ((sgn * (A_diag_data[jj1])) < 0)) {
                    P_diag_data[P_marker[i2]] += distribute * (A_diag_data[jj1]);
                  }
                }
                if (num_procs > 1) {
                  for (jj1 = A_offd_i[i1]; jj1 < (A_offd_i[i1 + 1]); jj1++) {
                    i2 = A_offd_j[jj1];
                    if (((P_marker_offd[i2]) >= jj_begin_row_offd) && ((sgn * (A_offd_data[jj1])) < 0)) {
                      P_offd_data[P_marker_offd[i2]] += distribute * (A_offd_data[jj1]);
                    }
                  }
                }
              }
              else {
                if ((num_functions == 1) || ((dof_func[i]) == (dof_func[i1])))
                  diagonal += A_diag_data[jj];
              }
            }
            else
              if ((CF_marker[i1]) != (-3)) {
                if ((num_functions == 1) || ((dof_func[i]) == (dof_func[i1])))
                  diagonal += A_diag_data[jj];
              }
        }
        if (num_procs > 1) {
          for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
            i1 = A_offd_j[jj];
            if ((P_marker_offd[i1]) >= jj_begin_row_offd) {
              P_offd_data[P_marker_offd[i1]] += A_offd_data[jj];
            }
            else
              if ((P_marker_offd[i1]) == strong_f_marker) {
                sum = zero;
                c_num = A_offd_j[jj];
                sgn = 1;
                if ((A_ext_data[A_ext_i[c_num]]) < 0)
                  sgn = -1;
                for (jj1 = A_ext_i[c_num]; jj1 < (A_ext_i[c_num + 1]); jj1++) {
                  i2 = A_ext_j[jj1];
                  if (i2 > (-1)) {
                    if (((P_marker[i2]) >= jj_begin_row) && ((sgn * (A_ext_data[jj1])) < 0)) {
                      sum += A_ext_data[jj1];
                    }
                  }
                  else {
                    if (((P_marker_offd[(-i2) - 1]) >= jj_begin_row_offd) && ((sgn * (A_ext_data[jj1])) < 0)) {
                      sum += A_ext_data[jj1];
                    }
                  }
                }
                if (sum != 0) {
                  distribute = (A_offd_data[jj]) / sum;
                  for (jj1 = A_ext_i[c_num]; jj1 < (A_ext_i[c_num + 1]); jj1++) {
                    i2 = A_ext_j[jj1];
                    if (i2 > (-1)) {
                      if (((P_marker[i2]) >= jj_begin_row) && ((sgn * (A_ext_data[jj1])) < 0)) {
                        P_diag_data[P_marker[i2]] += distribute * (A_ext_data[jj1]);
                      }
                    }
                    else {
                      if (((P_marker_offd[(-i2) - 1]) >= jj_begin_row_offd) && ((sgn * (A_ext_data[jj1])) < 0))
                        P_offd_data[P_marker_offd[(-i2) - 1]] += distribute * (A_ext_data[jj1]);
                    }
                  }
                }
                else {
                  if ((num_functions == 1) || ((dof_func[i]) == (dof_func_offd[i1])))
                    diagonal += A_offd_data[jj];
                }
              }
              else
                if ((CF_marker_offd[i1]) != (-3)) {
                  if ((num_functions == 1) || ((dof_func[i]) == (dof_func_offd[i1])))
                    diagonal += A_offd_data[jj];
                }
          }
        }
        if (diagonal == 0.0) {
          printf(" Warning! zero diagonal! Proc id %d row %d\n", my_id, i);
          diagonal = A_diag_data[A_diag_i[i]];
        }
        for (jj = jj_begin_row; jj < jj_end_row; jj++) {
          (P_diag_data[jj]) /= (-diagonal);
        }
        for (jj = jj_begin_row_offd; jj < jj_end_row_offd; jj++) {
          (P_offd_data[jj]) /= (-diagonal);
        }
      }
      strong_f_marker--;
      P_offd_i[i + 1] = jj_counter_offd;
    }
    hypre_Free((char*)P_marker), P_marker = (void*)0;
    hypre_Free((char*)P_marker_offd), P_marker_offd = (void*)0;
  }
  P = hypre_ParCSRMatrixCreate(comm, (A)->global_num_rows, total_global_cpts, (A)->col_starts, num_cpts_global, 0, P_diag_i[n_fine], P_offd_i[n_fine]);
  P_diag = (P)->diag;
  (P_diag)->data = P_diag_data;
  (P_diag)->i = P_diag_i;
  (P_diag)->j = P_diag_j;
  P_offd = (P)->offd;
  (P_offd)->data = P_offd_data;
  (P_offd)->i = P_offd_i;
  (P_offd)->j = P_offd_j;
  (P)->owns_row_starts = 0;
  if ((trunc_factor != 0.0) || (max_elmts > 0)) {
    hypre_BoomerAMGInterpTruncation(P, trunc_factor, max_elmts);
    P_diag_data = (P_diag)->data;
    P_diag_i = (P_diag)->i;
    P_diag_j = (P_diag)->j;
    P_offd_data = (P_offd)->data;
    P_offd_i = (P_offd)->i;
    P_offd_j = (P_offd)->j;
    P_diag_size = P_diag_i[n_fine];
    P_offd_size = P_offd_i[n_fine];
  }
  num_cols_P_offd = 0;
  if (P_offd_size) {
    if (num_cols_A_offd)
      P_marker = (int*)(hypre_CAlloc((unsigned)num_cols_A_offd, (unsigned)(sizeof(int))));
    for (i = 0; i < num_cols_A_offd; i++)
      P_marker[i] = 0;
    num_cols_P_offd = 0;
    for (i = 0; i < P_offd_size; i++) {
      index = P_offd_j[i];
      if (!(P_marker[index])) {
        num_cols_P_offd++;
        P_marker[index] = 1;
      }
    }
    if (num_cols_P_offd) {
      col_map_offd_P = (int*)(hypre_CAlloc((unsigned)num_cols_P_offd, (unsigned)(sizeof(int))));
      tmp_map_offd = (int*)(hypre_CAlloc((unsigned)num_cols_P_offd, (unsigned)(sizeof(int))));
    }
    index = 0;
    for (i = 0; i < num_cols_P_offd; i++) {
      while ((P_marker[index]) == 0)
        index++;
      tmp_map_offd[i] = index++;
    }
    for (i = 0; i < P_offd_size; i++)
      P_offd_j[i] = hypre_BinarySearch(tmp_map_offd, P_offd_j[i], num_cols_P_offd);
    hypre_Free((char*)P_marker), P_marker = (void*)0;
  }
  for (i = 0; i < n_fine; i++)
    if ((CF_marker[i]) == (-3))
      CF_marker[i] = -1;
  if (num_cols_P_offd) {
    (P)->col_map_offd = col_map_offd_P;
    (P_offd)->num_cols = num_cols_P_offd;
  }
  if (num_procs > 1)
    hypre_GetCommPkgRTFromCommPkgA(P, A, fine_to_coarse, tmp_map_offd);
  *P_ptr = P;
  hypre_Free((char*)tmp_map_offd), tmp_map_offd = (void*)0;
  hypre_Free((char*)CF_marker_offd), CF_marker_offd = (void*)0;
  hypre_Free((char*)dof_func_offd), dof_func_offd = (void*)0;
  hypre_Free((char*)int_buf_data), int_buf_data = (void*)0;
  hypre_Free((char*)fine_to_coarse), fine_to_coarse = (void*)0;
  hypre_Free((char*)coarse_counter), coarse_counter = (void*)0;
  hypre_Free((char*)jj_count), jj_count = (void*)0;
  hypre_Free((char*)jj_count_offd), jj_count_offd = (void*)0;
  if (num_procs > 1)
    hypre_CSRMatrixDestroy(A_ext);
  return 0;
}
int hypre_BoomerAMGInterpTruncation(hypre_ParCSRMatrix* P, double trunc_factor, int max_elmts) {
  hypre_CSRMatrix* P_diag = (P)->diag;
  int* P_diag_i = (P_diag)->i;
  int* P_diag_j = (P_diag)->j;
  double* P_diag_data = (P_diag)->data;
  int* P_diag_j_new;
  double* P_diag_data_new;
  hypre_CSRMatrix* P_offd = (P)->offd;
  int* P_offd_i = (P_offd)->i;
  int* P_offd_j = (P_offd)->j;
  double* P_offd_data = (P_offd)->data;
  int* P_offd_j_new;
  double* P_offd_data_new;
  int n_fine = (P_diag)->num_rows;
  int num_cols = (P_diag)->num_cols;
  int i;
  int j;
  int start_j;
  int ierr = 0;
  double max_coef;
  int next_open = 0;
  int now_checking = 0;
  int next_open_offd = 0;
  int now_checking_offd = 0;
  int num_lost = 0;
  int num_lost_offd = 0;
  int num_lost_global = 0;
  int num_lost_global_offd = 0;
  int P_diag_size;
  int P_offd_size;
  int num_elmts;
  int cnt;
  int cnt_diag;
  int cnt_offd;
  double row_sum;
  double scale;
  int my_thread_num;
  int num_threads;
  int start;
  int stop;
  int* max_num_threads = (int*)(hypre_CAlloc((unsigned)1, (unsigned)(sizeof(int))));
  int* cum_lost_per_thread;
  int* num_lost_per_thread;
  int* num_lost_offd_per_thread;
  max_num_threads[0] = 1;
  cum_lost_per_thread = (int*)(hypre_CAlloc((unsigned)(max_num_threads[0]), (unsigned)(sizeof(int))));
  num_lost_per_thread = (int*)(hypre_CAlloc((unsigned)(max_num_threads[0]), (unsigned)(sizeof(int))));
  num_lost_offd_per_thread = (int*)(hypre_CAlloc((unsigned)(max_num_threads[0]), (unsigned)(sizeof(int))));
  for (i = 0; i < (max_num_threads[0]); i++) {
    num_lost_per_thread[i] = 0;
    num_lost_offd_per_thread[i] = 0;
  }
  {
    my_thread_num = 0;
    num_threads = 1;
    start = (n_fine / num_threads) * my_thread_num;
    if (my_thread_num == (num_threads - 1)) {
      stop = n_fine;
    }
    else {
      stop = (n_fine / num_threads) * (my_thread_num + 1);
    }
    if (trunc_factor > 0) {
      num_lost_offd = 0;
      next_open = P_diag_i[start];
      now_checking = P_diag_i[start];
      next_open_offd = P_offd_i[start];
      ;
      now_checking_offd = P_offd_i[start];
      ;
      for (i = start; i < stop; i++) {
        max_coef = 0;
        for (j = P_diag_i[i]; j < (P_diag_i[i + 1]); j++)
          max_coef = max_coef < fabs(P_diag_data[j]) ? fabs(P_diag_data[j]) : max_coef;
        for (j = P_offd_i[i]; j < (P_offd_i[i + 1]); j++)
          max_coef = max_coef < fabs(P_offd_data[j]) ? fabs(P_offd_data[j]) : max_coef;
        max_coef -= trunc_factor;
        start_j = P_diag_i[i];
        (P_diag_i[i]) -= num_lost;
        row_sum = 0;
        scale = 0;
        for (j = start_j; j < (P_diag_i[i + 1]); j++) {
          row_sum += P_diag_data[now_checking];
          if (fabs(P_diag_data[now_checking]) < max_coef) {
            num_lost++;
            now_checking++;
          }
          else {
            scale += P_diag_data[now_checking];
            P_diag_data[next_open] = P_diag_data[now_checking];
            P_diag_j[next_open] = P_diag_j[now_checking];
            now_checking++;
            next_open++;
          }
        }
        start_j = P_offd_i[i];
        (P_offd_i[i]) -= num_lost_offd;
        for (j = start_j; j < (P_offd_i[i + 1]); j++) {
          row_sum += P_offd_data[now_checking_offd];
          if (fabs(P_offd_data[now_checking_offd]) < max_coef) {
            num_lost_offd++;
            now_checking_offd++;
          }
          else {
            scale += P_offd_data[now_checking_offd];
            P_offd_data[next_open_offd] = P_offd_data[now_checking_offd];
            P_offd_j[next_open_offd] = P_offd_j[now_checking_offd];
            now_checking_offd++;
            next_open_offd++;
          }
        }
        if (scale != 0.) {
          if (scale != row_sum) {
            scale = row_sum / scale;
            for (j = P_diag_i[i]; j < ((P_diag_i[i + 1]) - num_lost); j++)
              (P_diag_data[j]) -= scale;
            for (j = P_offd_i[i]; j < ((P_offd_i[i + 1]) - num_lost_offd); j++)
              (P_offd_data[j]) -= scale;
          }
        }
      }
      if (my_thread_num == 0) {
        max_num_threads[0] = num_threads;
      }
      num_lost_per_thread[my_thread_num] = num_lost;
      num_lost_offd_per_thread[my_thread_num] = num_lost_offd;
    }
    if (max_elmts > 0) {
      int P_mxnum;
      int cnt1;
      int last_index;
      int last_index_offd;
      int* P_aux_j;
      double* P_aux_data;
      P_mxnum = 0;
      for (i = start; i < stop; i++) {
        last_index = P_diag_i[i + 1];
        last_index_offd = P_offd_i[i + 1];
        if (i == (stop - 1)) {
          last_index -= (num_lost_per_thread[my_thread_num]);
          last_index_offd -= (num_lost_offd_per_thread[my_thread_num]);
        }
        cnt1 = ((last_index - (P_diag_i[i])) + last_index_offd) - (P_offd_i[i]);
        if (cnt1 > P_mxnum)
          P_mxnum = cnt1;
      }
      if (P_mxnum > max_elmts) {
        num_lost = 0;
        num_lost_offd = 0;
        P_aux_j = (int*)(hypre_CAlloc((unsigned)P_mxnum, (unsigned)(sizeof(int))));
        P_aux_data = (double*)(hypre_CAlloc((unsigned)P_mxnum, (unsigned)(sizeof(double))));
        cnt_diag = P_diag_i[start];
        cnt_offd = P_offd_i[start];
        for (i = start; i < stop; i++) {
          last_index = P_diag_i[i + 1];
          last_index_offd = P_offd_i[i + 1];
          if (i == (stop - 1)) {
            last_index -= (num_lost_per_thread[my_thread_num]);
            last_index_offd -= (num_lost_offd_per_thread[my_thread_num]);
          }
          row_sum = 0;
          num_elmts = (((P_diag_i[i + 1]) - (P_diag_i[i])) + (P_offd_i[i + 1])) - (P_offd_i[i]);
          if (max_elmts < num_elmts) {
            cnt = 0;
            for (j = P_diag_i[i]; j < (P_diag_i[i + 1]); j++) {
              P_aux_j[cnt] = P_diag_j[j];
              P_aux_data[cnt++] = P_diag_data[j];
              row_sum += P_diag_data[j];
            }
            num_lost += cnt;
            cnt1 = cnt;
            for (j = P_offd_i[i]; j < (P_offd_i[i + 1]); j++) {
              P_aux_j[cnt] = (P_offd_j[j]) + num_cols;
              P_aux_data[cnt++] = P_offd_data[j];
              row_sum += P_offd_data[j];
            }
            num_lost_offd += cnt - cnt1;
            hypre_qsort2abs(P_aux_j, P_aux_data, 0, cnt - 1);
            scale = 0;
            P_diag_i[i] = cnt_diag;
            P_offd_i[i] = cnt_offd;
            for (j = 0; j < max_elmts; j++) {
              scale += P_aux_data[j];
              if ((P_aux_j[j]) < num_cols) {
                P_diag_j[cnt_diag] = P_aux_j[j];
                P_diag_data[cnt_diag++] = P_aux_data[j];
              }
              else {
                P_offd_j[cnt_offd] = (P_aux_j[j]) - num_cols;
                P_offd_data[cnt_offd++] = P_aux_data[j];
              }
            }
            num_lost -= (cnt_diag - (P_diag_i[i]));
            num_lost_offd -= (cnt_offd - (P_offd_i[i]));
            if (scale != 0.) {
              if (scale != row_sum) {
                scale = row_sum / scale;
                for (j = P_diag_i[i]; j < cnt_diag; j++)
                  (P_diag_data[j]) -= scale;
                for (j = P_offd_i[i]; j < cnt_offd; j++)
                  (P_offd_data[j]) -= scale;
              }
            }
          }
          else {
            if ((P_diag_i[i]) != cnt_diag) {
              start_j = P_diag_i[i];
              P_diag_i[i] = cnt_diag;
              for (j = start_j; j < (P_diag_i[i + 1]); j++) {
                P_diag_j[cnt_diag] = P_diag_j[j];
                P_diag_data[cnt_diag++] = P_diag_data[j];
              }
            }
            else
              cnt_diag += (P_diag_i[i + 1]) - (P_diag_i[i]);
            if ((P_offd_i[i]) != cnt_offd) {
              start_j = P_offd_i[i];
              P_offd_i[i] = cnt_offd;
              for (j = start_j; j < (P_offd_i[i + 1]); j++) {
                P_offd_j[cnt_offd] = P_offd_j[j];
                P_offd_data[cnt_offd++] = P_offd_data[j];
              }
            }
            else
              cnt_offd += (P_offd_i[i + 1]) - (P_offd_i[i]);
          }
        }
        num_lost_per_thread[my_thread_num] += num_lost;
        num_lost_offd_per_thread[my_thread_num] += num_lost_offd;
        hypre_Free((char*)P_aux_j), P_aux_j = (void*)0;
        hypre_Free((char*)P_aux_data), P_aux_data = (void*)0;
      }
    }
    if (my_thread_num == 0) {
      num_lost_global = 0;
      num_lost_global_offd = 0;
      for (i = 0; i < (max_num_threads[0]); i++) {
        num_lost_global += num_lost_per_thread[i];
        num_lost_global_offd += num_lost_offd_per_thread[i];
      }
    }
    if (num_lost_global) {
      if (my_thread_num == 0) {
        P_diag_size = P_diag_i[n_fine];
        for (i = 0; i < (max_num_threads[0]); i++) {
          P_diag_size -= (num_lost_per_thread[i]);
          if (i > 0) {
            cum_lost_per_thread[i] = (num_lost_per_thread[i]) + (cum_lost_per_thread[i - 1]);
          }
          else {
            cum_lost_per_thread[i] = num_lost_per_thread[i];
          }
        }
        P_diag_j_new = (int*)(hypre_CAlloc((unsigned)P_diag_size, (unsigned)(sizeof(int))));
        P_diag_data_new = (double*)(hypre_CAlloc((unsigned)P_diag_size, (unsigned)(sizeof(double))));
      }
      if (my_thread_num == 0) {
        next_open = 0;
      }
      else {
        next_open = (P_diag_i[start]) - (cum_lost_per_thread[my_thread_num - 1]);
      }
      for (i = P_diag_i[start]; i < ((P_diag_i[stop]) - (num_lost_per_thread[my_thread_num])); i++) {
        P_diag_j_new[next_open] = P_diag_j[i];
        P_diag_data_new[next_open] = P_diag_data[i];
        next_open += 1;
      }
      if (my_thread_num > 0) {
        for (i = start; i < stop; i++) {
          (P_diag_i[i]) -= (cum_lost_per_thread[my_thread_num - 1]);
        }
      }
      if (my_thread_num == 0) {
        P_diag_i[n_fine] = P_diag_size;
        hypre_Free((char*)P_diag_j), P_diag_j = (void*)0;
        hypre_Free((char*)P_diag_data), P_diag_data = (void*)0;
        (P_diag)->j = P_diag_j_new;
        (P_diag)->data = P_diag_data_new;
        (P_diag)->num_nonzeros = P_diag_size;
      }
    }
    if (num_lost_global_offd) {
      if (my_thread_num == 0) {
        P_offd_size = P_offd_i[n_fine];
        for (i = 0; i < (max_num_threads[0]); i++) {
          P_offd_size -= (num_lost_offd_per_thread[i]);
          if (i > 0) {
            cum_lost_per_thread[i] = (num_lost_offd_per_thread[i]) + (cum_lost_per_thread[i - 1]);
          }
          else {
            cum_lost_per_thread[i] = num_lost_offd_per_thread[i];
          }
        }
        P_offd_j_new = (int*)(hypre_CAlloc((unsigned)P_offd_size, (unsigned)(sizeof(int))));
        P_offd_data_new = (double*)(hypre_CAlloc((unsigned)P_offd_size, (unsigned)(sizeof(double))));
      }
      if (my_thread_num == 0) {
        next_open = 0;
      }
      else {
        next_open = (P_offd_i[start]) - (cum_lost_per_thread[my_thread_num - 1]);
      }
      for (i = P_offd_i[start]; i < ((P_offd_i[stop]) - (num_lost_offd_per_thread[my_thread_num])); i++) {
        P_offd_j_new[next_open] = P_offd_j[i];
        P_offd_data_new[next_open] = P_offd_data[i];
        next_open += 1;
      }
      if (my_thread_num > 0) {
        for (i = start; i < stop; i++) {
          (P_offd_i[i]) -= (cum_lost_per_thread[my_thread_num - 1]);
        }
      }
      if (my_thread_num == 0) {
        P_offd_i[n_fine] = P_offd_size;
        hypre_Free((char*)P_offd_j), P_offd_j = (void*)0;
        hypre_Free((char*)P_offd_data), P_offd_data = (void*)0;
        (P_offd)->j = P_offd_j_new;
        (P_offd)->data = P_offd_data_new;
        (P_offd)->num_nonzeros = P_offd_size;
      }
    }
  }
  hypre_Free((char*)max_num_threads), max_num_threads = (void*)0;
  hypre_Free((char*)cum_lost_per_thread), cum_lost_per_thread = (void*)0;
  hypre_Free((char*)num_lost_per_thread), num_lost_per_thread = (void*)0;
  hypre_Free((char*)num_lost_offd_per_thread), num_lost_offd_per_thread = (void*)0;
  return ierr;
}
void hypre_qsort2abs(int* v, double* w, int left, int right) {
  int i;
  int last;
  if (left >= right)
    return;
  swap2(v, w, left, (left + right) / 2);
  last = left;
  for (i = left + 1; i <= right; i++)
    if (fabs(w[i]) > fabs(w[left])) {
      swap2(v, w, ++last, i);
    }
  swap2(v, w, left, last);
  hypre_qsort2abs(v, w, left, last - 1);
  hypre_qsort2abs(v, w, last + 1, right);
}
//=================== par_jacobi_interp.c ==================
void hypre_BoomerAMGJacobiInterp(hypre_ParCSRMatrix* A, hypre_ParCSRMatrix** P, hypre_ParCSRMatrix* S, int num_functions, int* dof_func, int* CF_marker, int level, double truncation_threshold, double truncation_threshold_minus) {
  double weight_AF = 1.0;
  int* dof_func_offd = (void*)0;
  int nji = 1;
  int iji;
  hypre_ParCSRMatrix_dof_func_offd(A, num_functions, dof_func, &(dof_func_offd));
  for (iji = 0; iji < nji; ++iji) {
    hypre_BoomerAMGJacobiInterp_1(A, P, S, CF_marker, level, truncation_threshold, truncation_threshold_minus, dof_func, dof_func_offd, weight_AF);
  }
  if (dof_func_offd != (void*)0)
    hypre_Free((char*)dof_func_offd), dof_func_offd = (void*)0;
}
void hypre_BoomerAMGJacobiInterp_1(hypre_ParCSRMatrix* A, hypre_ParCSRMatrix** P, hypre_ParCSRMatrix* S, int* CF_marker, int level, double truncation_threshold, double truncation_threshold_minus, int* dof_func, int* dof_func_offd, double weight_AF) {
  hypre_ParCSRMatrix* Pnew;
  hypre_ParCSRMatrix* C;
  hypre_CSRMatrix* P_diag = (*P)->diag;
  hypre_CSRMatrix* P_offd = (*P)->offd;
  double* P_diag_data = (P_diag)->data;
  int* P_diag_i = (P_diag)->i;
  int* P_diag_j = (P_diag)->j;
  double* P_offd_data = (P_offd)->data;
  int* P_offd_i = (P_offd)->i;
  hypre_CSRMatrix* C_diag;
  hypre_CSRMatrix* C_offd;
  hypre_CSRMatrix* Pnew_diag;
  hypre_CSRMatrix* Pnew_offd;
  int num_rows_diag_P = (P_diag)->num_rows;
  int i;
  int Jnochanges = 0;
  int Jchanges;
  int Pnew_num_nonzeros;
  int CF_coarse = 0;
  int* J_marker = (int*)(hypre_CAlloc((unsigned)num_rows_diag_P, (unsigned)(sizeof(int))));
  int nc;
  int ncmax;
  int ncmin;
  int nc1;
  int num_procs;
  int my_id;
  MPI_Comm comm = (A)->comm;
  MPI_Comm_size(comm, &(num_procs));
  MPI_Comm_rank(comm, &(my_id));
  for (i = 0; i < num_rows_diag_P; ++i) {
    J_marker[i] = CF_marker[i];
    if ((CF_marker[i]) >= 0)
      ++CF_coarse;
  }
  ncmax = 0;
  ncmin = num_rows_diag_P;
  nc1 = 0;
  for (i = 0; i < num_rows_diag_P; ++i)
    if ((CF_marker[i]) < 0) {
      nc = (P_diag_i[i + 1]) - (P_diag_i[i]);
      if (nc <= 1) {
        ++nc1;
      }
      ncmax = nc < ncmax ? ncmax : nc;
      ncmin = nc < ncmin ? nc : ncmin;
    }
  Jchanges = (num_rows_diag_P - Jnochanges) - CF_coarse;
  C = hypre_ParMatmul_FC(A, *P, J_marker, dof_func, dof_func_offd);
  C_diag = (C)->diag;
  C_offd = (C)->offd;
  hypre_ParMatScaleDiagInv_F(C, A, weight_AF, J_marker);
  Pnew = hypre_ParMatMinus_F(*P, C, J_marker);
  Pnew_diag = (Pnew)->diag;
  Pnew_offd = (Pnew)->offd;
  Pnew_num_nonzeros = (Pnew_diag)->num_nonzeros + (Pnew_offd)->num_nonzeros;
  if ((*P)->col_starts && ((*P)->col_starts == (Pnew)->col_starts)) {
    if ((*P)->owns_col_starts && (!(Pnew)->owns_col_starts)) {
      hypre_ParCSRMatrixSetColStartsOwner(*P, 0);
      hypre_ParCSRMatrixSetColStartsOwner(Pnew, 1);
    }
  }
  hypre_ParCSRMatrixDestroy(C);
  hypre_ParCSRMatrixDestroy(*P);
  hypre_BoomerAMGTruncateInterp(Pnew, truncation_threshold, truncation_threshold_minus, CF_marker);
  hypre_MatvecCommPkgCreate(Pnew);
  *P = Pnew;
  P_diag = (*P)->diag;
  P_offd = (*P)->offd;
  P_diag_data = (P_diag)->data;
  P_diag_i = (P_diag)->i;
  P_diag_j = (P_diag)->j;
  P_offd_data = (P_offd)->data;
  P_offd_i = (P_offd)->i;
  ncmax = 0;
  ncmin = num_rows_diag_P;
  nc1 = 0;
  for (i = 0; i < num_rows_diag_P; ++i)
    if ((CF_marker[i]) < 0) {
      nc = (P_diag_i[i + 1]) - (P_diag_i[i]);
      if (nc <= 1)
        ++nc1;
      ncmax = nc < ncmax ? ncmax : nc;
      ncmin = nc < ncmin ? nc : ncmin;
    }
  hypre_Free((char*)J_marker), J_marker = (void*)0;
}
void hypre_BoomerAMGTruncateInterp(hypre_ParCSRMatrix* P, double eps, double dlt, int* CF_marker) {
  hypre_CSRMatrix* P_diag = (P)->diag;
  hypre_CSRMatrix* P_offd = (P)->offd;
  double* P_diag_data = (P_diag)->data;
  int* P_diag_i = (P_diag)->i;
  int* P_diag_j = (P_diag)->j;
  double* P_offd_data = (P_offd)->data;
  int* P_offd_i = (P_offd)->i;
  int* P_offd_j = (P_offd)->j;
  int* new_P_diag_i;
  int* new_P_offd_i;
  int num_rows_diag_P = (P_diag)->num_rows;
  int num_rows_offd_P = (P_offd)->num_rows;
  int num_nonzeros_diag = (P_diag)->num_nonzeros;
  int num_nonzeros_offd = (P_offd)->num_nonzeros;
  double vmax = 0.0;
  double vmin = 0.0;
  double v;
  double old_sum;
  double new_sum;
  double scale;
  double wmax;
  double wmin;
  int i1;
  int m;
  int m1d;
  int m1o;
  for (i1 = 0; i1 < num_rows_diag_P; i1++) {
    for (m = P_diag_i[i1]; m < (P_diag_i[i1 + 1]); ++m) {
      v = P_diag_data[m];
      vmax = v < vmax ? vmax : v;
      vmin = v < vmin ? v : vmin;
    }
    for (m = P_offd_i[i1]; m < (P_offd_i[i1 + 1]); ++m) {
      v = P_offd_data[m];
      vmax = v < vmax ? vmax : v;
      vmin = v < vmin ? v : vmin;
    }
  }
  if (vmax <= 0.0)
    vmax = 1.0;
  if (vmin >= 0.0)
    vmin = -1.0;
  wmax = (-dlt) * vmin;
  wmin = (-dlt) * vmax;
  vmax -= eps;
  vmin -= eps;
  new_P_diag_i = (int*)(hypre_CAlloc((unsigned)(num_rows_diag_P + 1), (unsigned)(sizeof(int))));
  new_P_offd_i = (int*)(hypre_CAlloc((unsigned)(num_rows_offd_P + 1), (unsigned)(sizeof(int))));
  m1d = P_diag_i[0];
  m1o = P_offd_i[0];
  for (i1 = 0; i1 < num_rows_diag_P; i1++) {
    old_sum = 0;
    new_sum = 0;
    for (m = P_diag_i[i1]; m < (P_diag_i[i1 + 1]); ++m) {
      v = P_diag_data[m];
      old_sum += v;
      if ((((CF_marker[i1]) >= 0) || ((v >= vmax) && (v >= wmax))) || ((v <= vmin) && (v <= wmin))) {
        new_sum += v;
        P_diag_j[m1d] = P_diag_j[m];
        P_diag_data[m1d] = P_diag_data[m];
        ++m1d;
      }
      else {
        --num_nonzeros_diag;
      }
    }
    for (m = P_offd_i[i1]; m < (P_offd_i[i1 + 1]); ++m) {
      v = P_offd_data[m];
      old_sum += v;
      if ((((CF_marker[i1]) >= 0) || ((v >= vmax) && (v >= wmax))) || ((v <= vmin) && (v <= wmin))) {
        new_sum += v;
        P_offd_j[m1o] = P_offd_j[m];
        P_offd_data[m1o] = P_offd_data[m];
        ++m1o;
      }
      else {
        --num_nonzeros_offd;
      }
    }
    new_P_diag_i[i1 + 1] = m1d;
    if (i1 < num_rows_offd_P)
      new_P_offd_i[i1 + 1] = m1o;
    if (new_sum != 0)
      scale = old_sum / new_sum;
    else
      scale = 1.0;
    for (m = new_P_diag_i[i1]; m < (new_P_diag_i[i1 + 1]); ++m)
      (P_diag_data[m]) -= scale;
    if (i1 < num_rows_offd_P)
      for (m = new_P_offd_i[i1]; m < (new_P_offd_i[i1 + 1]); ++m)
        (P_offd_data[m]) -= scale;
  }
  for (i1 = 1; i1 <= num_rows_diag_P; i1++) {
    P_diag_i[i1] = new_P_diag_i[i1];
    if ((i1 <= num_rows_offd_P) && (num_nonzeros_offd > 0))
      P_offd_i[i1] = new_P_offd_i[i1];
  }
  hypre_Free((char*)new_P_diag_i), new_P_diag_i = (void*)0;
  if (num_rows_offd_P > 0)
    hypre_Free((char*)new_P_offd_i), new_P_offd_i = (void*)0;
  (P_diag)->num_nonzeros = num_nonzeros_diag;
  (P_offd)->num_nonzeros = num_nonzeros_offd;
  hypre_ParCSRMatrixSetDNumNonzeros(P);
  hypre_ParCSRMatrixSetNumNonzeros(P);
}
int hypre_ParCSRMatrix_dof_func_offd(hypre_ParCSRMatrix* A, int num_functions, int* dof_func, int** dof_func_offd) {
  hypre_ParCSRCommPkg* comm_pkg = (A)->comm_pkg;
  hypre_ParCSRCommHandle* comm_handle;
  hypre_CSRMatrix* A_offd = (A)->offd;
  int num_cols_offd = 0;
  int Solve_err_flag = 0;
  int num_sends;
  int* int_buf_data;
  int index;
  int start;
  int i;
  int j;
  num_cols_offd = (A_offd)->num_cols;
  *dof_func_offd = (void*)0;
  if (num_cols_offd) {
    if (num_functions > 1)
      *dof_func_offd = (int*)(hypre_CAlloc((unsigned)num_cols_offd, (unsigned)(sizeof(int))));
  }
  if (!comm_pkg) {
    hypre_MatvecCommPkgCreate(A);
    comm_pkg = (A)->comm_pkg;
  }
  num_sends = (comm_pkg)->num_sends;
  if (num_functions > 1) {
    int_buf_data = (int*)(hypre_CAlloc((unsigned)((comm_pkg)->send_map_starts[num_sends]), (unsigned)(sizeof(int))));
    index = 0;
    for (i = 0; i < num_sends; i++) {
      start = (comm_pkg)->send_map_starts[i];
      for (j = start; j < ((comm_pkg)->send_map_starts[i + 1]); j++)
        int_buf_data[index++] = dof_func[(comm_pkg)->send_map_elmts[j]];
    }
    comm_handle = hypre_ParCSRCommHandleCreate(11, comm_pkg, int_buf_data, *dof_func_offd);
    hypre_ParCSRCommHandleDestroy(comm_handle);
    hypre_Free((char*)int_buf_data), int_buf_data = (void*)0;
  }
  return Solve_err_flag;
}
//====================== par_laplace.c =====================
HYPRE_ParCSRMatrix GenerateLaplacian(MPI_Comm comm, int nx, int ny, int nz, int P, int Q, int R, int p, int q, int r, double* value, HYPRE_ParVector* rhs_ptr, HYPRE_ParVector* x_ptr) {
  hypre_ParCSRMatrix* A;
  hypre_CSRMatrix* diag;
  hypre_CSRMatrix* offd;
  hypre_ParVector* par_rhs;
  hypre_ParVector* par_x;
  hypre_Vector* rhs;
  hypre_Vector* x;
  double* rhs_data;
  double* x_data;
  int* diag_i;
  int* diag_j;
  double* diag_data;
  int* offd_i;
  int* offd_j = (void*)0;
  double* offd_data = (void*)0;
  int* global_part;
  int* global_part_rhs;
  int* global_part_x;
  int* tmp_j = (void*)0;
  int ix;
  int iy;
  int iz;
  int cnt;
  int o_cnt;
  int local_num_rows;
  int* col_map_offd = (void*)0;
  int row_index;
  int i;
  int j;
  int ip;
  int iq;
  int ir;
  int nx_local;
  int ny_local;
  int nz_local;
  int num_cols_offd;
  int grid_size;
  int* nx_part;
  int* ny_part;
  int* nz_part;
  int num_procs;
  int my_id;
  int P_busy;
  int Q_busy;
  int R_busy;
  int nx_size;
  int ny_size;
  int nz_size;
  MPI_Comm_size(comm, &(num_procs));
  MPI_Comm_rank(comm, &(my_id));
  hypre_GeneratePartitioning(nx, P, &(nx_part));
  hypre_GeneratePartitioning(ny, Q, &(ny_part));
  hypre_GeneratePartitioning(nz, R, &(nz_part));
  global_part = (int*)(hypre_CAlloc((unsigned)(((P * Q) * R) + 1), (unsigned)(sizeof(int))));
  global_part_rhs = (int*)(hypre_CAlloc((unsigned)(((P * Q) * R) + 1), (unsigned)(sizeof(int))));
  global_part_x = (int*)(hypre_CAlloc((unsigned)(((P * Q) * R) + 1), (unsigned)(sizeof(int))));
  global_part[0] = 0;
  global_part_rhs[0] = 0;
  global_part_x[0] = 0;
  cnt = 1;
  for (iz = 0; iz < R; iz++) {
    nz_size = (int)((nz_part[iz + 1]) - (nz_part[iz]));
    for (iy = 0; iy < Q; iy++) {
      ny_size = (int)((ny_part[iy + 1]) - (ny_part[iy]));
      for (ix = 0; ix < P; ix++) {
        nx_size = (int)((nx_part[ix + 1]) - (nx_part[ix]));
        global_part[cnt] = global_part[cnt - 1];
        global_part[cnt] += (int)((nx_size * ny_size) * nz_size);
        global_part_x[cnt] = global_part[cnt];
        global_part_rhs[cnt] = global_part[cnt];
        cnt++;
      }
    }
  }
  nx_local = (int)((nx_part[p + 1]) - (nx_part[p]));
  ny_local = (int)((ny_part[q + 1]) - (ny_part[q]));
  nz_local = (int)((nz_part[r + 1]) - (nz_part[r]));
  local_num_rows = (nx_local * ny_local) * nz_local;
  ip = p;
  iq = q;
  ir = r;
  grid_size = (nx * ny) * nz;
  diag_i = (int*)(hypre_CAlloc((unsigned)(local_num_rows + 1), (unsigned)(sizeof(int))));
  offd_i = (int*)(hypre_CAlloc((unsigned)(local_num_rows + 1), (unsigned)(sizeof(int))));
  rhs_data = (double*)(hypre_CAlloc((unsigned)local_num_rows, (unsigned)(sizeof(double))));
  x_data = (double*)(hypre_CAlloc((unsigned)local_num_rows, (unsigned)(sizeof(double))));
  for (i = 0; i < local_num_rows; i++) {
    x_data[i] = 0.0;
    rhs_data[i] = 1.0;
  }
  P_busy = nx < P ? nx : P;
  Q_busy = ny < Q ? ny : Q;
  R_busy = nz < R ? nz : R;
  num_cols_offd = 0;
  if (p)
    num_cols_offd += ny_local * nz_local;
  if (p < (P_busy - 1))
    num_cols_offd += ny_local * nz_local;
  if (q)
    num_cols_offd += nx_local * nz_local;
  if (q < (Q_busy - 1))
    num_cols_offd += nx_local * nz_local;
  if (r)
    num_cols_offd += nx_local * ny_local;
  if (r < (R_busy - 1))
    num_cols_offd += nx_local * ny_local;
  if (!local_num_rows)
    num_cols_offd = 0;
  if (num_cols_offd) {
    col_map_offd = (int*)(hypre_CAlloc((unsigned)num_cols_offd, (unsigned)(sizeof(int))));
  }
  cnt = 1;
  o_cnt = 1;
  diag_i[0] = 0;
  offd_i[0] = 0;
  for (iz = 0; iz < nz_local; iz++) {
    for (iy = 0; iy < ny_local; iy++) {
      for (ix = 0; ix < nx_local; ix++) {
        diag_i[cnt] = diag_i[cnt - 1];
        offd_i[o_cnt] = offd_i[o_cnt - 1];
        diag_i[cnt]++;
        if (iz)
          diag_i[cnt]++;
        else {
          if (ir) {
            offd_i[o_cnt]++;
          }
        }
        if (iy)
          diag_i[cnt]++;
        else {
          if (iq) {
            offd_i[o_cnt]++;
          }
        }
        if (ix)
          diag_i[cnt]++;
        else {
          if (ip) {
            offd_i[o_cnt]++;
          }
        }
        if ((ix + 1) < nx_local)
          diag_i[cnt]++;
        else {
          if ((ip + 1) < P) {
            offd_i[o_cnt]++;
          }
        }
        if ((iy + 1) < ny_local)
          diag_i[cnt]++;
        else {
          if ((iq + 1) < Q) {
            offd_i[o_cnt]++;
          }
        }
        if ((iz + 1) < nz_local)
          diag_i[cnt]++;
        else {
          if ((ir + 1) < R) {
            offd_i[o_cnt]++;
          }
        }
        cnt++;
        o_cnt++;
      }
    }
  }
  diag_j = (int*)(hypre_CAlloc((unsigned)(diag_i[local_num_rows]), (unsigned)(sizeof(int))));
  diag_data = (double*)(hypre_CAlloc((unsigned)(diag_i[local_num_rows]), (unsigned)(sizeof(double))));
  if (num_procs > 1) {
    offd_j = (int*)(hypre_CAlloc((unsigned)(offd_i[local_num_rows]), (unsigned)(sizeof(int))));
    offd_data = (double*)(hypre_CAlloc((unsigned)(offd_i[local_num_rows]), (unsigned)(sizeof(double))));
  }
  row_index = 0;
  cnt = 0;
  o_cnt = 0;
  for (iz = 0; iz < nz_local; iz++) {
    for (iy = 0; iy < ny_local; iy++) {
      for (ix = 0; ix < nx_local; ix++) {
        diag_j[cnt] = row_index;
        diag_data[cnt++] = value[0];
        if (iz) {
          diag_j[cnt] = row_index - (nx_local * ny_local);
          diag_data[cnt++] = value[3];
        }
        else {
          if (ir) {
            offd_j[o_cnt] = o_cnt;
            hypre_map(ix, iy, iz - 1, p, q, r - 1, P, Q, R, nx_part, ny_part, nz_part, global_part, &(col_map_offd[o_cnt]));
            offd_data[o_cnt++] = value[3];
          }
        }
        if (iy) {
          diag_j[cnt] = row_index - nx_local;
          diag_data[cnt++] = value[2];
        }
        else {
          if (iq) {
            offd_j[o_cnt] = o_cnt;
            hypre_map(ix, iy - 1, iz, p, q - 1, r, P, Q, R, nx_part, ny_part, nz_part, global_part, &(col_map_offd[o_cnt]));
            offd_data[o_cnt++] = value[2];
          }
        }
        if (ix) {
          diag_j[cnt] = row_index - 1;
          diag_data[cnt++] = value[1];
        }
        else {
          if (ip) {
            offd_j[o_cnt] = o_cnt;
            hypre_map(ix - 1, iy, iz, p - 1, q, r, P, Q, R, nx_part, ny_part, nz_part, global_part, &(col_map_offd[o_cnt]));
            offd_data[o_cnt++] = value[1];
          }
        }
        if ((ix + 1) < nx_local) {
          diag_j[cnt] = row_index + 1;
          diag_data[cnt++] = value[1];
        }
        else {
          if ((ip + 1) < P) {
            offd_j[o_cnt] = o_cnt;
            hypre_map(ix + 1, iy, iz, p + 1, q, r, P, Q, R, nx_part, ny_part, nz_part, global_part, &(col_map_offd[o_cnt]));
            offd_data[o_cnt++] = value[1];
          }
        }
        if ((iy + 1) < ny_local) {
          diag_j[cnt] = row_index + nx_local;
          diag_data[cnt++] = value[2];
        }
        else {
          if ((iq + 1) < Q) {
            offd_j[o_cnt] = o_cnt;
            hypre_map(ix, iy + 1, iz, p, q + 1, r, P, Q, R, nx_part, ny_part, nz_part, global_part, &(col_map_offd[o_cnt]));
            offd_data[o_cnt++] = value[2];
          }
        }
        if ((iz + 1) < nz_local) {
          diag_j[cnt] = row_index + (nx_local * ny_local);
          diag_data[cnt++] = value[3];
        }
        else {
          if ((ir + 1) < R) {
            offd_j[o_cnt] = o_cnt;
            hypre_map(ix, iy, iz + 1, p, q, r + 1, P, Q, R, nx_part, ny_part, nz_part, global_part, &(col_map_offd[o_cnt]));
            offd_data[o_cnt++] = value[3];
          }
        }
        row_index++;
      }
    }
  }
  if (num_cols_offd)
    tmp_j = (int*)(hypre_CAlloc((unsigned)num_cols_offd, (unsigned)(sizeof(int))));
  for (i = 0; i < num_cols_offd; i++)
    tmp_j[i] = offd_j[i];
  if (num_procs > 1) {
    hypre_BigQsortbi(col_map_offd, tmp_j, 0, num_cols_offd - 1);
    for (i = 0; i < num_cols_offd; i++)
      for (j = 0; j < num_cols_offd; j++)
        if ((offd_j[i]) == (tmp_j[j])) {
          offd_j[i] = j;
          break;
        }
  }
  hypre_Free((char*)tmp_j), tmp_j = (void*)0;
  A = hypre_ParCSRMatrixCreate(comm, grid_size, grid_size, global_part, global_part, num_cols_offd, diag_i[local_num_rows], offd_i[local_num_rows]);
  par_rhs = hypre_ParVectorCreate(comm, grid_size, global_part_rhs);
  rhs = (par_rhs)->local_vector;
  (rhs)->data = rhs_data;
  par_x = hypre_ParVectorCreate(comm, grid_size, global_part_x);
  x = (par_x)->local_vector;
  (x)->data = x_data;
  (A)->col_map_offd = col_map_offd;
  diag = (A)->diag;
  (diag)->i = diag_i;
  (diag)->j = diag_j;
  (diag)->data = diag_data;
  offd = (A)->offd;
  (offd)->i = offd_i;
  if (num_cols_offd) {
    (offd)->j = offd_j;
    (offd)->data = offd_data;
  }
  hypre_Free((char*)nx_part), nx_part = (void*)0;
  hypre_Free((char*)ny_part), ny_part = (void*)0;
  hypre_Free((char*)nz_part), nz_part = (void*)0;
  *rhs_ptr = (HYPRE_ParVector)par_rhs;
  *x_ptr = (HYPRE_ParVector)par_x;
  return (HYPRE_ParCSRMatrix)A;
}
int hypre_map(int ix, int iy, int iz, int p, int q, int r, int P, int Q, int R, int* nx_part, int* ny_part, int* nz_part, int* global_part, int* value_ptr) {
  int nx_local;
  int ny_local;
  int nz_local;
  int global_index;
  int proc_num;
  proc_num = (((r * P) * Q) + (q * P)) + p;
  nx_local = (int)((nx_part[p + 1]) - (nx_part[p]));
  ny_local = (int)((ny_part[q + 1]) - (ny_part[q]));
  nz_local = (int)((nz_part[r + 1]) - (nz_part[r]));
  if (ix < 0)
    ix += nx_local;
  if (ix >= nx_local)
    ix = 0;
  if (iy < 0)
    iy += ny_local;
  if (iy >= ny_local)
    iy = 0;
  if (iz < 0)
    iz += nz_local;
  if (iz >= nz_local)
    iz = 0;
  global_index = (global_part[proc_num]) + (int)((((iz * ny_local) + iy) * nx_local) + ix);
  *value_ptr = global_index;
  return 0;
}
//=================== par_laplace_27pt.c ===================
HYPRE_ParCSRMatrix GenerateLaplacian27pt(MPI_Comm comm, int nx, int ny, int nz, int P, int Q, int R, int p, int q, int r, double* value, HYPRE_ParVector* rhs_ptr, HYPRE_ParVector* x_ptr) {
  hypre_ParCSRMatrix* A;
  hypre_CSRMatrix* diag;
  hypre_CSRMatrix* offd;
  hypre_ParVector* par_rhs;
  hypre_ParVector* par_x;
  hypre_Vector* rhs;
  hypre_Vector* x;
  double* rhs_data;
  double* x_data;
  int* diag_i;
  int* diag_j;
  double* diag_data;
  int* offd_i;
  int* offd_j = (void*)0;
  double* offd_data = (void*)0;
  int* global_part;
  int* global_part_rhs;
  int* global_part_x;
  int ix;
  int iy;
  int iz;
  int cnt;
  int o_cnt;
  int local_num_rows;
  int* col_map_offd;
  int* work;
  int row_index;
  int i;
  int ip;
  int iq;
  int ir;
  int nx_local;
  int ny_local;
  int nz_local;
  int num_cols_offd;
  int nxy;
  int grid_size;
  int* nx_part;
  int* ny_part;
  int* nz_part;
  int num_procs;
  int my_id;
  int P_busy;
  int Q_busy;
  int R_busy;
  int nx_size;
  int ny_size;
  int nz_size;
  MPI_Comm_size(comm, &(num_procs));
  MPI_Comm_rank(comm, &(my_id));
  hypre_GeneratePartitioning(nx, P, &(nx_part));
  hypre_GeneratePartitioning(ny, Q, &(ny_part));
  hypre_GeneratePartitioning(nz, R, &(nz_part));
  global_part = (int*)(hypre_CAlloc((unsigned)(((P * Q) * R) + 1), (unsigned)(sizeof(int))));
  global_part_rhs = (int*)(hypre_CAlloc((unsigned)(((P * Q) * R) + 1), (unsigned)(sizeof(int))));
  global_part_x = (int*)(hypre_CAlloc((unsigned)(((P * Q) * R) + 1), (unsigned)(sizeof(int))));
  global_part[0] = 0;
  global_part_rhs[0] = 0;
  global_part_x[0] = 0;
  cnt = 1;
  for (iz = 0; iz < R; iz++) {
    nz_size = (int)((nz_part[iz + 1]) - (nz_part[iz]));
    for (iy = 0; iy < Q; iy++) {
      ny_size = (int)((ny_part[iy + 1]) - (ny_part[iy]));
      for (ix = 0; ix < P; ix++) {
        nx_size = (int)((nx_part[ix + 1]) - (nx_part[ix]));
        global_part[cnt] = global_part[cnt - 1];
        global_part[cnt] += (int)((nx_size * ny_size) * nz_size);
        global_part_rhs[cnt] = global_part[cnt];
        global_part_x[cnt] = global_part[cnt];
        cnt++;
      }
    }
  }
  nx_local = (int)((nx_part[p + 1]) - (nx_part[p]));
  ny_local = (int)((ny_part[q + 1]) - (ny_part[q]));
  nz_local = (int)((nz_part[r + 1]) - (nz_part[r]));
  local_num_rows = (nx_local * ny_local) * nz_local;
  ip = p;
  iq = q;
  ir = r;
  grid_size = (nx * ny) * nz;
  diag_i = (int*)(hypre_CAlloc((unsigned)(local_num_rows + 1), (unsigned)(sizeof(int))));
  offd_i = (int*)(hypre_CAlloc((unsigned)(local_num_rows + 1), (unsigned)(sizeof(int))));
  rhs_data = (double*)(hypre_CAlloc((unsigned)local_num_rows, (unsigned)(sizeof(double))));
  x_data = (double*)(hypre_CAlloc((unsigned)local_num_rows, (unsigned)(sizeof(double))));
  for (i = 0; i < local_num_rows; i++) {
    rhs_data[i] = 1.0;
    x_data[i] = 0.0;
  }
  P_busy = nx < P ? nx : P;
  Q_busy = ny < Q ? ny : Q;
  R_busy = nz < R ? nz : R;
  num_cols_offd = 0;
  if (p)
    num_cols_offd += ny_local * nz_local;
  if (p < (P_busy - 1))
    num_cols_offd += ny_local * nz_local;
  if (q)
    num_cols_offd += nx_local * nz_local;
  if (q < (Q_busy - 1))
    num_cols_offd += nx_local * nz_local;
  if (r)
    num_cols_offd += nx_local * ny_local;
  if (r < (R_busy - 1))
    num_cols_offd += nx_local * ny_local;
  if (p && q)
    num_cols_offd += nz_local;
  if (p && (q < (Q_busy - 1)))
    num_cols_offd += nz_local;
  if ((p < (P_busy - 1)) && q)
    num_cols_offd += nz_local;
  if ((p < (P_busy - 1)) && (q < (Q_busy - 1)))
    num_cols_offd += nz_local;
  if (p && r)
    num_cols_offd += ny_local;
  if (p && (r < (R_busy - 1)))
    num_cols_offd += ny_local;
  if ((p < (P_busy - 1)) && r)
    num_cols_offd += ny_local;
  if ((p < (P_busy - 1)) && (r < (R_busy - 1)))
    num_cols_offd += ny_local;
  if (q && r)
    num_cols_offd += nx_local;
  if (q && (r < (R_busy - 1)))
    num_cols_offd += nx_local;
  if ((q < (Q_busy - 1)) && r)
    num_cols_offd += nx_local;
  if ((q < (Q_busy - 1)) && (r < (R_busy - 1)))
    num_cols_offd += nx_local;
  if ((p && q) && r)
    num_cols_offd++;
  if ((p && q) && (r < (R_busy - 1)))
    num_cols_offd++;
  if ((p && (q < (Q_busy - 1))) && r)
    num_cols_offd++;
  if ((p && (q < (Q_busy - 1))) && (r < (R_busy - 1)))
    num_cols_offd++;
  if (((p < (P_busy - 1)) && q) && r)
    num_cols_offd++;
  if (((p < (P_busy - 1)) && q) && (r < (R_busy - 1)))
    num_cols_offd++;
  if (((p < (P_busy - 1)) && (q < (Q_busy - 1))) && r)
    num_cols_offd++;
  if (((p < (P_busy - 1)) && (q < (Q_busy - 1))) && (r < (R_busy - 1)))
    num_cols_offd++;
  if (!local_num_rows)
    num_cols_offd = 0;
  col_map_offd = (int*)(hypre_CAlloc((unsigned)num_cols_offd, (unsigned)(sizeof(int))));
  cnt = 0;
  o_cnt = 0;
  diag_i[0] = 0;
  offd_i[0] = 0;
  for (iz = 0; iz < nz_local; iz++) {
    for (iy = 0; iy < ny_local; iy++) {
      for (ix = 0; ix < nx_local; ix++) {
        cnt++;
        o_cnt++;
        diag_i[cnt] = diag_i[cnt - 1];
        offd_i[o_cnt] = offd_i[o_cnt - 1];
        diag_i[cnt]++;
        if (iz > 0) {
          diag_i[cnt]++;
          if (iy > 0) {
            diag_i[cnt]++;
            if (ix > 0) {
              diag_i[cnt]++;
            }
            else {
              if (ip)
                offd_i[o_cnt]++;
            }
            if (ix < (nx_local - 1)) {
              diag_i[cnt]++;
            }
            else {
              if ((ip + 1) < P)
                offd_i[o_cnt]++;
            }
          }
          else {
            if (iq) {
              offd_i[o_cnt]++;
              if (ix > 0) {
                offd_i[o_cnt]++;
              }
              else
                if (ip) {
                  offd_i[o_cnt]++;
                }
              if (ix < (nx_local - 1)) {
                offd_i[o_cnt]++;
              }
              else
                if (ip < (P - 1)) {
                  offd_i[o_cnt]++;
                }
            }
          }
          if (ix > 0)
            diag_i[cnt]++;
          else {
            if (ip) {
              offd_i[o_cnt]++;
            }
          }
          if ((ix + 1) < nx_local)
            diag_i[cnt]++;
          else {
            if ((ip + 1) < P) {
              offd_i[o_cnt]++;
            }
          }
          if ((iy + 1) < ny_local) {
            diag_i[cnt]++;
            if (ix > 0) {
              diag_i[cnt]++;
            }
            else {
              if (ip)
                offd_i[o_cnt]++;
            }
            if (ix < (nx_local - 1)) {
              diag_i[cnt]++;
            }
            else {
              if ((ip + 1) < P)
                offd_i[o_cnt]++;
            }
          }
          else {
            if ((iq + 1) < Q) {
              offd_i[o_cnt]++;
              if (ix > 0) {
                offd_i[o_cnt]++;
              }
              else
                if (ip) {
                  offd_i[o_cnt]++;
                }
              if (ix < (nx_local - 1)) {
                offd_i[o_cnt]++;
              }
              else
                if (ip < (P - 1)) {
                  offd_i[o_cnt]++;
                }
            }
          }
        }
        else {
          if (ir) {
            offd_i[o_cnt]++;
            if (iy > 0) {
              offd_i[o_cnt]++;
              if (ix > 0) {
                offd_i[o_cnt]++;
              }
              else {
                if (ip)
                  offd_i[o_cnt]++;
              }
              if (ix < (nx_local - 1)) {
                offd_i[o_cnt]++;
              }
              else {
                if ((ip + 1) < P)
                  offd_i[o_cnt]++;
              }
            }
            else {
              if (iq) {
                offd_i[o_cnt]++;
                if (ix > 0) {
                  offd_i[o_cnt]++;
                }
                else
                  if (ip) {
                    offd_i[o_cnt]++;
                  }
                if (ix < (nx_local - 1)) {
                  offd_i[o_cnt]++;
                }
                else
                  if (ip < (P - 1)) {
                    offd_i[o_cnt]++;
                  }
              }
            }
            if (ix > 0)
              offd_i[o_cnt]++;
            else {
              if (ip) {
                offd_i[o_cnt]++;
              }
            }
            if ((ix + 1) < nx_local)
              offd_i[o_cnt]++;
            else {
              if ((ip + 1) < P) {
                offd_i[o_cnt]++;
              }
            }
            if ((iy + 1) < ny_local) {
              offd_i[o_cnt]++;
              if (ix > 0) {
                offd_i[o_cnt]++;
              }
              else {
                if (ip)
                  offd_i[o_cnt]++;
              }
              if (ix < (nx_local - 1)) {
                offd_i[o_cnt]++;
              }
              else {
                if ((ip + 1) < P)
                  offd_i[o_cnt]++;
              }
            }
            else {
              if ((iq + 1) < Q) {
                offd_i[o_cnt]++;
                if (ix > 0) {
                  offd_i[o_cnt]++;
                }
                else
                  if (ip) {
                    offd_i[o_cnt]++;
                  }
                if (ix < (nx_local - 1)) {
                  offd_i[o_cnt]++;
                }
                else
                  if (ip < (P - 1)) {
                    offd_i[o_cnt]++;
                  }
              }
            }
          }
        }
        if (iy > 0) {
          diag_i[cnt]++;
          if (ix > 0) {
            diag_i[cnt]++;
          }
          else {
            if (ip)
              offd_i[o_cnt]++;
          }
          if (ix < (nx_local - 1)) {
            diag_i[cnt]++;
          }
          else {
            if ((ip + 1) < P)
              offd_i[o_cnt]++;
          }
        }
        else {
          if (iq) {
            offd_i[o_cnt]++;
            if (ix > 0) {
              offd_i[o_cnt]++;
            }
            else
              if (ip) {
                offd_i[o_cnt]++;
              }
            if (ix < (nx_local - 1)) {
              offd_i[o_cnt]++;
            }
            else
              if (ip < (P - 1)) {
                offd_i[o_cnt]++;
              }
          }
        }
        if (ix > 0)
          diag_i[cnt]++;
        else {
          if (ip) {
            offd_i[o_cnt]++;
          }
        }
        if ((ix + 1) < nx_local)
          diag_i[cnt]++;
        else {
          if ((ip + 1) < P) {
            offd_i[o_cnt]++;
          }
        }
        if ((iy + 1) < ny_local) {
          diag_i[cnt]++;
          if (ix > 0) {
            diag_i[cnt]++;
          }
          else {
            if (ip)
              offd_i[o_cnt]++;
          }
          if (ix < (nx_local - 1)) {
            diag_i[cnt]++;
          }
          else {
            if ((ip + 1) < P)
              offd_i[o_cnt]++;
          }
        }
        else {
          if ((iq + 1) < Q) {
            offd_i[o_cnt]++;
            if (ix > 0) {
              offd_i[o_cnt]++;
            }
            else
              if (ip) {
                offd_i[o_cnt]++;
              }
            if (ix < (nx_local - 1)) {
              offd_i[o_cnt]++;
            }
            else
              if (ip < (P - 1)) {
                offd_i[o_cnt]++;
              }
          }
        }
        if ((iz + 1) < nz_local) {
          diag_i[cnt]++;
          if (iy > 0) {
            diag_i[cnt]++;
            if (ix > 0) {
              diag_i[cnt]++;
            }
            else {
              if (ip)
                offd_i[o_cnt]++;
            }
            if (ix < (nx_local - 1)) {
              diag_i[cnt]++;
            }
            else {
              if ((ip + 1) < P)
                offd_i[o_cnt]++;
            }
          }
          else {
            if (iq) {
              offd_i[o_cnt]++;
              if (ix > 0) {
                offd_i[o_cnt]++;
              }
              else
                if (ip) {
                  offd_i[o_cnt]++;
                }
              if (ix < (nx_local - 1)) {
                offd_i[o_cnt]++;
              }
              else
                if (ip < (P - 1)) {
                  offd_i[o_cnt]++;
                }
            }
          }
          if (ix > 0)
            diag_i[cnt]++;
          else {
            if (ip) {
              offd_i[o_cnt]++;
            }
          }
          if ((ix + 1) < nx_local)
            diag_i[cnt]++;
          else {
            if ((ip + 1) < P) {
              offd_i[o_cnt]++;
            }
          }
          if ((iy + 1) < ny_local) {
            diag_i[cnt]++;
            if (ix > 0) {
              diag_i[cnt]++;
            }
            else {
              if (ip)
                offd_i[o_cnt]++;
            }
            if (ix < (nx_local - 1)) {
              diag_i[cnt]++;
            }
            else {
              if ((ip + 1) < P)
                offd_i[o_cnt]++;
            }
          }
          else {
            if ((iq + 1) < Q) {
              offd_i[o_cnt]++;
              if (ix > 0) {
                offd_i[o_cnt]++;
              }
              else
                if (ip) {
                  offd_i[o_cnt]++;
                }
              if (ix < (nx_local - 1)) {
                offd_i[o_cnt]++;
              }
              else
                if (ip < (P - 1)) {
                  offd_i[o_cnt]++;
                }
            }
          }
        }
        else {
          if ((ir + 1) < R) {
            offd_i[o_cnt]++;
            if (iy > 0) {
              offd_i[o_cnt]++;
              if (ix > 0) {
                offd_i[o_cnt]++;
              }
              else {
                if (ip)
                  offd_i[o_cnt]++;
              }
              if (ix < (nx_local - 1)) {
                offd_i[o_cnt]++;
              }
              else {
                if ((ip + 1) < P)
                  offd_i[o_cnt]++;
              }
            }
            else {
              if (iq) {
                offd_i[o_cnt]++;
                if (ix > 0) {
                  offd_i[o_cnt]++;
                }
                else
                  if (ip) {
                    offd_i[o_cnt]++;
                  }
                if (ix < (nx_local - 1)) {
                  offd_i[o_cnt]++;
                }
                else
                  if (ip < (P - 1)) {
                    offd_i[o_cnt]++;
                  }
              }
            }
            if (ix > 0)
              offd_i[o_cnt]++;
            else {
              if (ip) {
                offd_i[o_cnt]++;
              }
            }
            if ((ix + 1) < nx_local)
              offd_i[o_cnt]++;
            else {
              if ((ip + 1) < P) {
                offd_i[o_cnt]++;
              }
            }
            if ((iy + 1) < ny_local) {
              offd_i[o_cnt]++;
              if (ix > 0) {
                offd_i[o_cnt]++;
              }
              else {
                if (ip)
                  offd_i[o_cnt]++;
              }
              if (ix < (nx_local - 1)) {
                offd_i[o_cnt]++;
              }
              else {
                if ((ip + 1) < P)
                  offd_i[o_cnt]++;
              }
            }
            else {
              if ((iq + 1) < Q) {
                offd_i[o_cnt]++;
                if (ix > 0) {
                  offd_i[o_cnt]++;
                }
                else
                  if (ip) {
                    offd_i[o_cnt]++;
                  }
                if (ix < (nx_local - 1)) {
                  offd_i[o_cnt]++;
                }
                else
                  if (ip < (P - 1)) {
                    offd_i[o_cnt]++;
                  }
              }
            }
          }
        }
      }
    }
  }
  diag_j = (int*)(hypre_CAlloc((unsigned)(diag_i[local_num_rows]), (unsigned)(sizeof(int))));
  diag_data = (double*)(hypre_CAlloc((unsigned)(diag_i[local_num_rows]), (unsigned)(sizeof(double))));
  if (num_procs > 1) {
    work = (int*)(hypre_CAlloc((unsigned)(offd_i[local_num_rows]), (unsigned)(sizeof(int))));
    offd_j = (int*)(hypre_CAlloc((unsigned)(offd_i[local_num_rows]), (unsigned)(sizeof(int))));
    offd_data = (double*)(hypre_CAlloc((unsigned)(offd_i[local_num_rows]), (unsigned)(sizeof(double))));
  }
  nxy = nx_local * ny_local;
  row_index = 0;
  cnt = 0;
  o_cnt = 0;
  for (iz = 0; iz < nz_local; iz++) {
    for (iy = 0; iy < ny_local; iy++) {
      for (ix = 0; ix < nx_local; ix++) {
        diag_j[cnt] = row_index;
        diag_data[cnt++] = value[0];
        if (iz > 0) {
          if (iy > 0) {
            if (ix > 0) {
              diag_j[cnt] = ((row_index - nxy) - nx_local) - 1;
              diag_data[cnt++] = value[1];
            }
            else {
              if (ip) {
                hypre_map(ix - 1, iy - 1, iz - 1, p - 1, q, r, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                offd_data[o_cnt++] = value[1];
              }
            }
            diag_j[cnt] = (row_index - nxy) - nx_local;
            diag_data[cnt++] = value[1];
            if (ix < (nx_local - 1)) {
              diag_j[cnt] = ((row_index - nxy) - nx_local) + 1;
              diag_data[cnt++] = value[1];
            }
            else {
              if ((ip + 1) < P) {
                hypre_map(ix + 1, iy - 1, iz - 1, p + 1, q, r, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                offd_data[o_cnt++] = value[1];
              }
            }
          }
          else {
            if (iq) {
              if (ix > 0) {
                hypre_map(ix - 1, iy - 1, iz - 1, p, q - 1, r, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                offd_data[o_cnt++] = value[1];
              }
              else
                if (ip) {
                  hypre_map(ix - 1, iy - 1, iz - 1, p - 1, q - 1, r, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                  offd_data[o_cnt++] = value[1];
                }
              hypre_map(ix, iy - 1, iz - 1, p, q - 1, r, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
              offd_data[o_cnt++] = value[1];
              if (ix < (nx_local - 1)) {
                hypre_map(ix + 1, iy - 1, iz - 1, p, q - 1, r, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                offd_data[o_cnt++] = value[1];
              }
              else
                if (ip < (P - 1)) {
                  hypre_map(ix + 1, iy - 1, iz - 1, p + 1, q - 1, r, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                  offd_data[o_cnt++] = value[1];
                }
            }
          }
          if (ix > 0) {
            diag_j[cnt] = (row_index - nxy) - 1;
            diag_data[cnt++] = value[1];
          }
          else {
            if (ip) {
              hypre_map(ix - 1, iy, iz - 1, p - 1, q, r, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
              offd_data[o_cnt++] = value[1];
            }
          }
          diag_j[cnt] = row_index - nxy;
          diag_data[cnt++] = value[1];
          if ((ix + 1) < nx_local) {
            diag_j[cnt] = (row_index - nxy) + 1;
            diag_data[cnt++] = value[1];
          }
          else {
            if ((ip + 1) < P) {
              hypre_map(ix + 1, iy, iz - 1, p + 1, q, r, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
              offd_data[o_cnt++] = value[1];
            }
          }
          if ((iy + 1) < ny_local) {
            if (ix > 0) {
              diag_j[cnt] = ((row_index - nxy) + nx_local) - 1;
              diag_data[cnt++] = value[1];
            }
            else {
              if (ip) {
                hypre_map(ix - 1, iy + 1, iz - 1, p - 1, q, r, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                offd_data[o_cnt++] = value[1];
              }
            }
            diag_j[cnt] = (row_index - nxy) + nx_local;
            diag_data[cnt++] = value[1];
            if (ix < (nx_local - 1)) {
              diag_j[cnt] = ((row_index - nxy) + nx_local) + 1;
              diag_data[cnt++] = value[1];
            }
            else {
              if ((ip + 1) < P) {
                hypre_map(ix + 1, iy + 1, iz - 1, p + 1, q, r, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                offd_data[o_cnt++] = value[1];
              }
            }
          }
          else {
            if ((iq + 1) < Q) {
              if (ix > 0) {
                hypre_map(ix - 1, iy + 1, iz - 1, p, q + 1, r, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                offd_data[o_cnt++] = value[1];
              }
              else
                if (ip) {
                  hypre_map(ix - 1, iy + 1, iz - 1, p - 1, q + 1, r, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                  offd_data[o_cnt++] = value[1];
                }
              hypre_map(ix, iy + 1, iz - 1, p, q + 1, r, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
              offd_data[o_cnt++] = value[1];
              if (ix < (nx_local - 1)) {
                hypre_map(ix + 1, iy + 1, iz - 1, p, q + 1, r, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                offd_data[o_cnt++] = value[1];
              }
              else
                if (ip < (P - 1)) {
                  hypre_map(ix + 1, iy + 1, iz - 1, p + 1, q + 1, r, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                  offd_data[o_cnt++] = value[1];
                }
            }
          }
        }
        else {
          if (ir) {
            if (iy > 0) {
              if (ix > 0) {
                hypre_map(ix - 1, iy - 1, iz - 1, p, q, r - 1, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                offd_data[o_cnt++] = value[1];
              }
              else {
                if (ip) {
                  hypre_map(ix - 1, iy - 1, iz - 1, p - 1, q, r - 1, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                  offd_data[o_cnt++] = value[1];
                }
              }
              hypre_map(ix, iy - 1, iz - 1, p, q, r - 1, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
              offd_data[o_cnt++] = value[1];
              if (ix < (nx_local - 1)) {
                hypre_map(ix + 1, iy - 1, iz - 1, p, q, r - 1, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                offd_data[o_cnt++] = value[1];
              }
              else {
                if ((ip + 1) < P) {
                  hypre_map(ix + 1, iy - 1, iz - 1, p + 1, q, r - 1, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                  offd_data[o_cnt++] = value[1];
                }
              }
            }
            else {
              if (iq) {
                if (ix > 0) {
                  hypre_map(ix - 1, iy - 1, iz - 1, p, q - 1, r - 1, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                  offd_data[o_cnt++] = value[1];
                }
                else
                  if (ip) {
                    hypre_map(ix - 1, iy - 1, iz - 1, p - 1, q - 1, r - 1, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                    offd_data[o_cnt++] = value[1];
                  }
                hypre_map(ix, iy - 1, iz - 1, p, q - 1, r - 1, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                offd_data[o_cnt++] = value[1];
                if (ix < (nx_local - 1)) {
                  hypre_map(ix + 1, iy - 1, iz - 1, p, q - 1, r - 1, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                  offd_data[o_cnt++] = value[1];
                }
                else
                  if (ip < (P - 1)) {
                    hypre_map(ix + 1, iy - 1, iz - 1, p + 1, q - 1, r - 1, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                    offd_data[o_cnt++] = value[1];
                  }
              }
            }
            if (ix > 0) {
              hypre_map(ix - 1, iy, iz - 1, p, q, r - 1, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
              offd_data[o_cnt++] = value[1];
            }
            else {
              if (ip) {
                hypre_map(ix - 1, iy, iz - 1, p - 1, q, r - 1, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                offd_data[o_cnt++] = value[1];
              }
            }
            hypre_map(ix, iy, iz - 1, p, q, r - 1, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
            offd_data[o_cnt++] = value[1];
            if ((ix + 1) < nx_local) {
              hypre_map(ix + 1, iy, iz - 1, p, q, r - 1, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
              offd_data[o_cnt++] = value[1];
            }
            else {
              if ((ip + 1) < P) {
                hypre_map(ix + 1, iy, iz - 1, p + 1, q, r - 1, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                offd_data[o_cnt++] = value[1];
              }
            }
            if ((iy + 1) < ny_local) {
              if (ix > 0) {
                hypre_map(ix - 1, iy + 1, iz - 1, p, q, r - 1, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                offd_data[o_cnt++] = value[1];
              }
              else {
                if (ip) {
                  hypre_map(ix - 1, iy + 1, iz - 1, p - 1, q, r - 1, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                  offd_data[o_cnt++] = value[1];
                }
              }
              hypre_map(ix, iy + 1, iz - 1, p, q, r - 1, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
              offd_data[o_cnt++] = value[1];
              if (ix < (nx_local - 1)) {
                hypre_map(ix + 1, iy + 1, iz - 1, p, q, r - 1, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                offd_data[o_cnt++] = value[1];
              }
              else {
                if ((ip + 1) < P) {
                  hypre_map(ix + 1, iy + 1, iz - 1, p + 1, q, r - 1, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                  offd_data[o_cnt++] = value[1];
                }
              }
            }
            else {
              if ((iq + 1) < Q) {
                if (ix > 0) {
                  hypre_map(ix - 1, iy + 1, iz - 1, p, q + 1, r - 1, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                  offd_data[o_cnt++] = value[1];
                }
                else
                  if (ip) {
                    hypre_map(ix - 1, iy + 1, iz - 1, p - 1, q + 1, r - 1, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                    offd_data[o_cnt++] = value[1];
                  }
                hypre_map(ix, iy + 1, iz - 1, p, q + 1, r - 1, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                offd_data[o_cnt++] = value[1];
                if (ix < (nx_local - 1)) {
                  hypre_map(ix + 1, iy + 1, iz - 1, p, q + 1, r - 1, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                  offd_data[o_cnt++] = value[1];
                }
                else
                  if (ip < (P - 1)) {
                    hypre_map(ix + 1, iy + 1, iz - 1, p + 1, q + 1, r - 1, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                    offd_data[o_cnt++] = value[1];
                  }
              }
            }
          }
        }
        if (iy > 0) {
          if (ix > 0) {
            diag_j[cnt] = (row_index - nx_local) - 1;
            diag_data[cnt++] = value[1];
          }
          else {
            if (ip) {
              hypre_map(ix - 1, iy - 1, iz, p - 1, q, r, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
              offd_data[o_cnt++] = value[1];
            }
          }
          diag_j[cnt] = row_index - nx_local;
          diag_data[cnt++] = value[1];
          if (ix < (nx_local - 1)) {
            diag_j[cnt] = (row_index - nx_local) + 1;
            diag_data[cnt++] = value[1];
          }
          else {
            if ((ip + 1) < P) {
              hypre_map(ix + 1, iy - 1, iz, p + 1, q, r, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
              offd_data[o_cnt++] = value[1];
            }
          }
        }
        else {
          if (iq) {
            if (ix > 0) {
              hypre_map(ix - 1, iy - 1, iz, p, q - 1, r, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
              offd_data[o_cnt++] = value[1];
            }
            else
              if (ip) {
                hypre_map(ix - 1, iy - 1, iz, p - 1, q - 1, r, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                offd_data[o_cnt++] = value[1];
              }
            hypre_map(ix, iy - 1, iz, p, q - 1, r, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
            offd_data[o_cnt++] = value[1];
            if (ix < (nx_local - 1)) {
              hypre_map(ix + 1, iy - 1, iz, p, q - 1, r, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
              offd_data[o_cnt++] = value[1];
            }
            else
              if (ip < (P - 1)) {
                hypre_map(ix + 1, iy - 1, iz, p + 1, q - 1, r, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                offd_data[o_cnt++] = value[1];
              }
          }
        }
        if (ix > 0) {
          diag_j[cnt] = row_index - 1;
          diag_data[cnt++] = value[1];
        }
        else {
          if (ip) {
            hypre_map(ix - 1, iy, iz, p - 1, q, r, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
            offd_data[o_cnt++] = value[1];
          }
        }
        if ((ix + 1) < nx_local) {
          diag_j[cnt] = row_index + 1;
          diag_data[cnt++] = value[1];
        }
        else {
          if ((ip + 1) < P) {
            hypre_map(ix + 1, iy, iz, p + 1, q, r, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
            offd_data[o_cnt++] = value[1];
          }
        }
        if ((iy + 1) < ny_local) {
          if (ix > 0) {
            diag_j[cnt] = (row_index + nx_local) - 1;
            diag_data[cnt++] = value[1];
          }
          else {
            if (ip) {
              hypre_map(ix - 1, iy + 1, iz, p - 1, q, r, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
              offd_data[o_cnt++] = value[1];
            }
          }
          diag_j[cnt] = row_index + nx_local;
          diag_data[cnt++] = value[1];
          if (ix < (nx_local - 1)) {
            diag_j[cnt] = (row_index + nx_local) + 1;
            diag_data[cnt++] = value[1];
          }
          else {
            if ((ip + 1) < P) {
              hypre_map(ix + 1, iy + 1, iz, p + 1, q, r, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
              offd_data[o_cnt++] = value[1];
            }
          }
        }
        else {
          if ((iq + 1) < Q) {
            if (ix > 0) {
              hypre_map(ix - 1, iy + 1, iz, p, q + 1, r, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
              offd_data[o_cnt++] = value[1];
            }
            else
              if (ip) {
                hypre_map(ix - 1, iy + 1, iz, p - 1, q + 1, r, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                offd_data[o_cnt++] = value[1];
              }
            hypre_map(ix, iy + 1, iz, p, q + 1, r, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
            offd_data[o_cnt++] = value[1];
            if (ix < (nx_local - 1)) {
              hypre_map(ix + 1, iy + 1, iz, p, q + 1, r, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
              offd_data[o_cnt++] = value[1];
            }
            else
              if (ip < (P - 1)) {
                hypre_map(ix + 1, iy + 1, iz, p + 1, q + 1, r, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                offd_data[o_cnt++] = value[1];
              }
          }
        }
        if ((iz + 1) < nz_local) {
          if (iy > 0) {
            if (ix > 0) {
              diag_j[cnt] = ((row_index + nxy) - nx_local) - 1;
              diag_data[cnt++] = value[1];
            }
            else {
              if (ip) {
                hypre_map(ix - 1, iy - 1, iz + 1, p - 1, q, r, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                offd_data[o_cnt++] = value[1];
              }
            }
            diag_j[cnt] = (row_index + nxy) - nx_local;
            diag_data[cnt++] = value[1];
            if (ix < (nx_local - 1)) {
              diag_j[cnt] = ((row_index + nxy) - nx_local) + 1;
              diag_data[cnt++] = value[1];
            }
            else {
              if ((ip + 1) < P) {
                hypre_map(ix + 1, iy - 1, iz + 1, p + 1, q, r, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                offd_data[o_cnt++] = value[1];
              }
            }
          }
          else {
            if (iq) {
              if (ix > 0) {
                hypre_map(ix - 1, iy - 1, iz + 1, p, q - 1, r, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                offd_data[o_cnt++] = value[1];
              }
              else
                if (ip) {
                  hypre_map(ix - 1, iy - 1, iz + 1, p - 1, q - 1, r, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                  offd_data[o_cnt++] = value[1];
                }
              hypre_map(ix, iy - 1, iz + 1, p, q - 1, r, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
              offd_data[o_cnt++] = value[1];
              if (ix < (nx_local - 1)) {
                hypre_map(ix + 1, iy - 1, iz + 1, p, q - 1, r, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                offd_data[o_cnt++] = value[1];
              }
              else
                if (ip < (P - 1)) {
                  hypre_map(ix + 1, iy - 1, iz + 1, p + 1, q - 1, r, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                  offd_data[o_cnt++] = value[1];
                }
            }
          }
          if (ix > 0) {
            diag_j[cnt] = (row_index + nxy) - 1;
            diag_data[cnt++] = value[1];
          }
          else {
            if (ip) {
              hypre_map(ix - 1, iy, iz + 1, p - 1, q, r, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
              offd_data[o_cnt++] = value[1];
            }
          }
          diag_j[cnt] = row_index + nxy;
          diag_data[cnt++] = value[1];
          if ((ix + 1) < nx_local) {
            diag_j[cnt] = (row_index + nxy) + 1;
            diag_data[cnt++] = value[1];
          }
          else {
            if ((ip + 1) < P) {
              hypre_map(ix + 1, iy, iz + 1, p + 1, q, r, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
              offd_data[o_cnt++] = value[1];
            }
          }
          if ((iy + 1) < ny_local) {
            if (ix > 0) {
              diag_j[cnt] = ((row_index + nxy) + nx_local) - 1;
              diag_data[cnt++] = value[1];
            }
            else {
              if (ip) {
                hypre_map(ix - 1, iy + 1, iz + 1, p - 1, q, r, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                offd_data[o_cnt++] = value[1];
              }
            }
            diag_j[cnt] = (row_index + nxy) + nx_local;
            diag_data[cnt++] = value[1];
            if (ix < (nx_local - 1)) {
              diag_j[cnt] = ((row_index + nxy) + nx_local) + 1;
              diag_data[cnt++] = value[1];
            }
            else {
              if ((ip + 1) < P) {
                hypre_map(ix + 1, iy + 1, iz + 1, p + 1, q, r, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                offd_data[o_cnt++] = value[1];
              }
            }
          }
          else {
            if ((iq + 1) < Q) {
              if (ix > 0) {
                hypre_map(ix - 1, iy + 1, iz + 1, p, q + 1, r, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                offd_data[o_cnt++] = value[1];
              }
              else
                if (ip) {
                  hypre_map(ix - 1, iy + 1, iz + 1, p - 1, q + 1, r, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                  offd_data[o_cnt++] = value[1];
                }
              hypre_map(ix, iy + 1, iz + 1, p, q + 1, r, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
              offd_data[o_cnt++] = value[1];
              if (ix < (nx_local - 1)) {
                hypre_map(ix + 1, iy + 1, iz + 1, p, q + 1, r, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                offd_data[o_cnt++] = value[1];
              }
              else
                if (ip < (P - 1)) {
                  hypre_map(ix + 1, iy + 1, iz + 1, p + 1, q + 1, r, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                  offd_data[o_cnt++] = value[1];
                }
            }
          }
        }
        else {
          if ((ir + 1) < R) {
            if (iy > 0) {
              if (ix > 0) {
                hypre_map(ix - 1, iy - 1, iz + 1, p, q, r + 1, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                offd_data[o_cnt++] = value[1];
              }
              else {
                if (ip) {
                  hypre_map(ix - 1, iy - 1, iz + 1, p - 1, q, r + 1, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                  offd_data[o_cnt++] = value[1];
                }
              }
              hypre_map(ix, iy - 1, iz + 1, p, q, r + 1, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
              offd_data[o_cnt++] = value[1];
              if (ix < (nx_local - 1)) {
                hypre_map(ix + 1, iy - 1, iz + 1, p, q, r + 1, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                offd_data[o_cnt++] = value[1];
              }
              else {
                if ((ip + 1) < P) {
                  hypre_map(ix + 1, iy - 1, iz + 1, p + 1, q, r + 1, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                  offd_data[o_cnt++] = value[1];
                }
              }
            }
            else {
              if (iq) {
                if (ix > 0) {
                  hypre_map(ix - 1, iy - 1, iz + 1, p, q - 1, r + 1, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                  offd_data[o_cnt++] = value[1];
                }
                else
                  if (ip) {
                    hypre_map(ix - 1, iy - 1, iz + 1, p - 1, q - 1, r + 1, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                    offd_data[o_cnt++] = value[1];
                  }
                hypre_map(ix, iy - 1, iz + 1, p, q - 1, r + 1, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                offd_data[o_cnt++] = value[1];
                if (ix < (nx_local - 1)) {
                  hypre_map(ix + 1, iy - 1, iz + 1, p, q - 1, r + 1, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                  offd_data[o_cnt++] = value[1];
                }
                else
                  if (ip < (P - 1)) {
                    hypre_map(ix + 1, iy - 1, iz + 1, p + 1, q - 1, r + 1, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                    offd_data[o_cnt++] = value[1];
                  }
              }
            }
            if (ix > 0) {
              hypre_map(ix - 1, iy, iz + 1, p, q, r + 1, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
              offd_data[o_cnt++] = value[1];
            }
            else {
              if (ip) {
                hypre_map(ix - 1, iy, iz + 1, p - 1, q, r + 1, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                offd_data[o_cnt++] = value[1];
              }
            }
            hypre_map(ix, iy, iz + 1, p, q, r + 1, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
            offd_data[o_cnt++] = value[1];
            if ((ix + 1) < nx_local) {
              hypre_map(ix + 1, iy, iz + 1, p, q, r + 1, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
              offd_data[o_cnt++] = value[1];
            }
            else {
              if ((ip + 1) < P) {
                hypre_map(ix + 1, iy, iz + 1, p + 1, q, r + 1, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                offd_data[o_cnt++] = value[1];
              }
            }
            if ((iy + 1) < ny_local) {
              if (ix > 0) {
                hypre_map(ix - 1, iy + 1, iz + 1, p, q, r + 1, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                offd_data[o_cnt++] = value[1];
              }
              else {
                if (ip) {
                  hypre_map(ix - 1, iy + 1, iz + 1, p - 1, q, r + 1, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                  offd_data[o_cnt++] = value[1];
                }
              }
              hypre_map(ix, iy + 1, iz + 1, p, q, r + 1, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
              offd_data[o_cnt++] = value[1];
              if (ix < (nx_local - 1)) {
                hypre_map(ix + 1, iy + 1, iz + 1, p, q, r + 1, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                offd_data[o_cnt++] = value[1];
              }
              else {
                if ((ip + 1) < P) {
                  hypre_map(ix + 1, iy + 1, iz + 1, p + 1, q, r + 1, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                  offd_data[o_cnt++] = value[1];
                }
              }
            }
            else {
              if ((iq + 1) < Q) {
                if (ix > 0) {
                  hypre_map(ix - 1, iy + 1, iz + 1, p, q + 1, r + 1, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                  offd_data[o_cnt++] = value[1];
                }
                else
                  if (ip) {
                    hypre_map(ix - 1, iy + 1, iz + 1, p - 1, q + 1, r + 1, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                    offd_data[o_cnt++] = value[1];
                  }
                hypre_map(ix, iy + 1, iz + 1, p, q + 1, r + 1, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                offd_data[o_cnt++] = value[1];
                if (ix < (nx_local - 1)) {
                  hypre_map(ix + 1, iy + 1, iz + 1, p, q + 1, r + 1, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                  offd_data[o_cnt++] = value[1];
                }
                else
                  if (ip < (P - 1)) {
                    hypre_map(ix + 1, iy + 1, iz + 1, p + 1, q + 1, r + 1, P, Q, R, nx_part, ny_part, nz_part, global_part, &(work[o_cnt]));
                    offd_data[o_cnt++] = value[1];
                  }
              }
            }
          }
        }
        row_index++;
      }
    }
  }
  if (num_procs > 1) {
    int* tmp_work;
    tmp_work = (int*)(hypre_CAlloc((unsigned)o_cnt, (unsigned)(sizeof(int))));
    for (i = 0; i < o_cnt; i++)
      tmp_work[i] = work[i];
    hypre_BigQsort0(tmp_work, 0, o_cnt - 1);
    col_map_offd[0] = tmp_work[0];
    cnt = 0;
    for (i = 0; i < o_cnt; i++) {
      if ((tmp_work[i]) > (col_map_offd[cnt])) {
        cnt++;
        col_map_offd[cnt] = tmp_work[i];
      }
    }
    hypre_Free((char*)tmp_work), tmp_work = (void*)0;
    for (i = 0; i < o_cnt; i++) {
      offd_j[i] = hypre_BigBinarySearch(col_map_offd, work[i], num_cols_offd);
    }
    hypre_Free((char*)work), work = (void*)0;
  }
  par_rhs = hypre_ParVectorCreate(comm, grid_size, global_part_rhs);
  rhs = (par_rhs)->local_vector;
  (rhs)->data = rhs_data;
  par_x = hypre_ParVectorCreate(comm, grid_size, global_part_x);
  x = (par_x)->local_vector;
  (x)->data = x_data;
  A = hypre_ParCSRMatrixCreate(comm, grid_size, grid_size, global_part, global_part, num_cols_offd, diag_i[local_num_rows], offd_i[local_num_rows]);
  (A)->col_map_offd = col_map_offd;
  diag = (A)->diag;
  (diag)->i = diag_i;
  (diag)->j = diag_j;
  (diag)->data = diag_data;
  offd = (A)->offd;
  (offd)->i = offd_i;
  if (num_cols_offd) {
    (offd)->j = offd_j;
    (offd)->data = offd_data;
  }
  hypre_Free((char*)nx_part), nx_part = (void*)0;
  hypre_Free((char*)ny_part), ny_part = (void*)0;
  hypre_Free((char*)nz_part), nz_part = (void*)0;
  *rhs_ptr = (HYPRE_ParVector)par_rhs;
  *x_ptr = (HYPRE_ParVector)par_x;
  return (HYPRE_ParCSRMatrix)A;
}
//===================== par_lr_interp.c ====================
int hypre_BoomerAMGBuildStdInterp(hypre_ParCSRMatrix* A, int* CF_marker, hypre_ParCSRMatrix* S, int* num_cpts_global, int num_functions, int* dof_func, int debug_flag, double trunc_factor, int max_elmts, int sep_weight, int* col_offd_S_to_A, hypre_ParCSRMatrix** P_ptr) {
  MPI_Comm comm = (A)->comm;
  hypre_ParCSRCommPkg* comm_pkg = (A)->comm_pkg;
  int my_id;
  int num_procs;
  hypre_CSRMatrix* A_diag = (A)->diag;
  double* A_diag_data = (A_diag)->data;
  int* A_diag_i = (A_diag)->i;
  int* A_diag_j = (A_diag)->j;
  hypre_CSRMatrix* A_offd = (A)->offd;
  double* A_offd_data = (A_offd)->data;
  int* A_offd_i = (A_offd)->i;
  int* A_offd_j = (A_offd)->j;
  int num_cols_A_offd = (A_offd)->num_cols;
  int* col_map_offd = (A)->col_map_offd;
  int n_fine = (A_diag)->num_rows;
  int col_1 = (A)->first_row_index;
  int local_numrows = (A_diag)->num_rows;
  int col_n = col_1 + (int)local_numrows;
  int total_global_cpts;
  int my_first_cpt;
  hypre_CSRMatrix* S_diag = (S)->diag;
  int* S_diag_i = (S_diag)->i;
  int* S_diag_j = (S_diag)->j;
  hypre_CSRMatrix* S_offd = (S)->offd;
  int* S_offd_i = (S_offd)->i;
  int* S_offd_j = (S_offd)->j;
  hypre_ParCSRMatrix* P;
  hypre_CSRMatrix* P_diag;
  hypre_CSRMatrix* P_offd;
  double* P_diag_data = (void*)0;
  int* P_diag_i;
  int* P_diag_j = (void*)0;
  double* P_offd_data = (void*)0;
  int* P_offd_i;
  int* P_offd_j = (void*)0;
  int* col_map_offd_P;
  int* tmp_map_offd;
  int P_diag_size;
  int P_offd_size;
  int* P_marker = (void*)0;
  int* P_marker_offd = (void*)0;
  int* CF_marker_offd = (void*)0;
  int* tmp_CF_marker_offd = (void*)0;
  int* dof_func_offd = (void*)0;
  hypre_BigCSRMatrix* A_ext;
  double* A_ext_data;
  int* A_ext_i;
  int* big_A_ext_j;
  int* A_ext_j;
  int* fine_to_coarse = (void*)0;
  int* fine_to_coarse_offd = (void*)0;
  int* found;
  int num_cols_P_offd;
  int newoff;
  int loc_col;
  int A_ext_rows;
  int full_off_procNodes;
  hypre_BigCSRMatrix* Sop;
  int* Sop_i;
  int* big_Sop_j;
  int* Sop_j;
  int Soprows;
  int jj_counter;
  int jj_counter_offd;
  int jj_begin_row;
  int jj_end_row;
  int jj_begin_row_offd = 0;
  int jj_end_row_offd = 0;
  int coarse_counter;
  int coarse_counter_offd;
  int* ihat = (void*)0;
  int* ihat_offd = (void*)0;
  int* ipnt = (void*)0;
  int* ipnt_offd = (void*)0;
  int strong_f_marker = -2;
  double* ahat = (void*)0;
  double* ahat_offd = (void*)0;
  double sum_pos;
  double sum_pos_C;
  double sum_neg;
  double sum_neg_C;
  double sum;
  double sum_C;
  double diagonal;
  double distribute;
  double alfa;
  double beta;
  int index;
  int start_indexing = 0;
  int i;
  int i1;
  int j1;
  int jj;
  int kk;
  int k1;
  int cnt_c;
  int cnt_f;
  int cnt_c_offd;
  int cnt_f_offd;
  int indx;
  double zero = 0.0;
  double one = 1.0;
  double wall_time;
  double wall_1 = 0;
  double wall_2 = 0;
  double wall_3 = 0;
  hypre_ParCSRCommPkg* extend_comm_pkg = (void*)0;
  if (debug_flag == 4)
    wall_time = time_getWallclockSeconds();
  MPI_Comm_size(comm, &(num_procs));
  MPI_Comm_rank(comm, &(my_id));
  my_first_cpt = num_cpts_global[my_id];
  total_global_cpts = num_cpts_global[num_procs];
  if (!comm_pkg) {
    hypre_MatvecCommPkgCreate(A);
    comm_pkg = (A)->comm_pkg;
  }
  newoff = 0;
  full_off_procNodes = 0;
  if (num_procs > 1) {
    A_ext = hypre_ParCSRMatrixExtractBigExt(A, A, 1);
    A_ext_i = (A_ext)->i;
    big_A_ext_j = (A_ext)->j;
    A_ext_data = (A_ext)->data;
    A_ext_rows = (A_ext)->num_rows;
    Sop = hypre_ParCSRMatrixExtractBigExt(S, A, 0);
    Sop_i = (Sop)->i;
    big_Sop_j = (Sop)->j;
    Soprows = (Sop)->num_rows;
    newoff = new_offd_nodes(&(found), A_ext_rows, A_ext_i, big_A_ext_j, &(A_ext_j), Soprows, col_map_offd, col_1, col_n, Sop_i, big_Sop_j, &(Sop_j), CF_marker, comm_pkg);
    (A_ext)->j = (void*)0;
    (Sop)->j = (void*)0;
    if (newoff >= 0)
      full_off_procNodes = newoff + num_cols_A_offd;
    else
      return 1;
    hypre_ParCSRFindExtendCommPkg(A, newoff, found, &(extend_comm_pkg));
    CF_marker_offd = (int*)(hypre_CAlloc((unsigned)full_off_procNodes, (unsigned)(sizeof(int))));
    if ((num_functions > 1) && (full_off_procNodes > 0))
      dof_func_offd = (int*)(hypre_CAlloc((unsigned)full_off_procNodes, (unsigned)(sizeof(int))));
    alt_insert_new_nodes(comm_pkg, extend_comm_pkg, CF_marker, full_off_procNodes, CF_marker_offd);
    if (num_functions > 1)
      alt_insert_new_nodes(comm_pkg, extend_comm_pkg, dof_func, full_off_procNodes, dof_func_offd);
  }
  P_diag_i = (int*)(hypre_CAlloc((unsigned)(n_fine + 1), (unsigned)(sizeof(int))));
  P_offd_i = (int*)(hypre_CAlloc((unsigned)(n_fine + 1), (unsigned)(sizeof(int))));
  if (n_fine) {
    fine_to_coarse = (int*)(hypre_CAlloc((unsigned)n_fine, (unsigned)(sizeof(int))));
    P_marker = (int*)(hypre_CAlloc((unsigned)n_fine, (unsigned)(sizeof(int))));
  }
  if (full_off_procNodes) {
    P_marker_offd = (int*)(hypre_CAlloc((unsigned)full_off_procNodes, (unsigned)(sizeof(int))));
    fine_to_coarse_offd = (int*)(hypre_CAlloc((unsigned)full_off_procNodes, (unsigned)(sizeof(int))));
    tmp_CF_marker_offd = (int*)(hypre_CAlloc((unsigned)full_off_procNodes, (unsigned)(sizeof(int))));
  }
  for (i = 0; i < full_off_procNodes; i++) {
    P_marker_offd[i] = -1;
    tmp_CF_marker_offd[i] = -1;
    fine_to_coarse_offd[i] = -1;
  }
  for (i = 0; i < n_fine; i++) {
    P_marker[i] = -1;
    fine_to_coarse[i] = -1;
  }
  jj_counter = start_indexing;
  jj_counter_offd = start_indexing;
  coarse_counter = 0;
  coarse_counter_offd = 0;
  for (i = 0; i < n_fine; i++) {
    P_diag_i[i] = jj_counter;
    if (num_procs > 1)
      P_offd_i[i] = jj_counter_offd;
    if ((CF_marker[i]) >= 0) {
      jj_counter++;
      fine_to_coarse[i] = coarse_counter;
      coarse_counter++;
    }
    else
      if ((CF_marker[i]) != (-3)) {
        for (jj = S_diag_i[i]; jj < (S_diag_i[i + 1]); jj++) {
          i1 = S_diag_j[jj];
          if ((CF_marker[i1]) >= 0) {
            if ((P_marker[i1]) < (P_diag_i[i])) {
              P_marker[i1] = jj_counter;
              jj_counter++;
            }
          }
          else
            if ((CF_marker[i1]) != (-3)) {
              for (kk = S_diag_i[i1]; kk < (S_diag_i[i1 + 1]); kk++) {
                k1 = S_diag_j[kk];
                if ((CF_marker[k1]) >= 0) {
                  if ((P_marker[k1]) < (P_diag_i[i])) {
                    P_marker[k1] = jj_counter;
                    jj_counter++;
                  }
                }
              }
              if (num_procs > 1) {
                for (kk = S_offd_i[i1]; kk < (S_offd_i[i1 + 1]); kk++) {
                  if (col_offd_S_to_A)
                    k1 = col_offd_S_to_A[S_offd_j[kk]];
                  else
                    k1 = S_offd_j[kk];
                  if ((CF_marker_offd[k1]) > 0) {
                    if ((P_marker_offd[k1]) < (P_offd_i[i])) {
                      tmp_CF_marker_offd[k1] = 1;
                      P_marker_offd[k1] = jj_counter_offd;
                      jj_counter_offd++;
                    }
                  }
                }
              }
            }
        }
        if (num_procs > 1) {
          for (jj = S_offd_i[i]; jj < (S_offd_i[i + 1]); jj++) {
            i1 = S_offd_j[jj];
            if (col_offd_S_to_A)
              i1 = col_offd_S_to_A[i1];
            if ((CF_marker_offd[i1]) > 0) {
              if ((P_marker_offd[i1]) < (P_offd_i[i])) {
                tmp_CF_marker_offd[i1] = 1;
                P_marker_offd[i1] = jj_counter_offd;
                jj_counter_offd++;
              }
            }
            else
              if ((CF_marker_offd[i1]) != (-3)) {
                for (kk = Sop_i[i1]; kk < (Sop_i[i1 + 1]); kk++) {
                  loc_col = Sop_j[kk];
                  if (loc_col > (-1)) {
                    if ((CF_marker[loc_col]) > 0) {
                      if ((P_marker[loc_col]) < (P_diag_i[i])) {
                        P_marker[loc_col] = jj_counter;
                        jj_counter++;
                      }
                    }
                  }
                  else {
                    loc_col = (-loc_col) - 1;
                    if ((CF_marker_offd[loc_col]) > 0) {
                      if ((P_marker_offd[loc_col]) < (P_offd_i[i])) {
                        P_marker_offd[loc_col] = jj_counter_offd;
                        tmp_CF_marker_offd[loc_col] = 1;
                        jj_counter_offd++;
                      }
                    }
                  }
                }
              }
          }
        }
      }
  }
  if (debug_flag == 4) {
    wall_time = time_getWallclockSeconds() - wall_time;
    printf("Proc = %d     determine structure    %f\n", my_id, wall_time);
    fflush((void*)0);
  }
  P_diag_size = jj_counter;
  P_offd_size = jj_counter_offd;
  if (P_diag_size) {
    P_diag_j = (int*)(hypre_CAlloc((unsigned)P_diag_size, (unsigned)(sizeof(int))));
    P_diag_data = (double*)(hypre_CAlloc((unsigned)P_diag_size, (unsigned)(sizeof(double))));
  }
  if (P_offd_size) {
    P_offd_j = (int*)(hypre_CAlloc((unsigned)P_offd_size, (unsigned)(sizeof(int))));
    P_offd_data = (double*)(hypre_CAlloc((unsigned)P_offd_size, (unsigned)(sizeof(double))));
  }
  P_diag_i[n_fine] = jj_counter;
  P_offd_i[n_fine] = jj_counter_offd;
  jj_counter = start_indexing;
  jj_counter_offd = start_indexing;
  if (num_procs > 1) {
    big_insert_new_nodes(comm_pkg, extend_comm_pkg, fine_to_coarse, full_off_procNodes, my_first_cpt, fine_to_coarse_offd);
  }
  if (n_fine) {
    ahat = (double*)(hypre_CAlloc((unsigned)n_fine, (unsigned)(sizeof(double))));
    ihat = (int*)(hypre_CAlloc((unsigned)n_fine, (unsigned)(sizeof(int))));
    ipnt = (int*)(hypre_CAlloc((unsigned)n_fine, (unsigned)(sizeof(int))));
  }
  if (full_off_procNodes) {
    ahat_offd = (double*)(hypre_CAlloc((unsigned)full_off_procNodes, (unsigned)(sizeof(double))));
    ihat_offd = (int*)(hypre_CAlloc((unsigned)full_off_procNodes, (unsigned)(sizeof(int))));
    ipnt_offd = (int*)(hypre_CAlloc((unsigned)full_off_procNodes, (unsigned)(sizeof(int))));
  }
  for (i = 0; i < n_fine; i++) {
    P_marker[i] = -1;
    ahat[i] = 0;
    ihat[i] = -1;
  }
  for (i = 0; i < full_off_procNodes; i++) {
    P_marker_offd[i] = -1;
    ahat_offd[i] = 0;
    ihat_offd[i] = -1;
  }
  for (i = 0; i < n_fine; i++) {
    jj_begin_row = jj_counter;
    if (num_procs > 1)
      jj_begin_row_offd = jj_counter_offd;
    if ((CF_marker[i]) >= 0) {
      P_diag_j[jj_counter] = fine_to_coarse[i];
      P_diag_data[jj_counter] = one;
      jj_counter++;
    }
    else
      if ((CF_marker[i]) != (-3)) {
        if (debug_flag == 4)
          wall_time = time_getWallclockSeconds();
        strong_f_marker--;
        for (jj = S_diag_i[i]; jj < (S_diag_i[i + 1]); jj++) {
          i1 = S_diag_j[jj];
          if ((CF_marker[i1]) >= 0) {
            if ((P_marker[i1]) < jj_begin_row) {
              P_marker[i1] = jj_counter;
              P_diag_j[jj_counter] = i1;
              P_diag_data[jj_counter] = zero;
              jj_counter++;
            }
          }
          else
            if ((CF_marker[i1]) != (-3)) {
              P_marker[i1] = strong_f_marker;
              for (kk = S_diag_i[i1]; kk < (S_diag_i[i1 + 1]); kk++) {
                k1 = S_diag_j[kk];
                if ((CF_marker[k1]) >= 0) {
                  if ((P_marker[k1]) < jj_begin_row) {
                    P_marker[k1] = jj_counter;
                    P_diag_j[jj_counter] = k1;
                    P_diag_data[jj_counter] = zero;
                    jj_counter++;
                  }
                }
              }
              if (num_procs > 1) {
                for (kk = S_offd_i[i1]; kk < (S_offd_i[i1 + 1]); kk++) {
                  if (col_offd_S_to_A)
                    k1 = col_offd_S_to_A[S_offd_j[kk]];
                  else
                    k1 = S_offd_j[kk];
                  if ((CF_marker_offd[k1]) >= 0) {
                    if ((P_marker_offd[k1]) < jj_begin_row_offd) {
                      P_marker_offd[k1] = jj_counter_offd;
                      P_offd_j[jj_counter_offd] = k1;
                      P_offd_data[jj_counter_offd] = zero;
                      jj_counter_offd++;
                    }
                  }
                }
              }
            }
        }
        if (num_procs > 1) {
          for (jj = S_offd_i[i]; jj < (S_offd_i[i + 1]); jj++) {
            i1 = S_offd_j[jj];
            if (col_offd_S_to_A)
              i1 = col_offd_S_to_A[i1];
            if ((CF_marker_offd[i1]) >= 0) {
              if ((P_marker_offd[i1]) < jj_begin_row_offd) {
                P_marker_offd[i1] = jj_counter_offd;
                P_offd_j[jj_counter_offd] = i1;
                P_offd_data[jj_counter_offd] = zero;
                jj_counter_offd++;
              }
            }
            else
              if ((CF_marker_offd[i1]) != (-3)) {
                P_marker_offd[i1] = strong_f_marker;
                for (kk = Sop_i[i1]; kk < (Sop_i[i1 + 1]); kk++) {
                  loc_col = Sop_j[kk];
                  if (loc_col > (-1)) {
                    if ((CF_marker[loc_col]) > 0) {
                      if ((P_marker[loc_col]) < jj_begin_row) {
                        P_marker[loc_col] = jj_counter;
                        P_diag_j[jj_counter] = loc_col;
                        P_diag_data[jj_counter] = zero;
                        jj_counter++;
                      }
                    }
                  }
                  else {
                    loc_col = (-loc_col) - 1;
                    if ((CF_marker_offd[loc_col]) > 0) {
                      if ((P_marker_offd[loc_col]) < jj_begin_row_offd) {
                        P_marker_offd[loc_col] = jj_counter_offd;
                        P_offd_j[jj_counter_offd] = loc_col;
                        P_offd_data[jj_counter_offd] = zero;
                        jj_counter_offd++;
                      }
                    }
                  }
                }
              }
          }
        }
        jj_end_row = jj_counter;
        jj_end_row_offd = jj_counter_offd;
        if (debug_flag == 4) {
          wall_time = time_getWallclockSeconds() - wall_time;
          wall_1 += wall_time;
          fflush((void*)0);
        }
        if (debug_flag == 4)
          wall_time = time_getWallclockSeconds();
        cnt_c = 0;
        cnt_f = jj_end_row - jj_begin_row;
        cnt_c_offd = 0;
        cnt_f_offd = jj_end_row_offd - jj_begin_row_offd;
        ihat[i] = cnt_f;
        ipnt[cnt_f] = i;
        ahat[cnt_f++] = A_diag_data[A_diag_i[i]];
        for (jj = (A_diag_i[i]) + 1; jj < (A_diag_i[i + 1]); jj++) {
          i1 = A_diag_j[jj];
          if ((P_marker[i1]) != strong_f_marker) {
            indx = ihat[i1];
            if (indx > (-1))
              ahat[indx] += A_diag_data[jj];
            else
              if ((P_marker[i1]) >= jj_begin_row) {
                ihat[i1] = cnt_c;
                ipnt[cnt_c] = i1;
                ahat[cnt_c++] += A_diag_data[jj];
              }
              else
                if ((CF_marker[i1]) != (-3)) {
                  ihat[i1] = cnt_f;
                  ipnt[cnt_f] = i1;
                  ahat[cnt_f++] += A_diag_data[jj];
                }
          }
          else {
            if ((num_functions == 1) || ((dof_func[i]) == (dof_func[i1]))) {
              distribute = (A_diag_data[jj]) / (A_diag_data[A_diag_i[i1]]);
              for (kk = (A_diag_i[i1]) + 1; kk < (A_diag_i[i1 + 1]); kk++) {
                k1 = A_diag_j[kk];
                indx = ihat[k1];
                if (indx > (-1))
                  (ahat[indx]) -= ((A_diag_data[kk]) * distribute);
                else
                  if ((P_marker[k1]) >= jj_begin_row) {
                    ihat[k1] = cnt_c;
                    ipnt[cnt_c] = k1;
                    (ahat[cnt_c++]) -= ((A_diag_data[kk]) * distribute);
                  }
                  else {
                    ihat[k1] = cnt_f;
                    ipnt[cnt_f] = k1;
                    (ahat[cnt_f++]) -= ((A_diag_data[kk]) * distribute);
                  }
              }
              if (num_procs > 1) {
                for (kk = A_offd_i[i1]; kk < (A_offd_i[i1 + 1]); kk++) {
                  k1 = A_offd_j[kk];
                  indx = ihat_offd[k1];
                  if ((num_functions == 1) || ((dof_func[i1]) == (dof_func_offd[k1]))) {
                    if (indx > (-1))
                      (ahat_offd[indx]) -= ((A_offd_data[kk]) * distribute);
                    else
                      if ((P_marker_offd[k1]) >= jj_begin_row_offd) {
                        ihat_offd[k1] = cnt_c_offd;
                        ipnt_offd[cnt_c_offd] = k1;
                        (ahat_offd[cnt_c_offd++]) -= ((A_offd_data[kk]) * distribute);
                      }
                      else {
                        ihat_offd[k1] = cnt_f_offd;
                        ipnt_offd[cnt_f_offd] = k1;
                        (ahat_offd[cnt_f_offd++]) -= ((A_offd_data[kk]) * distribute);
                      }
                  }
                }
              }
            }
          }
        }
        if (num_procs > 1) {
          for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
            i1 = A_offd_j[jj];
            if ((P_marker_offd[i1]) != strong_f_marker) {
              indx = ihat_offd[i1];
              if (indx > (-1))
                ahat_offd[indx] += A_offd_data[jj];
              else
                if ((P_marker_offd[i1]) >= jj_begin_row_offd) {
                  ihat_offd[i1] = cnt_c_offd;
                  ipnt_offd[cnt_c_offd] = i1;
                  ahat_offd[cnt_c_offd++] += A_offd_data[jj];
                }
                else
                  if ((CF_marker_offd[i1]) != (-3)) {
                    ihat_offd[i1] = cnt_f_offd;
                    ipnt_offd[cnt_f_offd] = i1;
                    ahat_offd[cnt_f_offd++] += A_offd_data[jj];
                  }
            }
            else {
              if ((num_functions == 1) || ((dof_func[i]) == (dof_func_offd[i1]))) {
                distribute = (A_offd_data[jj]) / (A_ext_data[A_ext_i[i1]]);
                for (kk = (A_ext_i[i1]) + 1; kk < (A_ext_i[i1 + 1]); kk++) {
                  loc_col = A_ext_j[kk];
                  if (loc_col > (-1)) {
                    indx = ihat[loc_col];
                    if (indx > (-1))
                      (ahat[indx]) -= ((A_ext_data[kk]) * distribute);
                    else
                      if ((P_marker[loc_col]) >= jj_begin_row) {
                        ihat[loc_col] = cnt_c;
                        ipnt[cnt_c] = loc_col;
                        (ahat[cnt_c++]) -= ((A_ext_data[kk]) * distribute);
                      }
                      else {
                        ihat[loc_col] = cnt_f;
                        ipnt[cnt_f] = loc_col;
                        (ahat[cnt_f++]) -= ((A_ext_data[kk]) * distribute);
                      }
                  }
                  else {
                    loc_col = (-loc_col) - 1;
                    if ((num_functions == 1) || ((dof_func_offd[loc_col]) == (dof_func_offd[i1]))) {
                      indx = ihat_offd[loc_col];
                      if (indx > (-1))
                        (ahat_offd[indx]) -= ((A_ext_data[kk]) * distribute);
                      else
                        if ((P_marker_offd[loc_col]) >= jj_begin_row_offd) {
                          ihat_offd[loc_col] = cnt_c_offd;
                          ipnt_offd[cnt_c_offd] = loc_col;
                          (ahat_offd[cnt_c_offd++]) -= ((A_ext_data[kk]) * distribute);
                        }
                        else {
                          ihat_offd[loc_col] = cnt_f_offd;
                          ipnt_offd[cnt_f_offd] = loc_col;
                          (ahat_offd[cnt_f_offd++]) -= ((A_ext_data[kk]) * distribute);
                        }
                    }
                  }
                }
              }
            }
          }
        }
        if (debug_flag == 4) {
          wall_time = time_getWallclockSeconds() - wall_time;
          wall_2 += wall_time;
          fflush((void*)0);
        }
        if (debug_flag == 4)
          wall_time = time_getWallclockSeconds();
        diagonal = ahat[cnt_c];
        ahat[cnt_c] = 0;
        sum_pos = 0;
        sum_pos_C = 0;
        sum_neg = 0;
        sum_neg_C = 0;
        sum = 0;
        sum_C = 0;
        if (sep_weight == 1) {
          for (jj = 0; jj < cnt_c; jj++) {
            if ((ahat[jj]) > 0) {
              sum_pos_C += ahat[jj];
            }
            else {
              sum_neg_C += ahat[jj];
            }
          }
          if (num_procs > 1) {
            for (jj = 0; jj < cnt_c_offd; jj++) {
              if ((ahat_offd[jj]) > 0) {
                sum_pos_C += ahat_offd[jj];
              }
              else {
                sum_neg_C += ahat_offd[jj];
              }
            }
          }
          sum_pos = sum_pos_C;
          sum_neg = sum_neg_C;
          for (jj = cnt_c + 1; jj < cnt_f; jj++) {
            if ((ahat[jj]) > 0) {
              sum_pos += ahat[jj];
            }
            else {
              sum_neg += ahat[jj];
            }
            ahat[jj] = 0;
          }
          if (num_procs > 1) {
            for (jj = cnt_c_offd; jj < cnt_f_offd; jj++) {
              if ((ahat_offd[jj]) > 0) {
                sum_pos += ahat_offd[jj];
              }
              else {
                sum_neg += ahat_offd[jj];
              }
              ahat_offd[jj] = 0;
            }
          }
          if (sum_neg_C)
            alfa = (sum_neg / sum_neg_C) / diagonal;
          if (sum_pos_C)
            beta = (sum_pos / sum_pos_C) / diagonal;
          for (jj = jj_begin_row; jj < jj_end_row; jj++) {
            j1 = ihat[P_diag_j[jj]];
            if ((ahat[j1]) > 0)
              P_diag_data[jj] = (-beta) * (ahat[j1]);
            else
              P_diag_data[jj] = (-alfa) * (ahat[j1]);
            P_diag_j[jj] = fine_to_coarse[P_diag_j[jj]];
            ahat[j1] = 0;
          }
          for (jj = 0; jj < cnt_f; jj++)
            ihat[ipnt[jj]] = -1;
          if (num_procs > 1) {
            for (jj = jj_begin_row_offd; jj < jj_end_row_offd; jj++) {
              j1 = ihat_offd[P_offd_j[jj]];
              if ((ahat_offd[j1]) > 0)
                P_offd_data[jj] = (-beta) * (ahat_offd[j1]);
              else
                P_offd_data[jj] = (-alfa) * (ahat_offd[j1]);
              ahat_offd[j1] = 0;
            }
            for (jj = 0; jj < cnt_f_offd; jj++)
              ihat_offd[ipnt_offd[jj]] = -1;
          }
        }
        else {
          for (jj = 0; jj < cnt_c; jj++) {
            sum_C += ahat[jj];
          }
          if (num_procs > 1) {
            for (jj = 0; jj < cnt_c_offd; jj++) {
              sum_C += ahat_offd[jj];
            }
          }
          sum = sum_C;
          for (jj = cnt_c + 1; jj < cnt_f; jj++) {
            sum += ahat[jj];
            ahat[jj] = 0;
          }
          if (num_procs > 1) {
            for (jj = cnt_c_offd; jj < cnt_f_offd; jj++) {
              sum += ahat_offd[jj];
              ahat_offd[jj] = 0;
            }
          }
          if (sum_C)
            alfa = (sum / sum_C) / diagonal;
          for (jj = jj_begin_row; jj < jj_end_row; jj++) {
            j1 = ihat[P_diag_j[jj]];
            P_diag_data[jj] = (-alfa) * (ahat[j1]);
            P_diag_j[jj] = fine_to_coarse[P_diag_j[jj]];
            ahat[j1] = 0;
          }
          for (jj = 0; jj < cnt_f; jj++)
            ihat[ipnt[jj]] = -1;
          if (num_procs > 1) {
            for (jj = jj_begin_row_offd; jj < jj_end_row_offd; jj++) {
              j1 = ihat_offd[P_offd_j[jj]];
              P_offd_data[jj] = (-alfa) * (ahat_offd[j1]);
              ahat_offd[j1] = 0;
            }
            for (jj = 0; jj < cnt_f_offd; jj++)
              ihat_offd[ipnt_offd[jj]] = -1;
          }
        }
        if (debug_flag == 4) {
          wall_time = time_getWallclockSeconds() - wall_time;
          wall_3 += wall_time;
          fflush((void*)0);
        }
      }
  }
  if (debug_flag == 4) {
    printf("Proc = %d fill part 1 %f part 2 %f  part 3 %f\n", my_id, wall_1, wall_2, wall_3);
    fflush((void*)0);
  }
  P = hypre_ParCSRMatrixCreate(comm, (A)->global_num_rows, total_global_cpts, (A)->col_starts, num_cpts_global, 0, P_diag_i[n_fine], P_offd_i[n_fine]);
  P_diag = (P)->diag;
  (P_diag)->data = P_diag_data;
  (P_diag)->i = P_diag_i;
  (P_diag)->j = P_diag_j;
  P_offd = (P)->offd;
  (P_offd)->data = P_offd_data;
  (P_offd)->i = P_offd_i;
  (P_offd)->j = P_offd_j;
  (P)->owns_row_starts = 0;
  if ((trunc_factor != 0.0) || (max_elmts > 0)) {
    hypre_BoomerAMGInterpTruncation(P, trunc_factor, max_elmts);
    P_diag_data = (P_diag)->data;
    P_diag_i = (P_diag)->i;
    P_diag_j = (P_diag)->j;
    P_offd_data = (P_offd)->data;
    P_offd_i = (P_offd)->i;
    P_offd_j = (P_offd)->j;
    P_diag_size = P_diag_i[n_fine];
    P_offd_size = P_offd_i[n_fine];
  }
  num_cols_P_offd = 0;
  if (P_offd_size) {
    num_cols_P_offd = 0;
    for (i = 0; i < P_offd_size; i++) {
      index = P_offd_j[i];
      if ((tmp_CF_marker_offd[index]) == 1) {
        num_cols_P_offd++;
        tmp_CF_marker_offd[index] = 2;
      }
    }
    if (num_cols_P_offd) {
      col_map_offd_P = (int*)(hypre_CAlloc((unsigned)num_cols_P_offd, (unsigned)(sizeof(int))));
      tmp_map_offd = (int*)(hypre_CAlloc((unsigned)num_cols_P_offd, (unsigned)(sizeof(int))));
    }
    index = 0;
    for (i = 0; i < num_cols_P_offd; i++) {
      while ((tmp_CF_marker_offd[index]) == (-1))
        index++;
      col_map_offd_P[i] = fine_to_coarse_offd[index];
      tmp_map_offd[i] = index++;
    }
    hypre_BigQsortbi(col_map_offd_P, tmp_map_offd, 0, num_cols_P_offd - 1);
    for (i = 0; i < num_cols_P_offd; i++)
      tmp_CF_marker_offd[tmp_map_offd[i]] = i;
    for (i = 0; i < P_offd_size; i++)
      P_offd_j[i] = tmp_CF_marker_offd[P_offd_j[i]];
  }
  if (num_cols_P_offd) {
    (P)->col_map_offd = col_map_offd_P;
    (P_offd)->num_cols = num_cols_P_offd;
    hypre_Free((char*)tmp_map_offd), tmp_map_offd = (void*)0;
  }
  hypre_MatvecCommPkgCreate(P);
  for (i = 0; i < n_fine; i++)
    if ((CF_marker[i]) == (-3))
      CF_marker[i] = -1;
  *P_ptr = P;
  hypre_Free((char*)fine_to_coarse), fine_to_coarse = (void*)0;
  hypre_Free((char*)P_marker), P_marker = (void*)0;
  hypre_Free((char*)ahat), ahat = (void*)0;
  hypre_Free((char*)ihat), ihat = (void*)0;
  hypre_Free((char*)ipnt), ipnt = (void*)0;
  if (full_off_procNodes) {
    hypre_Free((char*)ahat_offd), ahat_offd = (void*)0;
    hypre_Free((char*)ihat_offd), ihat_offd = (void*)0;
    hypre_Free((char*)ipnt_offd), ipnt_offd = (void*)0;
  }
  if (num_procs > 1) {
    hypre_BigCSRMatrixDestroy(Sop);
    hypre_BigCSRMatrixDestroy(A_ext);
    hypre_Free((char*)fine_to_coarse_offd), fine_to_coarse_offd = (void*)0;
    hypre_Free((char*)P_marker_offd), P_marker_offd = (void*)0;
    hypre_Free((char*)CF_marker_offd), CF_marker_offd = (void*)0;
    hypre_Free((char*)tmp_CF_marker_offd), tmp_CF_marker_offd = (void*)0;
    if (num_functions > 1)
      hypre_Free((char*)dof_func_offd), dof_func_offd = (void*)0;
    hypre_Free((char*)found), found = (void*)0;
    hypre_MatvecCommPkgDestroy(extend_comm_pkg);
  }
  return hypre__global_error;
}
int hypre_BoomerAMGBuildExtPIInterp(hypre_ParCSRMatrix* A, int* CF_marker, hypre_ParCSRMatrix* S, int* num_cpts_global, int num_functions, int* dof_func, int debug_flag, double trunc_factor, int max_elmts, int* col_offd_S_to_A, hypre_ParCSRMatrix** P_ptr) {
  MPI_Comm comm = (A)->comm;
  hypre_ParCSRCommPkg* comm_pkg = (A)->comm_pkg;
  int my_id;
  int num_procs;
  hypre_CSRMatrix* A_diag = (A)->diag;
  double* A_diag_data = (A_diag)->data;
  int* A_diag_i = (A_diag)->i;
  int* A_diag_j = (A_diag)->j;
  hypre_CSRMatrix* A_offd = (A)->offd;
  double* A_offd_data = (A_offd)->data;
  int* A_offd_i = (A_offd)->i;
  int* A_offd_j = (A_offd)->j;
  int num_cols_A_offd = (A_offd)->num_cols;
  int* col_map_offd = (A)->col_map_offd;
  int n_fine = (A_diag)->num_rows;
  int col_1 = (A)->first_row_index;
  int local_numrows = (A_diag)->num_rows;
  int col_n = col_1 + (int)local_numrows;
  int total_global_cpts;
  int my_first_cpt;
  hypre_CSRMatrix* S_diag = (S)->diag;
  int* S_diag_i = (S_diag)->i;
  int* S_diag_j = (S_diag)->j;
  hypre_CSRMatrix* S_offd = (S)->offd;
  int* S_offd_i = (S_offd)->i;
  int* S_offd_j = (S_offd)->j;
  hypre_ParCSRMatrix* P;
  hypre_CSRMatrix* P_diag;
  hypre_CSRMatrix* P_offd;
  double* P_diag_data = (void*)0;
  int* P_diag_i;
  int* P_diag_j = (void*)0;
  double* P_offd_data = (void*)0;
  int* P_offd_i;
  int* P_offd_j = (void*)0;
  int* col_map_offd_P;
  int* tmp_map_offd;
  int P_diag_size;
  int P_offd_size;
  int* P_marker = (void*)0;
  int* P_marker_offd = (void*)0;
  int* CF_marker_offd = (void*)0;
  int* tmp_CF_marker_offd = (void*)0;
  int* dof_func_offd = (void*)0;
  hypre_BigCSRMatrix* A_ext;
  double* A_ext_data;
  int* A_ext_i;
  int* big_A_ext_j;
  int* A_ext_j;
  int* fine_to_coarse = (void*)0;
  int* fine_to_coarse_offd = (void*)0;
  int* found;
  int num_cols_P_offd;
  int newoff;
  int loc_col;
  int A_ext_rows;
  int full_off_procNodes;
  hypre_BigCSRMatrix* Sop;
  int* Sop_i;
  int* big_Sop_j;
  int* Sop_j;
  int Soprows;
  int sgn;
  int* jj_count;
  int* jj_count_offd;
  int jj_counter;
  int jj_counter_offd;
  int jj_begin_row;
  int jj_end_row;
  int jj_begin_row_offd = 0;
  int jj_end_row_offd = 0;
  int* coarse_counter;
  int coarse_counter_offd;
  double sum;
  double diagonal;
  double distribute;
  int strong_f_marker = -2;
  int index;
  int start_indexing = 0;
  int i;
  int i1;
  int i2;
  int j;
  int jj;
  int kk;
  int k1;
  int jj1;
  double zero = 0.0;
  double one = 1.0;
  double wall_time;
  int size;
  int rest;
  int ns;
  int ne;
  int num_threads;
  int coarse_shift;
  hypre_ParCSRCommPkg* extend_comm_pkg = (void*)0;
  if (debug_flag == 4)
    wall_time = time_getWallclockSeconds();
  MPI_Comm_size(comm, &(num_procs));
  MPI_Comm_rank(comm, &(my_id));
  num_threads = 1;
  my_first_cpt = num_cpts_global[my_id];
  total_global_cpts = num_cpts_global[num_procs];
  if (!comm_pkg) {
    hypre_MatvecCommPkgCreate(A);
    comm_pkg = (A)->comm_pkg;
  }
  newoff = 0;
  full_off_procNodes = 0;
  if (num_procs > 1) {
    A_ext = hypre_ParCSRMatrixExtractBigExt(A, A, 1);
    A_ext_i = (A_ext)->i;
    big_A_ext_j = (A_ext)->j;
    A_ext_data = (A_ext)->data;
    A_ext_rows = (A_ext)->num_rows;
    Sop = hypre_ParCSRMatrixExtractBigExt(S, A, 0);
    Sop_i = (Sop)->i;
    big_Sop_j = (Sop)->j;
    Soprows = (Sop)->num_rows;
    newoff = new_offd_nodes(&(found), A_ext_rows, A_ext_i, big_A_ext_j, &(A_ext_j), Soprows, col_map_offd, col_1, col_n, Sop_i, big_Sop_j, &(Sop_j), CF_marker, comm_pkg);
    (A_ext)->j = (void*)0;
    (Sop)->j = (void*)0;
    if (newoff >= 0)
      full_off_procNodes = newoff + num_cols_A_offd;
    else
      return 1;
    hypre_ParCSRFindExtendCommPkg(A, newoff, found, &(extend_comm_pkg));
    CF_marker_offd = (int*)(hypre_CAlloc((unsigned)full_off_procNodes, (unsigned)(sizeof(int))));
    if ((num_functions > 1) && (full_off_procNodes > 0))
      dof_func_offd = (int*)(hypre_CAlloc((unsigned)full_off_procNodes, (unsigned)(sizeof(int))));
    alt_insert_new_nodes(comm_pkg, extend_comm_pkg, CF_marker, full_off_procNodes, CF_marker_offd);
    if (num_functions > 1)
      alt_insert_new_nodes(comm_pkg, extend_comm_pkg, dof_func, full_off_procNodes, dof_func_offd);
  }
  P_diag_i = (int*)(hypre_CAlloc((unsigned)(n_fine + 1), (unsigned)(sizeof(int))));
  P_offd_i = (int*)(hypre_CAlloc((unsigned)(n_fine + 1), (unsigned)(sizeof(int))));
  if (n_fine) {
    fine_to_coarse = (int*)(hypre_CAlloc((unsigned)n_fine, (unsigned)(sizeof(int))));
  }
  if (full_off_procNodes) {
    fine_to_coarse_offd = (int*)(hypre_CAlloc((unsigned)full_off_procNodes, (unsigned)(sizeof(int))));
    tmp_CF_marker_offd = (int*)(hypre_CAlloc((unsigned)full_off_procNodes, (unsigned)(sizeof(int))));
  }
  for (i = 0; i < full_off_procNodes; i++) {
    tmp_CF_marker_offd[i] = -1;
    fine_to_coarse_offd[i] = -1;
  }
  coarse_counter = (int*)(hypre_CAlloc((unsigned)num_threads, (unsigned)(sizeof(int))));
  jj_count = (int*)(hypre_CAlloc((unsigned)num_threads, (unsigned)(sizeof(int))));
  jj_count_offd = (int*)(hypre_CAlloc((unsigned)num_threads, (unsigned)(sizeof(int))));
  jj_counter = start_indexing;
  jj_counter_offd = start_indexing;
  coarse_counter_offd = 0;
  for (j = 0; j < num_threads; j++) {
    size = n_fine / num_threads;
    rest = n_fine - (size * num_threads);
    jj_count[j] = 0;
    jj_count_offd[j] = 0;
    coarse_counter[j] = 0;
    if (n_fine) {
      P_marker = (int*)(hypre_CAlloc((unsigned)n_fine, (unsigned)(sizeof(int))));
      for (i = 0; i < n_fine; i++)
        P_marker[i] = -1;
    }
    if (full_off_procNodes) {
      P_marker_offd = (int*)(hypre_CAlloc((unsigned)full_off_procNodes, (unsigned)(sizeof(int))));
      for (i = 0; i < full_off_procNodes; i++)
        P_marker_offd[i] = -1;
    }
    if (j < rest) {
      ns = (j * size) + j;
      ne = (((j + 1) * size) + j) + 1;
    }
    else {
      ns = (j * size) + rest;
      ne = ((j + 1) * size) + rest;
    }
    for (i = ns; i < ne; i++) {
      P_diag_i[i] = jj_count[j];
      if (num_procs > 1)
        P_offd_i[i] = jj_count_offd[j];
      fine_to_coarse[i] = -1;
      if ((CF_marker[i]) >= 0) {
        jj_count[j]++;
        fine_to_coarse[i] = coarse_counter[j];
        coarse_counter[j]++;
      }
      else
        if ((CF_marker[i]) != (-3)) {
          for (jj = S_diag_i[i]; jj < (S_diag_i[i + 1]); jj++) {
            i1 = S_diag_j[jj];
            if ((CF_marker[i1]) > 0) {
              if ((P_marker[i1]) < (P_diag_i[i])) {
                P_marker[i1] = jj_count[j];
                jj_count[j]++;
              }
            }
            else
              if ((CF_marker[i1]) != (-3)) {
                for (kk = S_diag_i[i1]; kk < (S_diag_i[i1 + 1]); kk++) {
                  k1 = S_diag_j[kk];
                  if ((CF_marker[k1]) > 0) {
                    if ((P_marker[k1]) < (P_diag_i[i])) {
                      P_marker[k1] = jj_count[j];
                      jj_count[j]++;
                    }
                  }
                }
                if (num_procs > 1) {
                  for (kk = S_offd_i[i1]; kk < (S_offd_i[i1 + 1]); kk++) {
                    if (col_offd_S_to_A)
                      k1 = col_offd_S_to_A[S_offd_j[kk]];
                    else
                      k1 = S_offd_j[kk];
                    if ((CF_marker_offd[k1]) > 0) {
                      if ((P_marker_offd[k1]) < (P_offd_i[i])) {
                        tmp_CF_marker_offd[k1] = 1;
                        P_marker_offd[k1] = jj_count_offd[j];
                        jj_count_offd[j]++;
                      }
                    }
                  }
                }
              }
          }
          if (num_procs > 1) {
            for (jj = S_offd_i[i]; jj < (S_offd_i[i + 1]); jj++) {
              i1 = S_offd_j[jj];
              if (col_offd_S_to_A)
                i1 = col_offd_S_to_A[i1];
              if ((CF_marker_offd[i1]) > 0) {
                if ((P_marker_offd[i1]) < (P_offd_i[i])) {
                  tmp_CF_marker_offd[i1] = 1;
                  P_marker_offd[i1] = jj_count_offd[j];
                  jj_count_offd[j]++;
                }
              }
              else
                if ((CF_marker_offd[i1]) != (-3)) {
                  for (kk = Sop_i[i1]; kk < (Sop_i[i1 + 1]); kk++) {
                    loc_col = Sop_j[kk];
                    if (loc_col > (-1)) {
                      if ((CF_marker[loc_col]) > 0) {
                        if ((P_marker[loc_col]) < (P_diag_i[i])) {
                          P_marker[loc_col] = jj_count[j];
                          jj_count[j]++;
                        }
                      }
                    }
                    else {
                      loc_col = (-loc_col) - 1;
                      if ((CF_marker_offd[loc_col]) > 0) {
                        if ((P_marker_offd[loc_col]) < (P_offd_i[i])) {
                          P_marker_offd[loc_col] = jj_count_offd[j];
                          tmp_CF_marker_offd[loc_col] = 1;
                          jj_count_offd[j]++;
                        }
                      }
                    }
                  }
                }
            }
          }
        }
    }
    if (n_fine)
      hypre_Free((char*)P_marker), P_marker = (void*)0;
    if (full_off_procNodes)
      hypre_Free((char*)P_marker_offd), P_marker_offd = (void*)0;
  }
  for (i = 0; i < (num_threads - 1); i++) {
    coarse_counter[i + 1] += coarse_counter[i];
    jj_count[i + 1] += jj_count[i];
    jj_count_offd[i + 1] += jj_count_offd[i];
  }
  i = num_threads - 1;
  jj_counter = jj_count[i];
  jj_counter_offd = jj_count_offd[i];
  if (debug_flag == 4) {
    wall_time = time_getWallclockSeconds() - wall_time;
    printf("Proc = %d     determine structure    %f\n", my_id, wall_time);
    fflush((void*)0);
  }
  if (debug_flag == 4)
    wall_time = time_getWallclockSeconds();
  P_diag_size = jj_counter;
  P_offd_size = jj_counter_offd;
  if (P_diag_size) {
    P_diag_j = (int*)(hypre_CAlloc((unsigned)P_diag_size, (unsigned)(sizeof(int))));
    P_diag_data = (double*)(hypre_CAlloc((unsigned)P_diag_size, (unsigned)(sizeof(double))));
  }
  if (P_offd_size) {
    P_offd_j = (int*)(hypre_CAlloc((unsigned)P_offd_size, (unsigned)(sizeof(int))));
    P_offd_data = (double*)(hypre_CAlloc((unsigned)P_offd_size, (unsigned)(sizeof(double))));
  }
  P_diag_i[n_fine] = jj_counter;
  P_offd_i[n_fine] = jj_counter_offd;
  jj_counter = start_indexing;
  jj_counter_offd = start_indexing;
  for (j = 0; j < num_threads; j++) {
    coarse_shift = 0;
    if (j > 0)
      coarse_shift = coarse_counter[j - 1];
    size = n_fine / num_threads;
    rest = n_fine - (size * num_threads);
    if (j < rest) {
      ns = (j * size) + j;
      ne = (((j + 1) * size) + j) + 1;
    }
    else {
      ns = (j * size) + rest;
      ne = ((j + 1) * size) + rest;
    }
    for (i = ns; i < ne; i++)
      fine_to_coarse[i] += coarse_shift;
  }
  if (num_procs > 1) {
    big_insert_new_nodes(comm_pkg, extend_comm_pkg, fine_to_coarse, full_off_procNodes, my_first_cpt, fine_to_coarse_offd);
  }
  for (j = 0; j < num_threads; j++) {
    size = n_fine / num_threads;
    rest = n_fine - (size * num_threads);
    strong_f_marker = -2;
    if (n_fine) {
      P_marker = (int*)(hypre_CAlloc((unsigned)n_fine, (unsigned)(sizeof(int))));
      for (i = 0; i < n_fine; i++)
        P_marker[i] = -1;
    }
    jj_counter = 0;
    if (j > 0)
      jj_counter = jj_count[j - 1];
    jj_counter_offd = 0;
    if (j > 0)
      jj_counter_offd = jj_count_offd[j - 1];
    if (full_off_procNodes) {
      P_marker_offd = (int*)(hypre_CAlloc((unsigned)full_off_procNodes, (unsigned)(sizeof(int))));
      for (i = 0; i < full_off_procNodes; i++)
        P_marker_offd[i] = -1;
    }
    if (j < rest) {
      ns = (j * size) + j;
      ne = (((j + 1) * size) + j) + 1;
    }
    else {
      ns = (j * size) + rest;
      ne = ((j + 1) * size) + rest;
    }
    for (i = ns; i < ne; i++) {
      jj_begin_row = jj_counter;
      jj_begin_row_offd = jj_counter_offd;
      P_diag_i[i] = jj_counter;
      if (num_procs > 1)
        P_offd_i[i] = jj_counter_offd;
      if ((CF_marker[i]) >= 0) {
        P_diag_j[jj_counter] = fine_to_coarse[i];
        P_diag_data[jj_counter] = one;
        jj_counter++;
      }
      else
        if ((CF_marker[i]) != (-3)) {
          strong_f_marker--;
          for (jj = S_diag_i[i]; jj < (S_diag_i[i + 1]); jj++) {
            i1 = S_diag_j[jj];
            if ((CF_marker[i1]) >= 0) {
              if ((P_marker[i1]) < jj_begin_row) {
                P_marker[i1] = jj_counter;
                P_diag_j[jj_counter] = fine_to_coarse[i1];
                P_diag_data[jj_counter] = zero;
                jj_counter++;
              }
            }
            else
              if ((CF_marker[i1]) != (-3)) {
                P_marker[i1] = strong_f_marker;
                for (kk = S_diag_i[i1]; kk < (S_diag_i[i1 + 1]); kk++) {
                  k1 = S_diag_j[kk];
                  if ((CF_marker[k1]) > 0) {
                    if ((P_marker[k1]) < jj_begin_row) {
                      P_marker[k1] = jj_counter;
                      P_diag_j[jj_counter] = fine_to_coarse[k1];
                      P_diag_data[jj_counter] = zero;
                      jj_counter++;
                    }
                  }
                }
                if (num_procs > 1) {
                  for (kk = S_offd_i[i1]; kk < (S_offd_i[i1 + 1]); kk++) {
                    if (col_offd_S_to_A)
                      k1 = col_offd_S_to_A[S_offd_j[kk]];
                    else
                      k1 = S_offd_j[kk];
                    if ((CF_marker_offd[k1]) > 0) {
                      if ((P_marker_offd[k1]) < jj_begin_row_offd) {
                        P_marker_offd[k1] = jj_counter_offd;
                        P_offd_j[jj_counter_offd] = k1;
                        P_offd_data[jj_counter_offd] = zero;
                        jj_counter_offd++;
                      }
                    }
                  }
                }
              }
          }
          if (num_procs > 1) {
            for (jj = S_offd_i[i]; jj < (S_offd_i[i + 1]); jj++) {
              i1 = S_offd_j[jj];
              if (col_offd_S_to_A)
                i1 = col_offd_S_to_A[i1];
              if ((CF_marker_offd[i1]) > 0) {
                if ((P_marker_offd[i1]) < jj_begin_row_offd) {
                  P_marker_offd[i1] = jj_counter_offd;
                  P_offd_j[jj_counter_offd] = i1;
                  P_offd_data[jj_counter_offd] = zero;
                  jj_counter_offd++;
                }
              }
              else
                if ((CF_marker_offd[i1]) != (-3)) {
                  P_marker_offd[i1] = strong_f_marker;
                  for (kk = Sop_i[i1]; kk < (Sop_i[i1 + 1]); kk++) {
                    loc_col = Sop_j[kk];
                    if (loc_col > (-1)) {
                      if ((CF_marker[loc_col]) > 0) {
                        if ((P_marker[loc_col]) < jj_begin_row) {
                          P_marker[loc_col] = jj_counter;
                          P_diag_j[jj_counter] = fine_to_coarse[loc_col];
                          P_diag_data[jj_counter] = zero;
                          jj_counter++;
                        }
                      }
                    }
                    else {
                      loc_col = (-loc_col) - 1;
                      if ((CF_marker_offd[loc_col]) > 0) {
                        if ((P_marker_offd[loc_col]) < jj_begin_row_offd) {
                          P_marker_offd[loc_col] = jj_counter_offd;
                          P_offd_j[jj_counter_offd] = loc_col;
                          P_offd_data[jj_counter_offd] = zero;
                          jj_counter_offd++;
                        }
                      }
                    }
                  }
                }
            }
          }
          jj_end_row = jj_counter;
          jj_end_row_offd = jj_counter_offd;
          diagonal = A_diag_data[A_diag_i[i]];
          for (jj = (A_diag_i[i]) + 1; jj < (A_diag_i[i + 1]); jj++) {
            i1 = A_diag_j[jj];
            if ((P_marker[i1]) >= jj_begin_row) {
              P_diag_data[P_marker[i1]] += A_diag_data[jj];
            }
            else
              if ((P_marker[i1]) == strong_f_marker) {
                sum = zero;
                sgn = 1;
                if ((A_diag_data[A_diag_i[i1]]) < 0)
                  sgn = -1;
                for (jj1 = (A_diag_i[i1]) + 1; jj1 < (A_diag_i[i1 + 1]); jj1++) {
                  i2 = A_diag_j[jj1];
                  if ((((P_marker[i2]) >= jj_begin_row) || (i2 == i)) && ((sgn * (A_diag_data[jj1])) < 0))
                    sum += A_diag_data[jj1];
                }
                if (num_procs > 1) {
                  for (jj1 = A_offd_i[i1]; jj1 < (A_offd_i[i1 + 1]); jj1++) {
                    i2 = A_offd_j[jj1];
                    if (((P_marker_offd[i2]) >= jj_begin_row_offd) && ((sgn * (A_offd_data[jj1])) < 0))
                      sum += A_offd_data[jj1];
                  }
                }
                if (sum != 0) {
                  distribute = (A_diag_data[jj]) / sum;
                  for (jj1 = (A_diag_i[i1]) + 1; jj1 < (A_diag_i[i1 + 1]); jj1++) {
                    i2 = A_diag_j[jj1];
                    if (((P_marker[i2]) >= jj_begin_row) && ((sgn * (A_diag_data[jj1])) < 0))
                      P_diag_data[P_marker[i2]] += distribute * (A_diag_data[jj1]);
                    if ((i2 == i) && ((sgn * (A_diag_data[jj1])) < 0))
                      diagonal += distribute * (A_diag_data[jj1]);
                  }
                  if (num_procs > 1) {
                    for (jj1 = A_offd_i[i1]; jj1 < (A_offd_i[i1 + 1]); jj1++) {
                      i2 = A_offd_j[jj1];
                      if (((P_marker_offd[i2]) >= jj_begin_row_offd) && ((sgn * (A_offd_data[jj1])) < 0))
                        P_offd_data[P_marker_offd[i2]] += distribute * (A_offd_data[jj1]);
                    }
                  }
                }
                else {
                  diagonal += A_diag_data[jj];
                }
              }
              else
                if ((CF_marker[i1]) != (-3)) {
                  if ((num_functions == 1) || ((dof_func[i]) == (dof_func[i1])))
                    diagonal += A_diag_data[jj];
                }
          }
          if (num_procs > 1) {
            for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
              i1 = A_offd_j[jj];
              if ((P_marker_offd[i1]) >= jj_begin_row_offd)
                P_offd_data[P_marker_offd[i1]] += A_offd_data[jj];
              else
                if ((P_marker_offd[i1]) == strong_f_marker) {
                  sum = zero;
                  sgn = 1;
                  if ((A_ext_data[A_ext_i[i1]]) < 0)
                    sgn = -1;
                  for (jj1 = (A_ext_i[i1]) + 1; jj1 < (A_ext_i[i1 + 1]); jj1++) {
                    loc_col = A_ext_j[jj1];
                    if (loc_col > (-1)) {
                      if ((((P_marker[loc_col]) >= jj_begin_row) || (loc_col == i)) && ((sgn * (A_ext_data[jj1])) < 0))
                        sum += A_ext_data[jj1];
                    }
                    else {
                      loc_col = (-loc_col) - 1;
                      if (((P_marker_offd[loc_col]) >= jj_begin_row_offd) && ((sgn * (A_ext_data[jj1])) < 0))
                        sum += A_ext_data[jj1];
                    }
                  }
                  if (sum != 0) {
                    distribute = (A_offd_data[jj]) / sum;
                    for (jj1 = (A_ext_i[i1]) + 1; jj1 < (A_ext_i[i1 + 1]); jj1++) {
                      loc_col = A_ext_j[jj1];
                      if (loc_col > (-1)) {
                        if (((P_marker[loc_col]) >= jj_begin_row) && ((sgn * (A_ext_data[jj1])) < 0))
                          P_diag_data[P_marker[loc_col]] += distribute * (A_ext_data[jj1]);
                        if ((loc_col == i) && ((sgn * (A_ext_data[jj1])) < 0))
                          diagonal += distribute * (A_ext_data[jj1]);
                      }
                      else {
                        loc_col = (-loc_col) - 1;
                        if (((P_marker_offd[loc_col]) >= jj_begin_row_offd) && ((sgn * (A_ext_data[jj1])) < 0))
                          P_offd_data[P_marker_offd[loc_col]] += distribute * (A_ext_data[jj1]);
                      }
                    }
                  }
                  else {
                    diagonal += A_offd_data[jj];
                  }
                }
                else
                  if ((CF_marker_offd[i1]) != (-3)) {
                    if ((num_functions == 1) || ((dof_func[i]) == (dof_func_offd[i1])))
                      diagonal += A_offd_data[jj];
                  }
            }
          }
          for (jj = jj_begin_row; jj < jj_end_row; jj++)
            (P_diag_data[jj]) /= (-diagonal);
          for (jj = jj_begin_row_offd; jj < jj_end_row_offd; jj++)
            (P_offd_data[jj]) /= (-diagonal);
        }
      strong_f_marker--;
    }
    if (n_fine)
      hypre_Free((char*)P_marker), P_marker = (void*)0;
    if (full_off_procNodes)
      hypre_Free((char*)P_marker_offd), P_marker_offd = (void*)0;
  }
  if (debug_flag == 4) {
    wall_time = time_getWallclockSeconds() - wall_time;
    printf("Proc = %d     fill structure    %f\n", my_id, wall_time);
    fflush((void*)0);
  }
  P = hypre_ParCSRMatrixCreate(comm, (A)->global_num_rows, total_global_cpts, (A)->col_starts, num_cpts_global, 0, P_diag_i[n_fine], P_offd_i[n_fine]);
  P_diag = (P)->diag;
  (P_diag)->data = P_diag_data;
  (P_diag)->i = P_diag_i;
  (P_diag)->j = P_diag_j;
  P_offd = (P)->offd;
  (P_offd)->data = P_offd_data;
  (P_offd)->i = P_offd_i;
  (P_offd)->j = P_offd_j;
  (P)->owns_row_starts = 0;
  if ((trunc_factor != 0.0) || (max_elmts > 0)) {
    hypre_BoomerAMGInterpTruncation(P, trunc_factor, max_elmts);
    P_diag_data = (P_diag)->data;
    P_diag_i = (P_diag)->i;
    P_diag_j = (P_diag)->j;
    P_offd_data = (P_offd)->data;
    P_offd_i = (P_offd)->i;
    P_offd_j = (P_offd)->j;
    P_diag_size = P_diag_i[n_fine];
    P_offd_size = P_offd_i[n_fine];
  }
  num_cols_P_offd = 0;
  if (P_offd_size) {
    num_cols_P_offd = 0;
    for (i = 0; i < P_offd_size; i++) {
      index = P_offd_j[i];
      if ((tmp_CF_marker_offd[index]) == 1) {
        num_cols_P_offd++;
        tmp_CF_marker_offd[index] = 2;
      }
    }
    if (num_cols_P_offd) {
      col_map_offd_P = (int*)(hypre_CAlloc((unsigned)num_cols_P_offd, (unsigned)(sizeof(int))));
      tmp_map_offd = (int*)(hypre_CAlloc((unsigned)num_cols_P_offd, (unsigned)(sizeof(int))));
    }
    index = 0;
    for (i = 0; i < num_cols_P_offd; i++) {
      while ((tmp_CF_marker_offd[index]) != 2)
        index++;
      col_map_offd_P[i] = fine_to_coarse_offd[index];
      tmp_map_offd[i] = index++;
    }
    hypre_BigQsortbi(col_map_offd_P, tmp_map_offd, 0, num_cols_P_offd - 1);
    for (i = 0; i < num_cols_P_offd; i++)
      tmp_CF_marker_offd[tmp_map_offd[i]] = i;
    for (i = 0; i < P_offd_size; i++)
      P_offd_j[i] = tmp_CF_marker_offd[P_offd_j[i]];
  }
  if (num_cols_P_offd) {
    (P)->col_map_offd = col_map_offd_P;
    (P_offd)->num_cols = num_cols_P_offd;
    hypre_Free((char*)tmp_map_offd), tmp_map_offd = (void*)0;
  }
  hypre_MatvecCommPkgCreate(P);
  for (i = 0; i < n_fine; i++)
    if ((CF_marker[i]) == (-3))
      CF_marker[i] = -1;
  *P_ptr = P;
  hypre_Free((char*)fine_to_coarse), fine_to_coarse = (void*)0;
  hypre_Free((char*)jj_count), jj_count = (void*)0;
  hypre_Free((char*)jj_count_offd), jj_count_offd = (void*)0;
  hypre_Free((char*)coarse_counter), coarse_counter = (void*)0;
  if (num_procs > 1) {
    hypre_BigCSRMatrixDestroy(Sop);
    hypre_BigCSRMatrixDestroy(A_ext);
    hypre_Free((char*)fine_to_coarse_offd), fine_to_coarse_offd = (void*)0;
    hypre_Free((char*)CF_marker_offd), CF_marker_offd = (void*)0;
    hypre_Free((char*)tmp_CF_marker_offd), tmp_CF_marker_offd = (void*)0;
    if (num_functions > 1)
      hypre_Free((char*)dof_func_offd), dof_func_offd = (void*)0;
    hypre_Free((char*)found), found = (void*)0;
    hypre_MatvecCommPkgDestroy(extend_comm_pkg);
  }
  return hypre__global_error;
}
int hypre_BoomerAMGBuildExtPICCInterp(hypre_ParCSRMatrix* A, int* CF_marker, hypre_ParCSRMatrix* S, int* num_cpts_global, int num_functions, int* dof_func, int debug_flag, double trunc_factor, int max_elmts, int* col_offd_S_to_A, hypre_ParCSRMatrix** P_ptr) {
  MPI_Comm comm = (A)->comm;
  hypre_ParCSRCommPkg* comm_pkg = (A)->comm_pkg;
  int my_id;
  int num_procs;
  hypre_CSRMatrix* A_diag = (A)->diag;
  double* A_diag_data = (A_diag)->data;
  int* A_diag_i = (A_diag)->i;
  int* A_diag_j = (A_diag)->j;
  hypre_CSRMatrix* A_offd = (A)->offd;
  double* A_offd_data = (A_offd)->data;
  int* A_offd_i = (A_offd)->i;
  int* A_offd_j = (A_offd)->j;
  int num_cols_A_offd = (A_offd)->num_cols;
  int* col_map_offd = (A)->col_map_offd;
  int n_fine = (A_diag)->num_rows;
  int col_1 = (A)->first_row_index;
  int local_numrows = (A_diag)->num_rows;
  int col_n = col_1 + (int)local_numrows;
  int total_global_cpts;
  int my_first_cpt;
  hypre_CSRMatrix* S_diag = (S)->diag;
  int* S_diag_i = (S_diag)->i;
  int* S_diag_j = (S_diag)->j;
  hypre_CSRMatrix* S_offd = (S)->offd;
  int* S_offd_i = (S_offd)->i;
  int* S_offd_j = (S_offd)->j;
  hypre_ParCSRMatrix* P;
  hypre_CSRMatrix* P_diag;
  hypre_CSRMatrix* P_offd;
  double* P_diag_data = (void*)0;
  int* P_diag_i;
  int* P_diag_j = (void*)0;
  double* P_offd_data = (void*)0;
  int* P_offd_i;
  int* P_offd_j = (void*)0;
  int* col_map_offd_P;
  int* tmp_map_offd;
  int P_diag_size;
  int P_offd_size;
  int* P_marker = (void*)0;
  int* P_marker_offd = (void*)0;
  int* CF_marker_offd = (void*)0;
  int* tmp_CF_marker_offd = (void*)0;
  int* dof_func_offd = (void*)0;
  int ccounter_offd;
  int common_c;
  hypre_BigCSRMatrix* A_ext;
  double* A_ext_data;
  int* A_ext_i;
  int* big_A_ext_j;
  int* A_ext_j;
  int* fine_to_coarse = (void*)0;
  int* fine_to_coarse_offd = (void*)0;
  int* found;
  int num_cols_P_offd;
  int newoff;
  int loc_col;
  int A_ext_rows;
  int full_off_procNodes;
  hypre_BigCSRMatrix* Sop;
  int* Sop_i;
  int* big_Sop_j;
  int* Sop_j;
  int Soprows;
  int sgn;
  int jj_counter;
  int jj_counter_offd;
  int jj_begin_row;
  int jj_end_row;
  int jj_begin_row_offd = 0;
  int jj_end_row_offd = 0;
  int coarse_counter;
  int coarse_counter_offd;
  double sum;
  double diagonal;
  double distribute;
  int strong_f_marker = -2;
  int index;
  int start_indexing = 0;
  int i;
  int i1;
  int i2;
  int jj;
  int kk;
  int k1;
  int jj1;
  int ccounter;
  double zero = 0.0;
  double one = 1.0;
  hypre_ParCSRCommPkg* extend_comm_pkg = (void*)0;
  MPI_Comm_size(comm, &(num_procs));
  MPI_Comm_rank(comm, &(my_id));
  my_first_cpt = num_cpts_global[my_id];
  total_global_cpts = num_cpts_global[num_procs];
  if (!comm_pkg) {
    hypre_MatvecCommPkgCreate(A);
    comm_pkg = (A)->comm_pkg;
  }
  newoff = 0;
  full_off_procNodes = 0;
  if (num_procs > 1) {
    A_ext = hypre_ParCSRMatrixExtractBigExt(A, A, 1);
    A_ext_i = (A_ext)->i;
    big_A_ext_j = (A_ext)->j;
    A_ext_data = (A_ext)->data;
    A_ext_rows = (A_ext)->num_rows;
    Sop = hypre_ParCSRMatrixExtractBigExt(S, A, 0);
    Sop_i = (Sop)->i;
    big_Sop_j = (Sop)->j;
    Soprows = (Sop)->num_rows;
    newoff = new_offd_nodes(&(found), A_ext_rows, A_ext_i, big_A_ext_j, &(A_ext_j), Soprows, col_map_offd, col_1, col_n, Sop_i, big_Sop_j, &(Sop_j), CF_marker, comm_pkg);
    (A_ext)->j = (void*)0;
    (Sop)->j = (void*)0;
    if (newoff >= 0)
      full_off_procNodes = newoff + num_cols_A_offd;
    else
      return 1;
    hypre_ParCSRFindExtendCommPkg(A, newoff, found, &(extend_comm_pkg));
    CF_marker_offd = (int*)(hypre_CAlloc((unsigned)full_off_procNodes, (unsigned)(sizeof(int))));
    if ((num_functions > 1) && (full_off_procNodes > 0))
      dof_func_offd = (int*)(hypre_CAlloc((unsigned)full_off_procNodes, (unsigned)(sizeof(int))));
    alt_insert_new_nodes(comm_pkg, extend_comm_pkg, CF_marker, full_off_procNodes, CF_marker_offd);
    if (num_functions > 1)
      alt_insert_new_nodes(comm_pkg, extend_comm_pkg, dof_func, full_off_procNodes, dof_func_offd);
  }
  P_diag_i = (int*)(hypre_CAlloc((unsigned)(n_fine + 1), (unsigned)(sizeof(int))));
  P_offd_i = (int*)(hypre_CAlloc((unsigned)(n_fine + 1), (unsigned)(sizeof(int))));
  if (n_fine) {
    fine_to_coarse = (int*)(hypre_CAlloc((unsigned)n_fine, (unsigned)(sizeof(int))));
    P_marker = (int*)(hypre_CAlloc((unsigned)n_fine, (unsigned)(sizeof(int))));
  }
  if (full_off_procNodes) {
    P_marker_offd = (int*)(hypre_CAlloc((unsigned)full_off_procNodes, (unsigned)(sizeof(int))));
    fine_to_coarse_offd = (int*)(hypre_CAlloc((unsigned)full_off_procNodes, (unsigned)(sizeof(int))));
    tmp_CF_marker_offd = (int*)(hypre_CAlloc((unsigned)full_off_procNodes, (unsigned)(sizeof(int))));
  }
  for (i = 0; i < full_off_procNodes; i++) {
    P_marker_offd[i] = -1;
    tmp_CF_marker_offd[i] = -1;
    fine_to_coarse_offd[i] = -1;
  }
  for (i = 0; i < n_fine; i++) {
    P_marker[i] = -1;
    fine_to_coarse[i] = -1;
  }
  jj_counter = start_indexing;
  jj_counter_offd = start_indexing;
  coarse_counter = 0;
  coarse_counter_offd = 0;
  for (i = 0; i < n_fine; i++) {
    P_diag_i[i] = jj_counter;
    if (num_procs > 1)
      P_offd_i[i] = jj_counter_offd;
    if ((CF_marker[i]) > 0) {
      jj_counter++;
      fine_to_coarse[i] = coarse_counter;
      coarse_counter++;
    }
    else
      if ((CF_marker[i]) != (-3)) {
        ccounter = 0;
        ccounter_offd = 0;
        for (jj = S_diag_i[i]; jj < (S_diag_i[i + 1]); jj++) {
          i1 = S_diag_j[jj];
          if ((CF_marker[i1]) > 0) {
            CF_marker[i1] = 2;
            if ((P_marker[i1]) < (P_diag_i[i])) {
              P_marker[i1] = jj_counter;
              jj_counter++;
            }
          }
        }
        if (num_procs > 1) {
          for (jj = S_offd_i[i]; jj < (S_offd_i[i + 1]); jj++) {
            if (col_offd_S_to_A)
              i1 = col_offd_S_to_A[S_offd_j[jj]];
            else
              i1 = S_offd_j[jj];
            if ((CF_marker_offd[i1]) > 0) {
              CF_marker_offd[i1] = 2;
              if ((P_marker_offd[i1]) < (P_offd_i[i])) {
                tmp_CF_marker_offd[i1] = 1;
                P_marker_offd[i1] = jj_counter_offd;
                jj_counter_offd++;
              }
            }
          }
        }
        for (jj = S_diag_i[i]; jj < (S_diag_i[i + 1]); jj++) {
          i1 = S_diag_j[jj];
          if ((CF_marker[i1]) == (-1)) {
            common_c = 0;
            for (kk = S_diag_i[i1]; kk < (S_diag_i[i1 + 1]); kk++) {
              k1 = S_diag_j[kk];
              if ((CF_marker[k1]) == 2) {
                common_c = 1;
                break;
              }
            }
            if ((num_procs > 1) && (common_c == 0)) {
              for (kk = S_offd_i[i1]; kk < (S_offd_i[i1 + 1]); kk++) {
                if (col_offd_S_to_A)
                  k1 = col_offd_S_to_A[S_offd_j[kk]];
                else
                  k1 = S_offd_j[kk];
                if ((CF_marker_offd[k1]) == 2) {
                  common_c = 1;
                  break;
                }
              }
            }
            if (!common_c) {
              for (kk = S_diag_i[i1]; kk < (S_diag_i[i1 + 1]); kk++) {
                k1 = S_diag_j[kk];
                if ((CF_marker[k1]) > 0) {
                  if ((P_marker[k1]) < (P_diag_i[i])) {
                    P_marker[k1] = jj_counter;
                    jj_counter++;
                  }
                }
              }
              if (num_procs > 1) {
                for (kk = S_offd_i[i1]; kk < (S_offd_i[i1 + 1]); kk++) {
                  if (col_offd_S_to_A)
                    k1 = col_offd_S_to_A[S_offd_j[kk]];
                  else
                    k1 = S_offd_j[kk];
                  if ((CF_marker_offd[k1]) > 0) {
                    if ((P_marker_offd[k1]) < (P_offd_i[i])) {
                      tmp_CF_marker_offd[k1] = 1;
                      P_marker_offd[k1] = jj_counter_offd;
                      jj_counter_offd++;
                    }
                  }
                }
              }
            }
          }
        }
        if (num_procs > 1) {
          for (jj = S_offd_i[i]; jj < (S_offd_i[i + 1]); jj++) {
            i1 = S_offd_j[jj];
            if (col_offd_S_to_A)
              i1 = col_offd_S_to_A[i1];
            if ((CF_marker_offd[i1]) == (-1)) {
              common_c = 0;
              for (kk = Sop_i[i1]; kk < (Sop_i[i1 + 1]); kk++) {
                loc_col = Sop_j[kk];
                if (loc_col > (-1)) {
                  if ((CF_marker[loc_col]) == 2) {
                    common_c = 1;
                    break;
                  }
                }
                else {
                  loc_col = (-loc_col) - 1;
                  if ((CF_marker_offd[loc_col]) == 2) {
                    common_c = 1;
                    break;
                  }
                }
              }
              if (!common_c) {
                for (kk = Sop_i[i1]; kk < (Sop_i[i1 + 1]); kk++) {
                  loc_col = Sop_j[kk];
                  if (loc_col > (-1)) {
                    if ((CF_marker[loc_col]) > 0) {
                      if ((P_marker[loc_col]) < (P_diag_i[i])) {
                        P_marker[loc_col] = jj_counter;
                        jj_counter++;
                      }
                    }
                  }
                  else {
                    loc_col = (-loc_col) - 1;
                    if ((CF_marker_offd[loc_col]) > 0) {
                      if ((P_marker_offd[loc_col]) < (P_offd_i[i])) {
                        P_marker_offd[loc_col] = jj_counter_offd;
                        tmp_CF_marker_offd[loc_col] = 1;
                        jj_counter_offd++;
                      }
                    }
                  }
                }
              }
            }
          }
        }
        for (jj = S_diag_i[i]; jj < (S_diag_i[i + 1]); jj++) {
          i1 = S_diag_j[jj];
          if ((CF_marker[i1]) == 2)
            CF_marker[i1] = 1;
        }
        if (num_procs > 1) {
          for (jj = S_offd_i[i]; jj < (S_offd_i[i + 1]); jj++) {
            if (col_offd_S_to_A)
              i1 = col_offd_S_to_A[S_offd_j[jj]];
            else
              i1 = S_offd_j[jj];
            if ((CF_marker_offd[i1]) == 2) {
              CF_marker_offd[i1] = 1;
            }
          }
        }
      }
  }
  P_diag_size = jj_counter;
  P_offd_size = jj_counter_offd;
  if (P_diag_size) {
    P_diag_j = (int*)(hypre_CAlloc((unsigned)P_diag_size, (unsigned)(sizeof(int))));
    P_diag_data = (double*)(hypre_CAlloc((unsigned)P_diag_size, (unsigned)(sizeof(double))));
  }
  if (P_offd_size) {
    P_offd_j = (int*)(hypre_CAlloc((unsigned)P_offd_size, (unsigned)(sizeof(int))));
    P_offd_data = (double*)(hypre_CAlloc((unsigned)P_offd_size, (unsigned)(sizeof(double))));
  }
  P_diag_i[n_fine] = jj_counter;
  P_offd_i[n_fine] = jj_counter_offd;
  jj_counter = start_indexing;
  jj_counter_offd = start_indexing;
  ccounter = start_indexing;
  ccounter_offd = start_indexing;
  if (num_procs > 1) {
    big_insert_new_nodes(comm_pkg, extend_comm_pkg, fine_to_coarse, full_off_procNodes, my_first_cpt, fine_to_coarse_offd);
  }
  for (i = 0; i < n_fine; i++)
    P_marker[i] = -1;
  for (i = 0; i < full_off_procNodes; i++)
    P_marker_offd[i] = -1;
  for (i = 0; i < n_fine; i++) {
    jj_begin_row = jj_counter;
    if (num_procs > 1)
      jj_begin_row_offd = jj_counter_offd;
    if ((CF_marker[i]) >= 0) {
      P_diag_j[jj_counter] = fine_to_coarse[i];
      P_diag_data[jj_counter] = one;
      jj_counter++;
    }
    else
      if ((CF_marker[i]) != (-3)) {
        ccounter = 0;
        ccounter_offd = 0;
        strong_f_marker--;
        for (jj = S_diag_i[i]; jj < (S_diag_i[i + 1]); jj++) {
          i1 = S_diag_j[jj];
          if ((CF_marker[i1]) > 0) {
            CF_marker[i1] = 2;
            if ((P_marker[i1]) < jj_begin_row) {
              P_marker[i1] = jj_counter;
              P_diag_j[jj_counter] = fine_to_coarse[i1];
              P_diag_data[jj_counter] = zero;
              jj_counter++;
            }
          }
        }
        if (num_procs > 1) {
          for (jj = S_offd_i[i]; jj < (S_offd_i[i + 1]); jj++) {
            if (col_offd_S_to_A)
              i1 = col_offd_S_to_A[S_offd_j[jj]];
            else
              i1 = S_offd_j[jj];
            if ((CF_marker_offd[i1]) > 0) {
              CF_marker_offd[i1] = 2;
              if ((P_marker_offd[i1]) < jj_begin_row_offd) {
                P_marker_offd[i1] = jj_counter_offd;
                P_offd_j[jj_counter_offd] = i1;
                P_offd_data[jj_counter_offd] = zero;
                jj_counter_offd++;
              }
            }
          }
        }
        for (jj = S_diag_i[i]; jj < (S_diag_i[i + 1]); jj++) {
          i1 = S_diag_j[jj];
          if ((CF_marker[i1]) == (-1)) {
            P_marker[i1] = strong_f_marker;
            common_c = 0;
            for (kk = S_diag_i[i1]; kk < (S_diag_i[i1 + 1]); kk++) {
              k1 = S_diag_j[kk];
              if ((CF_marker[k1]) == 2) {
                common_c = 1;
                break;
              }
            }
            if ((num_procs > 1) && (common_c == 0)) {
              for (kk = S_offd_i[i1]; kk < (S_offd_i[i1 + 1]); kk++) {
                if (col_offd_S_to_A)
                  k1 = col_offd_S_to_A[S_offd_j[kk]];
                else
                  k1 = S_offd_j[kk];
                if ((CF_marker_offd[k1]) == 2) {
                  common_c = 1;
                  break;
                }
              }
            }
            if (!common_c) {
              for (kk = S_diag_i[i1]; kk < (S_diag_i[i1 + 1]); kk++) {
                k1 = S_diag_j[kk];
                if ((CF_marker[k1]) >= 0) {
                  if ((P_marker[k1]) < jj_begin_row) {
                    P_marker[k1] = jj_counter;
                    P_diag_j[jj_counter] = fine_to_coarse[k1];
                    P_diag_data[jj_counter] = zero;
                    jj_counter++;
                  }
                }
              }
              if (num_procs > 1) {
                for (kk = S_offd_i[i1]; kk < (S_offd_i[i1 + 1]); kk++) {
                  if (col_offd_S_to_A)
                    k1 = col_offd_S_to_A[S_offd_j[kk]];
                  else
                    k1 = S_offd_j[kk];
                  if ((CF_marker_offd[k1]) >= 0) {
                    if ((P_marker_offd[k1]) < jj_begin_row_offd) {
                      P_marker_offd[k1] = jj_counter_offd;
                      P_offd_j[jj_counter_offd] = k1;
                      P_offd_data[jj_counter_offd] = zero;
                      jj_counter_offd++;
                    }
                  }
                }
              }
            }
          }
        }
        if (num_procs > 1) {
          for (jj = S_offd_i[i]; jj < (S_offd_i[i + 1]); jj++) {
            i1 = S_offd_j[jj];
            if (col_offd_S_to_A)
              i1 = col_offd_S_to_A[i1];
            if ((CF_marker_offd[i1]) == (-1)) {
              P_marker_offd[i1] = strong_f_marker;
              common_c = 0;
              for (kk = Sop_i[i1]; kk < (Sop_i[i1 + 1]); kk++) {
                loc_col = Sop_j[kk];
                if (loc_col > (-1)) {
                  if ((CF_marker[loc_col]) == 2) {
                    common_c = 1;
                    break;
                  }
                }
                else {
                  loc_col = (-loc_col) - 1;
                  if ((CF_marker_offd[loc_col]) == 2) {
                    common_c = 1;
                    break;
                  }
                }
              }
              if (!common_c) {
                for (kk = Sop_i[i1]; kk < (Sop_i[i1 + 1]); kk++) {
                  loc_col = Sop_j[kk];
                  if (loc_col > (-1)) {
                    if ((CF_marker[loc_col]) > 0) {
                      if ((P_marker[loc_col]) < jj_begin_row) {
                        P_marker[loc_col] = jj_counter;
                        P_diag_j[jj_counter] = fine_to_coarse[loc_col];
                        P_diag_data[jj_counter] = zero;
                        jj_counter++;
                      }
                    }
                  }
                  else {
                    loc_col = (-loc_col) - 1;
                    if ((CF_marker_offd[loc_col]) > 0) {
                      if ((P_marker_offd[loc_col]) < jj_begin_row_offd) {
                        P_marker_offd[loc_col] = jj_counter_offd;
                        P_offd_j[jj_counter_offd] = loc_col;
                        P_offd_data[jj_counter_offd] = zero;
                        jj_counter_offd++;
                      }
                    }
                  }
                }
              }
            }
          }
        }
        for (jj = S_diag_i[i]; jj < (S_diag_i[i + 1]); jj++) {
          i1 = S_diag_j[jj];
          if ((CF_marker[i1]) == 2) {
            CF_marker[i1] = 1;
          }
        }
        if (num_procs > 1) {
          for (jj = S_offd_i[i]; jj < (S_offd_i[i + 1]); jj++) {
            if (col_offd_S_to_A)
              i1 = col_offd_S_to_A[S_offd_j[jj]];
            else
              i1 = S_offd_j[jj];
            if ((CF_marker_offd[i1]) == 2) {
              CF_marker_offd[i1] = 1;
            }
          }
        }
        jj_end_row = jj_counter;
        jj_end_row_offd = jj_counter_offd;
        diagonal = A_diag_data[A_diag_i[i]];
        for (jj = (A_diag_i[i]) + 1; jj < (A_diag_i[i + 1]); jj++) {
          i1 = A_diag_j[jj];
          if ((P_marker[i1]) >= jj_begin_row) {
            P_diag_data[P_marker[i1]] += A_diag_data[jj];
          }
          else
            if ((P_marker[i1]) == strong_f_marker) {
              sum = zero;
              sgn = 1;
              if ((A_diag_data[A_diag_i[i1]]) < 0)
                sgn = -1;
              for (jj1 = (A_diag_i[i1]) + 1; jj1 < (A_diag_i[i1 + 1]); jj1++) {
                i2 = A_diag_j[jj1];
                if ((((P_marker[i2]) >= jj_begin_row) || (i2 == i)) && ((sgn * (A_diag_data[jj1])) < 0))
                  sum += A_diag_data[jj1];
              }
              if (num_procs > 1) {
                for (jj1 = A_offd_i[i1]; jj1 < (A_offd_i[i1 + 1]); jj1++) {
                  i2 = A_offd_j[jj1];
                  if (((P_marker_offd[i2]) >= jj_begin_row_offd) && ((sgn * (A_offd_data[jj1])) < 0))
                    sum += A_offd_data[jj1];
                }
              }
              if (sum != 0) {
                distribute = (A_diag_data[jj]) / sum;
                for (jj1 = A_diag_i[i1]; jj1 < (A_diag_i[i1 + 1]); jj1++) {
                  i2 = A_diag_j[jj1];
                  if (((P_marker[i2]) >= jj_begin_row) && ((sgn * (A_diag_data[jj1])) < 0))
                    P_diag_data[P_marker[i2]] += distribute * (A_diag_data[jj1]);
                  if ((i2 == i) && ((sgn * (A_diag_data[jj1])) < 0))
                    diagonal += distribute * (A_diag_data[jj1]);
                }
                if (num_procs > 1) {
                  for (jj1 = A_offd_i[i1]; jj1 < (A_offd_i[i1 + 1]); jj1++) {
                    i2 = A_offd_j[jj1];
                    if (((P_marker_offd[i2]) >= jj_begin_row_offd) && ((sgn * (A_offd_data[jj1])) < 0))
                      P_offd_data[P_marker_offd[i2]] += distribute * (A_offd_data[jj1]);
                  }
                }
              }
              else
                diagonal += A_diag_data[jj];
            }
            else
              if ((CF_marker[i1]) != (-3)) {
                if ((num_functions == 1) || ((dof_func[i]) == (dof_func[i1])))
                  diagonal += A_diag_data[jj];
              }
        }
        if (num_procs > 1) {
          for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
            i1 = A_offd_j[jj];
            if ((P_marker_offd[i1]) >= jj_begin_row_offd)
              P_offd_data[P_marker_offd[i1]] += A_offd_data[jj];
            else
              if ((P_marker_offd[i1]) == strong_f_marker) {
                sum = zero;
                sgn = 1;
                if ((A_ext_data[A_ext_i[i1]]) < 0)
                  sgn = -1;
                for (jj1 = (A_ext_i[i1]) + 1; jj1 < (A_ext_i[i1 + 1]); jj1++) {
                  loc_col = A_ext_j[jj1];
                  if (loc_col > (-1)) {
                    if ((((P_marker[loc_col]) >= jj_begin_row) || (loc_col == i)) && ((sgn * (A_ext_data[jj1])) < 0))
                      sum += A_ext_data[jj1];
                  }
                  else {
                    loc_col = (-loc_col) - 1;
                    if (((P_marker_offd[loc_col]) >= jj_begin_row_offd) && ((sgn * (A_ext_data[jj1])) < 0))
                      sum += A_ext_data[jj1];
                  }
                }
                if (sum != 0) {
                  distribute = (A_offd_data[jj]) / sum;
                  for (jj1 = (A_ext_i[i1]) + 1; jj1 < (A_ext_i[i1 + 1]); jj1++) {
                    loc_col = A_ext_j[jj1];
                    if (loc_col > (-1)) {
                      if (((P_marker[loc_col]) >= jj_begin_row) && ((sgn * (A_ext_data[jj1])) < 0))
                        P_diag_data[P_marker[loc_col]] += distribute * (A_ext_data[jj1]);
                      if ((loc_col == i) && ((sgn * (A_ext_data[jj1])) < 0))
                        diagonal += distribute * (A_ext_data[jj1]);
                    }
                    else {
                      loc_col = (-loc_col) - 1;
                      if (((P_marker_offd[loc_col]) >= jj_begin_row_offd) && ((sgn * (A_ext_data[jj1])) < 0))
                        P_offd_data[P_marker_offd[loc_col]] += distribute * (A_ext_data[jj1]);
                    }
                  }
                }
                else
                  diagonal += A_offd_data[jj];
              }
              else
                if ((CF_marker_offd[i1]) != (-3)) {
                  if ((num_functions == 1) || ((dof_func[i]) == (dof_func_offd[i1])))
                    diagonal += A_offd_data[jj];
                }
          }
        }
        for (jj = jj_begin_row; jj < jj_end_row; jj++)
          (P_diag_data[jj]) /= (-diagonal);
        for (jj = jj_begin_row_offd; jj < jj_end_row_offd; jj++)
          (P_offd_data[jj]) /= (-diagonal);
      }
    strong_f_marker--;
  }
  P = hypre_ParCSRMatrixCreate(comm, (A)->global_num_rows, total_global_cpts, (A)->col_starts, num_cpts_global, 0, P_diag_i[n_fine], P_offd_i[n_fine]);
  P_diag = (P)->diag;
  (P_diag)->data = P_diag_data;
  (P_diag)->i = P_diag_i;
  (P_diag)->j = P_diag_j;
  P_offd = (P)->offd;
  (P_offd)->data = P_offd_data;
  (P_offd)->i = P_offd_i;
  (P_offd)->j = P_offd_j;
  (P)->owns_row_starts = 0;
  if ((trunc_factor != 0.0) || (max_elmts > 0)) {
    hypre_BoomerAMGInterpTruncation(P, trunc_factor, max_elmts);
    P_diag_data = (P_diag)->data;
    P_diag_i = (P_diag)->i;
    P_diag_j = (P_diag)->j;
    P_offd_data = (P_offd)->data;
    P_offd_i = (P_offd)->i;
    P_offd_j = (P_offd)->j;
    P_diag_size = P_diag_i[n_fine];
    P_offd_size = P_offd_i[n_fine];
  }
  num_cols_P_offd = 0;
  if (P_offd_size) {
    num_cols_P_offd = 0;
    for (i = 0; i < P_offd_size; i++) {
      index = P_offd_j[i];
      if ((tmp_CF_marker_offd[index]) == 1) {
        num_cols_P_offd++;
        tmp_CF_marker_offd[index] = 2;
      }
    }
    if (num_cols_P_offd) {
      col_map_offd_P = (int*)(hypre_CAlloc((unsigned)num_cols_P_offd, (unsigned)(sizeof(int))));
      tmp_map_offd = (int*)(hypre_CAlloc((unsigned)num_cols_P_offd, (unsigned)(sizeof(int))));
    }
    index = 0;
    for (i = 0; i < num_cols_P_offd; i++) {
      while ((tmp_CF_marker_offd[index]) != 2)
        index++;
      col_map_offd_P[i] = fine_to_coarse_offd[index];
      tmp_map_offd[i] = index++;
    }
    hypre_BigQsortbi(col_map_offd_P, tmp_map_offd, 0, num_cols_P_offd - 1);
    for (i = 0; i < num_cols_P_offd; i++)
      tmp_CF_marker_offd[tmp_map_offd[i]] = i;
    for (i = 0; i < P_offd_size; i++)
      P_offd_j[i] = tmp_CF_marker_offd[P_offd_j[i]];
  }
  if (num_cols_P_offd) {
    (P)->col_map_offd = col_map_offd_P;
    (P_offd)->num_cols = num_cols_P_offd;
    hypre_Free((char*)tmp_map_offd), tmp_map_offd = (void*)0;
  }
  hypre_MatvecCommPkgCreate(P);
  for (i = 0; i < n_fine; i++)
    if ((CF_marker[i]) == (-3))
      CF_marker[i] = -1;
  *P_ptr = P;
  hypre_Free((char*)fine_to_coarse), fine_to_coarse = (void*)0;
  hypre_Free((char*)P_marker), P_marker = (void*)0;
  if (num_procs > 1) {
    hypre_BigCSRMatrixDestroy(Sop);
    hypre_BigCSRMatrixDestroy(A_ext);
    hypre_Free((char*)fine_to_coarse_offd), fine_to_coarse_offd = (void*)0;
    hypre_Free((char*)P_marker_offd), P_marker_offd = (void*)0;
    hypre_Free((char*)CF_marker_offd), CF_marker_offd = (void*)0;
    hypre_Free((char*)tmp_CF_marker_offd), tmp_CF_marker_offd = (void*)0;
    if (num_functions > 1)
      hypre_Free((char*)dof_func_offd), dof_func_offd = (void*)0;
    hypre_Free((char*)found), found = (void*)0;
    hypre_MatvecCommPkgDestroy(extend_comm_pkg);
  }
  return hypre__global_error;
}
int hypre_BoomerAMGBuildFF1Interp(hypre_ParCSRMatrix* A, int* CF_marker, hypre_ParCSRMatrix* S, int* num_cpts_global, int num_functions, int* dof_func, int debug_flag, double trunc_factor, int max_elmts, int* col_offd_S_to_A, hypre_ParCSRMatrix** P_ptr) {
  MPI_Comm comm = (A)->comm;
  hypre_ParCSRCommPkg* comm_pkg = (A)->comm_pkg;
  int my_id;
  int num_procs;
  hypre_CSRMatrix* A_diag = (A)->diag;
  double* A_diag_data = (A_diag)->data;
  int* A_diag_i = (A_diag)->i;
  int* A_diag_j = (A_diag)->j;
  hypre_CSRMatrix* A_offd = (A)->offd;
  double* A_offd_data = (A_offd)->data;
  int* A_offd_i = (A_offd)->i;
  int* A_offd_j = (A_offd)->j;
  int num_cols_A_offd = (A_offd)->num_cols;
  int* col_map_offd = (A)->col_map_offd;
  int n_fine = (A_diag)->num_rows;
  int col_1 = (A)->first_row_index;
  int local_numrows = (A_diag)->num_rows;
  int col_n = col_1 + (int)local_numrows;
  int total_global_cpts;
  int my_first_cpt;
  hypre_CSRMatrix* S_diag = (S)->diag;
  int* S_diag_i = (S_diag)->i;
  int* S_diag_j = (S_diag)->j;
  hypre_CSRMatrix* S_offd = (S)->offd;
  int* S_offd_i = (S_offd)->i;
  int* S_offd_j = (S_offd)->j;
  hypre_ParCSRMatrix* P;
  hypre_CSRMatrix* P_diag;
  hypre_CSRMatrix* P_offd;
  double* P_diag_data = (void*)0;
  int* P_diag_i;
  int* P_diag_j = (void*)0;
  double* P_offd_data = (void*)0;
  int* P_offd_i;
  int* P_offd_j = (void*)0;
  int* col_map_offd_P;
  int* tmp_map_offd;
  int P_diag_size;
  int P_offd_size;
  int* P_marker = (void*)0;
  int* P_marker_offd = (void*)0;
  int* CF_marker_offd = (void*)0;
  int* tmp_CF_marker_offd = (void*)0;
  int* dof_func_offd = (void*)0;
  int ccounter_offd;
  int common_c;
  hypre_BigCSRMatrix* A_ext;
  double* A_ext_data;
  int* A_ext_i;
  int* big_A_ext_j;
  int* A_ext_j;
  int* fine_to_coarse = (void*)0;
  int* fine_to_coarse_offd = (void*)0;
  int* found;
  int num_cols_P_offd;
  int newoff;
  int loc_col;
  int A_ext_rows;
  int full_off_procNodes;
  hypre_BigCSRMatrix* Sop;
  int* Sop_i;
  int* big_Sop_j;
  int* Sop_j;
  int Soprows;
  int jj_counter;
  int jj_counter_offd;
  int jj_begin_row;
  int jj_end_row;
  int jj_begin_row_offd = 0;
  int jj_end_row_offd = 0;
  int coarse_counter;
  int coarse_counter_offd;
  double sum;
  double diagonal;
  double distribute;
  int strong_f_marker = -2;
  int sgn;
  int index;
  int start_indexing = 0;
  int i;
  int i1;
  int i2;
  int jj;
  int kk;
  int k1;
  int jj1;
  int ccounter;
  int found_c = 0;
  double zero = 0.0;
  double one = 1.0;
  hypre_ParCSRCommPkg* extend_comm_pkg = (void*)0;
  MPI_Comm_size(comm, &(num_procs));
  MPI_Comm_rank(comm, &(my_id));
  my_first_cpt = num_cpts_global[my_id];
  total_global_cpts = num_cpts_global[num_procs];
  if (!comm_pkg) {
    hypre_MatvecCommPkgCreate(A);
    comm_pkg = (A)->comm_pkg;
  }
  newoff = 0;
  full_off_procNodes = 0;
  if (num_procs > 1) {
    A_ext = hypre_ParCSRMatrixExtractBigExt(A, A, 1);
    A_ext_i = (A_ext)->i;
    big_A_ext_j = (A_ext)->j;
    A_ext_data = (A_ext)->data;
    A_ext_rows = (A_ext)->num_rows;
    Sop = hypre_ParCSRMatrixExtractBigExt(S, A, 0);
    Sop_i = (Sop)->i;
    big_Sop_j = (Sop)->j;
    Soprows = (Sop)->num_rows;
    newoff = new_offd_nodes(&(found), A_ext_rows, A_ext_i, big_A_ext_j, &(A_ext_j), Soprows, col_map_offd, col_1, col_n, Sop_i, big_Sop_j, &(Sop_j), CF_marker, comm_pkg);
    (A_ext)->j = (void*)0;
    (Sop)->j = (void*)0;
    if (newoff >= 0)
      full_off_procNodes = newoff + num_cols_A_offd;
    else
      return 1;
    hypre_ParCSRFindExtendCommPkg(A, newoff, found, &(extend_comm_pkg));
    CF_marker_offd = (int*)(hypre_CAlloc((unsigned)full_off_procNodes, (unsigned)(sizeof(int))));
    if ((num_functions > 1) && (full_off_procNodes > 0))
      dof_func_offd = (int*)(hypre_CAlloc((unsigned)full_off_procNodes, (unsigned)(sizeof(int))));
    alt_insert_new_nodes(comm_pkg, extend_comm_pkg, CF_marker, full_off_procNodes, CF_marker_offd);
    if (num_functions > 1)
      alt_insert_new_nodes(comm_pkg, extend_comm_pkg, dof_func, full_off_procNodes, dof_func_offd);
  }
  P_diag_i = (int*)(hypre_CAlloc((unsigned)(n_fine + 1), (unsigned)(sizeof(int))));
  P_offd_i = (int*)(hypre_CAlloc((unsigned)(n_fine + 1), (unsigned)(sizeof(int))));
  if (n_fine) {
    fine_to_coarse = (int*)(hypre_CAlloc((unsigned)n_fine, (unsigned)(sizeof(int))));
    P_marker = (int*)(hypre_CAlloc((unsigned)n_fine, (unsigned)(sizeof(int))));
  }
  if (full_off_procNodes) {
    P_marker_offd = (int*)(hypre_CAlloc((unsigned)full_off_procNodes, (unsigned)(sizeof(int))));
    fine_to_coarse_offd = (int*)(hypre_CAlloc((unsigned)full_off_procNodes, (unsigned)(sizeof(int))));
    tmp_CF_marker_offd = (int*)(hypre_CAlloc((unsigned)full_off_procNodes, (unsigned)(sizeof(int))));
  }
  for (i = 0; i < full_off_procNodes; i++) {
    P_marker_offd[i] = -1;
    tmp_CF_marker_offd[i] = -1;
    fine_to_coarse_offd[i] = -1;
  }
  for (i = 0; i < n_fine; i++) {
    P_marker[i] = -1;
    fine_to_coarse[i] = -1;
  }
  jj_counter = start_indexing;
  jj_counter_offd = start_indexing;
  coarse_counter = 0;
  coarse_counter_offd = 0;
  for (i = 0; i < n_fine; i++) {
    P_diag_i[i] = jj_counter;
    if (num_procs > 1)
      P_offd_i[i] = jj_counter_offd;
    if ((CF_marker[i]) >= 0) {
      jj_counter++;
      fine_to_coarse[i] = coarse_counter;
      coarse_counter++;
    }
    else {
      ccounter = 0;
      ccounter_offd = 0;
      for (jj = S_diag_i[i]; jj < (S_diag_i[i + 1]); jj++) {
        i1 = S_diag_j[jj];
        if ((CF_marker[i1]) > 0) {
          CF_marker[i1] = 2;
          if ((P_marker[i1]) < (P_diag_i[i])) {
            P_marker[i1] = jj_counter;
            jj_counter++;
          }
        }
      }
      if (num_procs > 1) {
        for (jj = S_offd_i[i]; jj < (S_offd_i[i + 1]); jj++) {
          if (col_offd_S_to_A)
            i1 = col_offd_S_to_A[S_offd_j[jj]];
          else
            i1 = S_offd_j[jj];
          if ((CF_marker_offd[i1]) > 0) {
            CF_marker_offd[i1] = 2;
            if ((P_marker_offd[i1]) < (P_offd_i[i])) {
              tmp_CF_marker_offd[i1] = 1;
              P_marker_offd[i1] = jj_counter_offd;
              jj_counter_offd++;
            }
          }
        }
      }
      for (jj = S_diag_i[i]; jj < (S_diag_i[i + 1]); jj++) {
        i1 = S_diag_j[jj];
        if ((CF_marker[i1]) < 0) {
          common_c = 0;
          for (kk = S_diag_i[i1]; kk < (S_diag_i[i1 + 1]); kk++) {
            k1 = S_diag_j[kk];
            if ((CF_marker[k1]) == 2) {
              common_c = 1;
              break;
            }
          }
          if ((num_procs > 1) && (common_c == 0)) {
            for (kk = S_offd_i[i1]; kk < (S_offd_i[i1 + 1]); kk++) {
              if (col_offd_S_to_A)
                k1 = col_offd_S_to_A[S_offd_j[kk]];
              else
                k1 = S_offd_j[kk];
              if ((CF_marker_offd[k1]) == 2) {
                common_c = 1;
                break;
              }
            }
          }
          if (!common_c) {
            found_c = 0;
            for (kk = S_diag_i[i1]; kk < (S_diag_i[i1 + 1]); kk++) {
              k1 = S_diag_j[kk];
              if ((CF_marker[k1]) > 0) {
                if ((P_marker[k1]) < (P_diag_i[i])) {
                  P_marker[k1] = jj_counter;
                  jj_counter++;
                  found_c = 1;
                  break;
                }
              }
            }
            if ((num_procs > 1) && (!found_c)) {
              for (kk = S_offd_i[i1]; kk < (S_offd_i[i1 + 1]); kk++) {
                if (col_offd_S_to_A)
                  k1 = col_offd_S_to_A[S_offd_j[kk]];
                else
                  k1 = S_offd_j[kk];
                if ((CF_marker_offd[k1]) > 0) {
                  if ((P_marker_offd[k1]) < (P_offd_i[i])) {
                    tmp_CF_marker_offd[k1] = 1;
                    P_marker_offd[k1] = jj_counter_offd;
                    jj_counter_offd++;
                    break;
                  }
                }
              }
            }
          }
        }
      }
      if (num_procs > 1) {
        for (jj = S_offd_i[i]; jj < (S_offd_i[i + 1]); jj++) {
          i1 = S_offd_j[jj];
          if (col_offd_S_to_A)
            i1 = col_offd_S_to_A[i1];
          if ((CF_marker_offd[i1]) < 0) {
            common_c = 0;
            for (kk = Sop_i[i1]; kk < (Sop_i[i1 + 1]); kk++) {
              loc_col = Sop_j[kk];
              if (loc_col > (-1)) {
                if ((CF_marker[loc_col]) == 2) {
                  common_c = 1;
                  break;
                }
              }
              else {
                loc_col = (-loc_col) - 1;
                if ((CF_marker_offd[loc_col]) == 2) {
                  common_c = 1;
                  break;
                }
              }
            }
            if (!common_c) {
              for (kk = Sop_i[i1]; kk < (Sop_i[i1 + 1]); kk++) {
                loc_col = Sop_j[kk];
                if (loc_col > (-1)) {
                  if ((CF_marker[loc_col]) > 0) {
                    if ((P_marker[loc_col]) < (P_diag_i[i])) {
                      P_marker[loc_col] = jj_counter;
                      jj_counter++;
                      break;
                    }
                  }
                }
                else {
                  loc_col = (-loc_col) - 1;
                  if ((CF_marker_offd[loc_col]) > 0) {
                    if ((P_marker_offd[loc_col]) < (P_offd_i[i])) {
                      P_marker_offd[loc_col] = jj_counter_offd;
                      tmp_CF_marker_offd[loc_col] = 1;
                      jj_counter_offd++;
                      break;
                    }
                  }
                }
              }
            }
          }
        }
      }
      for (jj = S_diag_i[i]; jj < (S_diag_i[i + 1]); jj++) {
        i1 = S_diag_j[jj];
        if ((CF_marker[i1]) == 2)
          CF_marker[i1] = 1;
      }
      if (num_procs > 1) {
        for (jj = S_offd_i[i]; jj < (S_offd_i[i + 1]); jj++) {
          if (col_offd_S_to_A)
            i1 = col_offd_S_to_A[S_offd_j[jj]];
          else
            i1 = S_offd_j[jj];
          if ((CF_marker_offd[i1]) == 2) {
            CF_marker_offd[i1] = 1;
          }
        }
      }
    }
  }
  P_diag_size = jj_counter;
  P_offd_size = jj_counter_offd;
  if (P_diag_size) {
    P_diag_j = (int*)(hypre_CAlloc((unsigned)P_diag_size, (unsigned)(sizeof(int))));
    P_diag_data = (double*)(hypre_CAlloc((unsigned)P_diag_size, (unsigned)(sizeof(double))));
  }
  if (P_offd_size) {
    P_offd_j = (int*)(hypre_CAlloc((unsigned)P_offd_size, (unsigned)(sizeof(int))));
    P_offd_data = (double*)(hypre_CAlloc((unsigned)P_offd_size, (unsigned)(sizeof(double))));
  }
  P_diag_i[n_fine] = jj_counter;
  P_offd_i[n_fine] = jj_counter_offd;
  jj_counter = start_indexing;
  jj_counter_offd = start_indexing;
  ccounter = start_indexing;
  ccounter_offd = start_indexing;
  if (num_procs > 1) {
    big_insert_new_nodes(comm_pkg, extend_comm_pkg, fine_to_coarse, full_off_procNodes, my_first_cpt, fine_to_coarse_offd);
  }
  for (i = 0; i < n_fine; i++)
    P_marker[i] = -1;
  for (i = 0; i < full_off_procNodes; i++)
    P_marker_offd[i] = -1;
  jj_begin_row_offd = 0;
  for (i = 0; i < n_fine; i++) {
    jj_begin_row = jj_counter;
    if (num_procs > 1)
      jj_begin_row_offd = jj_counter_offd;
    if ((CF_marker[i]) > 0) {
      P_diag_j[jj_counter] = fine_to_coarse[i];
      P_diag_data[jj_counter] = one;
      jj_counter++;
    }
    else
      if ((CF_marker[i]) != (-3)) {
        ccounter = 0;
        ccounter_offd = 0;
        strong_f_marker--;
        for (jj = S_diag_i[i]; jj < (S_diag_i[i + 1]); jj++) {
          i1 = S_diag_j[jj];
          if ((CF_marker[i1]) > 0) {
            CF_marker[i1] = 2;
            if ((P_marker[i1]) < jj_begin_row) {
              P_marker[i1] = jj_counter;
              P_diag_j[jj_counter] = fine_to_coarse[i1];
              P_diag_data[jj_counter] = zero;
              jj_counter++;
            }
          }
        }
        if (num_procs > 1) {
          for (jj = S_offd_i[i]; jj < (S_offd_i[i + 1]); jj++) {
            if (col_offd_S_to_A)
              i1 = col_offd_S_to_A[S_offd_j[jj]];
            else
              i1 = S_offd_j[jj];
            if ((CF_marker_offd[i1]) > 0) {
              CF_marker_offd[i1] = 2;
              if ((P_marker_offd[i1]) < jj_begin_row_offd) {
                P_marker_offd[i1] = jj_counter_offd;
                P_offd_j[jj_counter_offd] = i1;
                P_offd_data[jj_counter_offd] = zero;
                jj_counter_offd++;
              }
            }
          }
        }
        for (jj = S_diag_i[i]; jj < (S_diag_i[i + 1]); jj++) {
          i1 = S_diag_j[jj];
          if ((CF_marker[i1]) == (-1)) {
            P_marker[i1] = strong_f_marker;
            common_c = 0;
            for (kk = S_diag_i[i1]; kk < (S_diag_i[i1 + 1]); kk++) {
              k1 = S_diag_j[kk];
              if ((CF_marker[k1]) == 2) {
                common_c = 1;
                break;
              }
            }
            if ((num_procs > 1) && (common_c == 0)) {
              for (kk = S_offd_i[i1]; kk < (S_offd_i[i1 + 1]); kk++) {
                if (col_offd_S_to_A)
                  k1 = col_offd_S_to_A[S_offd_j[kk]];
                else
                  k1 = S_offd_j[kk];
                if ((CF_marker_offd[k1]) == 2) {
                  common_c = 1;
                  break;
                }
              }
            }
            if (!common_c) {
              found_c = 0;
              for (kk = S_diag_i[i1]; kk < (S_diag_i[i1 + 1]); kk++) {
                k1 = S_diag_j[kk];
                if ((CF_marker[k1]) >= 0) {
                  if ((P_marker[k1]) < jj_begin_row) {
                    P_marker[k1] = jj_counter;
                    P_diag_j[jj_counter] = fine_to_coarse[k1];
                    P_diag_data[jj_counter] = zero;
                    jj_counter++;
                    found_c = 1;
                    break;
                  }
                }
              }
              if ((num_procs > 1) && (!found_c)) {
                for (kk = S_offd_i[i1]; kk < (S_offd_i[i1 + 1]); kk++) {
                  if (col_offd_S_to_A)
                    k1 = col_offd_S_to_A[S_offd_j[kk]];
                  else
                    k1 = S_offd_j[kk];
                  if ((CF_marker_offd[k1]) >= 0) {
                    if ((P_marker_offd[k1]) < jj_begin_row_offd) {
                      P_marker_offd[k1] = jj_counter_offd;
                      P_offd_j[jj_counter_offd] = k1;
                      P_offd_data[jj_counter_offd] = zero;
                      jj_counter_offd++;
                      break;
                    }
                  }
                }
              }
            }
          }
        }
        if (num_procs > 1) {
          for (jj = S_offd_i[i]; jj < (S_offd_i[i + 1]); jj++) {
            i1 = S_offd_j[jj];
            if (col_offd_S_to_A)
              i1 = col_offd_S_to_A[i1];
            if ((CF_marker_offd[i1]) == (-1)) {
              P_marker_offd[i1] = strong_f_marker;
              common_c = 0;
              for (kk = Sop_i[i1]; kk < (Sop_i[i1 + 1]); kk++) {
                loc_col = Sop_j[kk];
                if (loc_col > (-1)) {
                  if ((CF_marker[loc_col]) == 2) {
                    common_c = 1;
                    break;
                  }
                }
                else {
                  loc_col = (-loc_col) - 1;
                  if ((CF_marker_offd[loc_col]) == 2) {
                    common_c = 1;
                    break;
                  }
                }
              }
              if (!common_c) {
                for (kk = Sop_i[i1]; kk < (Sop_i[i1 + 1]); kk++) {
                  loc_col = Sop_j[kk];
                  if (loc_col > (-1)) {
                    if ((CF_marker[loc_col]) > 0) {
                      if ((P_marker[loc_col]) < jj_begin_row) {
                        P_marker[loc_col] = jj_counter;
                        P_diag_j[jj_counter] = fine_to_coarse[loc_col];
                        P_diag_data[jj_counter] = zero;
                        jj_counter++;
                        break;
                      }
                    }
                  }
                  else {
                    loc_col = (-loc_col) - 1;
                    if ((CF_marker_offd[loc_col]) > 0) {
                      if ((P_marker_offd[loc_col]) < jj_begin_row_offd) {
                        P_marker_offd[loc_col] = jj_counter_offd;
                        P_offd_j[jj_counter_offd] = loc_col;
                        P_offd_data[jj_counter_offd] = zero;
                        jj_counter_offd++;
                        break;
                      }
                    }
                  }
                }
              }
            }
          }
        }
        for (jj = S_diag_i[i]; jj < (S_diag_i[i + 1]); jj++) {
          i1 = S_diag_j[jj];
          if ((CF_marker[i1]) == 2) {
            CF_marker[i1] = 1;
          }
        }
        if (num_procs > 1) {
          for (jj = S_offd_i[i]; jj < (S_offd_i[i + 1]); jj++) {
            if (col_offd_S_to_A)
              i1 = col_offd_S_to_A[S_offd_j[jj]];
            else
              i1 = S_offd_j[jj];
            if ((CF_marker_offd[i1]) == 2) {
              CF_marker_offd[i1] = 1;
            }
          }
        }
        jj_end_row = jj_counter;
        jj_end_row_offd = jj_counter_offd;
        diagonal = A_diag_data[A_diag_i[i]];
        for (jj = (A_diag_i[i]) + 1; jj < (A_diag_i[i + 1]); jj++) {
          i1 = A_diag_j[jj];
          if ((P_marker[i1]) >= jj_begin_row) {
            P_diag_data[P_marker[i1]] += A_diag_data[jj];
          }
          else
            if ((P_marker[i1]) == strong_f_marker) {
              sum = zero;
              if ((A_diag_data[A_diag_i[i1]]) < 0)
                sgn = -1;
              for (jj1 = A_diag_i[i1]; jj1 < (A_diag_i[i1 + 1]); jj1++) {
                i2 = A_diag_j[jj1];
                if (((P_marker[i2]) >= jj_begin_row) && ((sgn * (A_diag_data[jj1])) < 0))
                  sum += A_diag_data[jj1];
              }
              if (num_procs > 1) {
                for (jj1 = A_offd_i[i1]; jj1 < (A_offd_i[i1 + 1]); jj1++) {
                  i2 = A_offd_j[jj1];
                  if (((P_marker_offd[i2]) >= jj_begin_row_offd) && ((sgn * (A_offd_data[jj1])) < 0))
                    sum += A_offd_data[jj1];
                }
              }
              if (sum != 0) {
                distribute = (A_diag_data[jj]) / sum;
                for (jj1 = A_diag_i[i1]; jj1 < (A_diag_i[i1 + 1]); jj1++) {
                  i2 = A_diag_j[jj1];
                  if (((P_marker[i2]) >= jj_begin_row) && ((sgn * (A_diag_data[jj1])) < 0))
                    P_diag_data[P_marker[i2]] += distribute * (A_diag_data[jj1]);
                }
                if (num_procs > 1) {
                  for (jj1 = A_offd_i[i1]; jj1 < (A_offd_i[i1 + 1]); jj1++) {
                    i2 = A_offd_j[jj1];
                    if (((P_marker_offd[i2]) >= jj_begin_row_offd) && ((sgn * (A_offd_data[jj1])) < 0))
                      P_offd_data[P_marker_offd[i2]] += distribute * (A_offd_data[jj1]);
                  }
                }
              }
              else
                diagonal += A_diag_data[jj];
            }
            else
              if ((CF_marker[i1]) != (-3)) {
                if ((num_functions == 1) || ((dof_func[i]) == (dof_func[i1])))
                  diagonal += A_diag_data[jj];
              }
        }
        if (num_procs > 1) {
          for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
            i1 = A_offd_j[jj];
            if ((P_marker_offd[i1]) >= jj_begin_row_offd)
              P_offd_data[P_marker_offd[i1]] += A_offd_data[jj];
            else
              if ((P_marker_offd[i1]) == strong_f_marker) {
                sum = zero;
                sgn = 1;
                if ((A_ext_data[A_ext_i[i1]]) < 0)
                  sgn = -1;
                for (jj1 = (A_ext_i[i1]) + 1; jj1 < (A_ext_i[i1 + 1]); jj1++) {
                  loc_col = A_ext_j[jj1];
                  if (loc_col > (-1)) {
                    if (((P_marker[loc_col]) >= jj_begin_row) && ((sgn * (A_ext_data[jj1])) < 0))
                      sum += A_ext_data[jj1];
                  }
                  else {
                    loc_col = (-loc_col) - 1;
                    if (((P_marker_offd[loc_col]) >= jj_begin_row_offd) && ((sgn * (A_ext_data[jj1])) < 0))
                      sum += A_ext_data[jj1];
                  }
                }
                if (sum != 0) {
                  distribute = (A_offd_data[jj]) / sum;
                  for (jj1 = (A_ext_i[i1]) + 1; jj1 < (A_ext_i[i1 + 1]); jj1++) {
                    loc_col = A_ext_j[jj1];
                    if (loc_col > (-1)) {
                      if (((P_marker[loc_col]) >= jj_begin_row) && ((sgn * (A_ext_data[jj1])) < 0))
                        P_diag_data[P_marker[loc_col]] += distribute * (A_ext_data[jj1]);
                    }
                    else {
                      loc_col = (-loc_col) - 1;
                      if (((P_marker_offd[loc_col]) >= jj_begin_row_offd) && ((sgn * (A_ext_data[jj1])) < 0))
                        P_offd_data[P_marker_offd[loc_col]] += distribute * (A_ext_data[jj1]);
                    }
                  }
                }
                else
                  diagonal += A_offd_data[jj];
              }
              else
                if ((CF_marker_offd[i1]) != (-3)) {
                  if ((num_functions == 1) || ((dof_func[i]) == (dof_func_offd[i1])))
                    diagonal += A_offd_data[jj];
                }
          }
        }
        for (jj = jj_begin_row; jj < jj_end_row; jj++)
          (P_diag_data[jj]) /= (-diagonal);
        for (jj = jj_begin_row_offd; jj < jj_end_row_offd; jj++)
          (P_offd_data[jj]) /= (-diagonal);
      }
    strong_f_marker--;
  }
  P = hypre_ParCSRMatrixCreate(comm, (A)->global_num_rows, total_global_cpts, (A)->col_starts, num_cpts_global, 0, P_diag_i[n_fine], P_offd_i[n_fine]);
  P_diag = (P)->diag;
  (P_diag)->data = P_diag_data;
  (P_diag)->i = P_diag_i;
  (P_diag)->j = P_diag_j;
  P_offd = (P)->offd;
  (P_offd)->data = P_offd_data;
  (P_offd)->i = P_offd_i;
  (P_offd)->j = P_offd_j;
  (P)->owns_row_starts = 0;
  if ((trunc_factor != 0.0) || (max_elmts > 0)) {
    hypre_BoomerAMGInterpTruncation(P, trunc_factor, max_elmts);
    P_diag_data = (P_diag)->data;
    P_diag_i = (P_diag)->i;
    P_diag_j = (P_diag)->j;
    P_offd_data = (P_offd)->data;
    P_offd_i = (P_offd)->i;
    P_offd_j = (P_offd)->j;
    P_diag_size = P_diag_i[n_fine];
    P_offd_size = P_offd_i[n_fine];
  }
  num_cols_P_offd = 0;
  if (P_offd_size) {
    num_cols_P_offd = 0;
    for (i = 0; i < P_offd_size; i++) {
      index = P_offd_j[i];
      if ((tmp_CF_marker_offd[index]) == 1) {
        num_cols_P_offd++;
        tmp_CF_marker_offd[index] = 2;
      }
    }
    if (num_cols_P_offd) {
      col_map_offd_P = (int*)(hypre_CAlloc((unsigned)num_cols_P_offd, (unsigned)(sizeof(int))));
      tmp_map_offd = (int*)(hypre_CAlloc((unsigned)num_cols_P_offd, (unsigned)(sizeof(int))));
    }
    index = 0;
    for (i = 0; i < num_cols_P_offd; i++) {
      while ((tmp_CF_marker_offd[index]) == (-1))
        index++;
      col_map_offd_P[i] = fine_to_coarse_offd[index];
      tmp_map_offd[i] = index++;
    }
    hypre_BigQsortbi(col_map_offd_P, tmp_map_offd, 0, num_cols_P_offd - 1);
    for (i = 0; i < num_cols_P_offd; i++)
      tmp_CF_marker_offd[tmp_map_offd[i]] = i;
    for (i = 0; i < P_offd_size; i++)
      P_offd_j[i] = tmp_CF_marker_offd[P_offd_j[i]];
  }
  if (num_cols_P_offd) {
    (P)->col_map_offd = col_map_offd_P;
    (P_offd)->num_cols = num_cols_P_offd;
    hypre_Free((char*)tmp_map_offd), tmp_map_offd = (void*)0;
  }
  hypre_MatvecCommPkgCreate(P);
  for (i = 0; i < n_fine; i++)
    if ((CF_marker[i]) == (-3))
      CF_marker[i] = -1;
  *P_ptr = P;
  hypre_Free((char*)fine_to_coarse), fine_to_coarse = (void*)0;
  hypre_Free((char*)P_marker), P_marker = (void*)0;
  if (num_procs > 1) {
    hypre_BigCSRMatrixDestroy(Sop);
    hypre_BigCSRMatrixDestroy(A_ext);
    hypre_Free((char*)fine_to_coarse_offd), fine_to_coarse_offd = (void*)0;
    hypre_Free((char*)P_marker_offd), P_marker_offd = (void*)0;
    hypre_Free((char*)CF_marker_offd), CF_marker_offd = (void*)0;
    hypre_Free((char*)tmp_CF_marker_offd), tmp_CF_marker_offd = (void*)0;
    if (num_functions > 1)
      hypre_Free((char*)dof_func_offd), dof_func_offd = (void*)0;
    hypre_Free((char*)found), found = (void*)0;
    hypre_MatvecCommPkgDestroy(extend_comm_pkg);
  }
  return hypre__global_error;
}
int hypre_BoomerAMGBuildExtInterp(hypre_ParCSRMatrix* A, int* CF_marker, hypre_ParCSRMatrix* S, int* num_cpts_global, int num_functions, int* dof_func, int debug_flag, double trunc_factor, int max_elmts, int* col_offd_S_to_A, hypre_ParCSRMatrix** P_ptr) {
  MPI_Comm comm = (A)->comm;
  hypre_ParCSRCommPkg* comm_pkg = (A)->comm_pkg;
  int my_id;
  int num_procs;
  hypre_CSRMatrix* A_diag = (A)->diag;
  double* A_diag_data = (A_diag)->data;
  int* A_diag_i = (A_diag)->i;
  int* A_diag_j = (A_diag)->j;
  hypre_CSRMatrix* A_offd = (A)->offd;
  double* A_offd_data = (A_offd)->data;
  int* A_offd_i = (A_offd)->i;
  int* A_offd_j = (A_offd)->j;
  int num_cols_A_offd = (A_offd)->num_cols;
  int* col_map_offd = (A)->col_map_offd;
  int n_fine = (A_diag)->num_rows;
  int col_1 = (A)->first_row_index;
  int local_numrows = (A_diag)->num_rows;
  int col_n = col_1 + (int)local_numrows;
  int total_global_cpts;
  int my_first_cpt;
  hypre_CSRMatrix* S_diag = (S)->diag;
  int* S_diag_i = (S_diag)->i;
  int* S_diag_j = (S_diag)->j;
  hypre_CSRMatrix* S_offd = (S)->offd;
  int* S_offd_i = (S_offd)->i;
  int* S_offd_j = (S_offd)->j;
  hypre_ParCSRMatrix* P;
  hypre_CSRMatrix* P_diag;
  hypre_CSRMatrix* P_offd;
  double* P_diag_data = (void*)0;
  int* P_diag_i;
  int* P_diag_j = (void*)0;
  double* P_offd_data = (void*)0;
  int* P_offd_i;
  int* P_offd_j = (void*)0;
  int* col_map_offd_P;
  int* tmp_map_offd;
  int P_diag_size;
  int P_offd_size;
  int* P_marker = (void*)0;
  int* P_marker_offd = (void*)0;
  int* CF_marker_offd = (void*)0;
  int* tmp_CF_marker_offd = (void*)0;
  int* dof_func_offd = (void*)0;
  hypre_BigCSRMatrix* A_ext;
  double* A_ext_data;
  int* A_ext_i;
  int* big_A_ext_j;
  int* A_ext_j;
  int* fine_to_coarse = (void*)0;
  int* fine_to_coarse_offd = (void*)0;
  int* found;
  int num_cols_P_offd;
  int newoff;
  int loc_col;
  int A_ext_rows;
  int full_off_procNodes;
  hypre_BigCSRMatrix* Sop;
  int* Sop_i;
  int* big_Sop_j;
  int* Sop_j;
  int Soprows;
  int sgn;
  int jj_counter;
  int jj_counter_offd;
  int jj_begin_row;
  int jj_end_row;
  int jj_begin_row_offd = 0;
  int jj_end_row_offd = 0;
  int coarse_counter;
  int coarse_counter_offd;
  double sum;
  double diagonal;
  double distribute;
  int strong_f_marker = -2;
  int index;
  int start_indexing = 0;
  int i;
  int i1;
  int i2;
  int jj;
  int kk;
  int k1;
  int jj1;
  double zero = 0.0;
  double one = 1.0;
  double wall_time;
  hypre_ParCSRCommPkg* extend_comm_pkg = (void*)0;
  if (debug_flag == 4)
    wall_time = time_getWallclockSeconds();
  MPI_Comm_size(comm, &(num_procs));
  MPI_Comm_rank(comm, &(my_id));
  my_first_cpt = num_cpts_global[my_id];
  total_global_cpts = num_cpts_global[num_procs];
  if (!comm_pkg) {
    hypre_MatvecCommPkgCreate(A);
    comm_pkg = (A)->comm_pkg;
  }
  newoff = 0;
  full_off_procNodes = 0;
  if (num_procs > 1) {
    A_ext = hypre_ParCSRMatrixExtractBigExt(A, A, 1);
    A_ext_i = (A_ext)->i;
    big_A_ext_j = (A_ext)->j;
    A_ext_data = (A_ext)->data;
    A_ext_rows = (A_ext)->num_rows;
    Sop = hypre_ParCSRMatrixExtractBigExt(S, A, 0);
    Sop_i = (Sop)->i;
    big_Sop_j = (Sop)->j;
    Soprows = (Sop)->num_rows;
    newoff = new_offd_nodes(&(found), A_ext_rows, A_ext_i, big_A_ext_j, &(A_ext_j), Soprows, col_map_offd, col_1, col_n, Sop_i, big_Sop_j, &(Sop_j), CF_marker, comm_pkg);
    (A_ext)->j = (void*)0;
    (Sop)->j = (void*)0;
    if (newoff >= 0)
      full_off_procNodes = newoff + num_cols_A_offd;
    else
      return 1;
    hypre_ParCSRFindExtendCommPkg(A, newoff, found, &(extend_comm_pkg));
    CF_marker_offd = (int*)(hypre_CAlloc((unsigned)full_off_procNodes, (unsigned)(sizeof(int))));
    if ((num_functions > 1) && (full_off_procNodes > 0))
      dof_func_offd = (int*)(hypre_CAlloc((unsigned)full_off_procNodes, (unsigned)(sizeof(int))));
    alt_insert_new_nodes(comm_pkg, extend_comm_pkg, CF_marker, full_off_procNodes, CF_marker_offd);
    if (num_functions > 1)
      alt_insert_new_nodes(comm_pkg, extend_comm_pkg, dof_func, full_off_procNodes, dof_func_offd);
  }
  P_diag_i = (int*)(hypre_CAlloc((unsigned)(n_fine + 1), (unsigned)(sizeof(int))));
  P_offd_i = (int*)(hypre_CAlloc((unsigned)(n_fine + 1), (unsigned)(sizeof(int))));
  if (n_fine) {
    fine_to_coarse = (int*)(hypre_CAlloc((unsigned)n_fine, (unsigned)(sizeof(int))));
    P_marker = (int*)(hypre_CAlloc((unsigned)n_fine, (unsigned)(sizeof(int))));
  }
  if (full_off_procNodes) {
    P_marker_offd = (int*)(hypre_CAlloc((unsigned)full_off_procNodes, (unsigned)(sizeof(int))));
    fine_to_coarse_offd = (int*)(hypre_CAlloc((unsigned)full_off_procNodes, (unsigned)(sizeof(int))));
    tmp_CF_marker_offd = (int*)(hypre_CAlloc((unsigned)full_off_procNodes, (unsigned)(sizeof(int))));
  }
  for (i = 0; i < full_off_procNodes; i++) {
    P_marker_offd[i] = -1;
    tmp_CF_marker_offd[i] = -1;
    fine_to_coarse_offd[i] = -1;
  }
  for (i = 0; i < n_fine; i++) {
    P_marker[i] = -1;
    fine_to_coarse[i] = -1;
  }
  jj_counter = start_indexing;
  jj_counter_offd = start_indexing;
  coarse_counter = 0;
  coarse_counter_offd = 0;
  for (i = 0; i < n_fine; i++) {
    P_diag_i[i] = jj_counter;
    if (num_procs > 1)
      P_offd_i[i] = jj_counter_offd;
    if ((CF_marker[i]) >= 0) {
      jj_counter++;
      fine_to_coarse[i] = coarse_counter;
      coarse_counter++;
    }
    else
      if ((CF_marker[i]) != (-3)) {
        for (jj = S_diag_i[i]; jj < (S_diag_i[i + 1]); jj++) {
          i1 = S_diag_j[jj];
          if ((CF_marker[i1]) > 0) {
            if ((P_marker[i1]) < (P_diag_i[i])) {
              P_marker[i1] = jj_counter;
              jj_counter++;
            }
          }
          else
            if ((CF_marker[i1]) != (-3)) {
              for (kk = S_diag_i[i1]; kk < (S_diag_i[i1 + 1]); kk++) {
                k1 = S_diag_j[kk];
                if ((CF_marker[k1]) > 0) {
                  if ((P_marker[k1]) < (P_diag_i[i])) {
                    P_marker[k1] = jj_counter;
                    jj_counter++;
                  }
                }
              }
              if (num_procs > 1) {
                for (kk = S_offd_i[i1]; kk < (S_offd_i[i1 + 1]); kk++) {
                  if (col_offd_S_to_A)
                    k1 = col_offd_S_to_A[S_offd_j[kk]];
                  else
                    k1 = S_offd_j[kk];
                  if ((CF_marker_offd[k1]) > 0) {
                    if ((P_marker_offd[k1]) < (P_offd_i[i])) {
                      tmp_CF_marker_offd[k1] = 1;
                      P_marker_offd[k1] = jj_counter_offd;
                      jj_counter_offd++;
                    }
                  }
                }
              }
            }
        }
        if (num_procs > 1) {
          for (jj = S_offd_i[i]; jj < (S_offd_i[i + 1]); jj++) {
            i1 = S_offd_j[jj];
            if (col_offd_S_to_A)
              i1 = col_offd_S_to_A[i1];
            if ((CF_marker_offd[i1]) > 0) {
              if ((P_marker_offd[i1]) < (P_offd_i[i])) {
                tmp_CF_marker_offd[i1] = 1;
                P_marker_offd[i1] = jj_counter_offd;
                jj_counter_offd++;
              }
            }
            else
              if ((CF_marker_offd[i1]) != (-3)) {
                for (kk = Sop_i[i1]; kk < (Sop_i[i1 + 1]); kk++) {
                  loc_col = Sop_j[kk];
                  if (loc_col > (-1)) {
                    if ((CF_marker[loc_col]) > 0) {
                      if ((P_marker[loc_col]) < (P_diag_i[i])) {
                        P_marker[loc_col] = jj_counter;
                        jj_counter++;
                      }
                    }
                  }
                  else {
                    loc_col = (-loc_col) - 1;
                    if ((CF_marker_offd[loc_col]) > 0) {
                      if ((P_marker_offd[loc_col]) < (P_offd_i[i])) {
                        P_marker_offd[loc_col] = jj_counter_offd;
                        tmp_CF_marker_offd[loc_col] = 1;
                        jj_counter_offd++;
                      }
                    }
                  }
                }
              }
          }
        }
      }
  }
  if (debug_flag == 4) {
    wall_time = time_getWallclockSeconds() - wall_time;
    printf("Proc = %d     determine structure    %f\n", my_id, wall_time);
    fflush((void*)0);
  }
  if (debug_flag == 4)
    wall_time = time_getWallclockSeconds();
  P_diag_size = jj_counter;
  P_offd_size = jj_counter_offd;
  if (P_diag_size) {
    P_diag_j = (int*)(hypre_CAlloc((unsigned)P_diag_size, (unsigned)(sizeof(int))));
    P_diag_data = (double*)(hypre_CAlloc((unsigned)P_diag_size, (unsigned)(sizeof(double))));
  }
  if (P_offd_size) {
    P_offd_j = (int*)(hypre_CAlloc((unsigned)P_offd_size, (unsigned)(sizeof(int))));
    P_offd_data = (double*)(hypre_CAlloc((unsigned)P_offd_size, (unsigned)(sizeof(double))));
  }
  P_diag_i[n_fine] = jj_counter;
  P_offd_i[n_fine] = jj_counter_offd;
  jj_counter = start_indexing;
  jj_counter_offd = start_indexing;
  if (num_procs > 1) {
    big_insert_new_nodes(comm_pkg, extend_comm_pkg, fine_to_coarse, full_off_procNodes, my_first_cpt, fine_to_coarse_offd);
  }
  for (i = 0; i < n_fine; i++)
    P_marker[i] = -1;
  for (i = 0; i < full_off_procNodes; i++)
    P_marker_offd[i] = -1;
  for (i = 0; i < n_fine; i++) {
    jj_begin_row = jj_counter;
    jj_begin_row_offd = jj_counter_offd;
    if ((CF_marker[i]) >= 0) {
      P_diag_j[jj_counter] = fine_to_coarse[i];
      P_diag_data[jj_counter] = one;
      jj_counter++;
    }
    else
      if ((CF_marker[i]) != (-3)) {
        strong_f_marker--;
        for (jj = S_diag_i[i]; jj < (S_diag_i[i + 1]); jj++) {
          i1 = S_diag_j[jj];
          if ((CF_marker[i1]) >= 0) {
            if ((P_marker[i1]) < jj_begin_row) {
              P_marker[i1] = jj_counter;
              P_diag_j[jj_counter] = fine_to_coarse[i1];
              P_diag_data[jj_counter] = zero;
              jj_counter++;
            }
          }
          else
            if ((CF_marker[i1]) != (-3)) {
              P_marker[i1] = strong_f_marker;
              for (kk = S_diag_i[i1]; kk < (S_diag_i[i1 + 1]); kk++) {
                k1 = S_diag_j[kk];
                if ((CF_marker[k1]) > 0) {
                  if ((P_marker[k1]) < jj_begin_row) {
                    P_marker[k1] = jj_counter;
                    P_diag_j[jj_counter] = fine_to_coarse[k1];
                    P_diag_data[jj_counter] = zero;
                    jj_counter++;
                  }
                }
              }
              if (num_procs > 1) {
                for (kk = S_offd_i[i1]; kk < (S_offd_i[i1 + 1]); kk++) {
                  if (col_offd_S_to_A)
                    k1 = col_offd_S_to_A[S_offd_j[kk]];
                  else
                    k1 = S_offd_j[kk];
                  if ((CF_marker_offd[k1]) > 0) {
                    if ((P_marker_offd[k1]) < jj_begin_row_offd) {
                      P_marker_offd[k1] = jj_counter_offd;
                      P_offd_j[jj_counter_offd] = k1;
                      P_offd_data[jj_counter_offd] = zero;
                      jj_counter_offd++;
                    }
                  }
                }
              }
            }
        }
        if (num_procs > 1) {
          for (jj = S_offd_i[i]; jj < (S_offd_i[i + 1]); jj++) {
            i1 = S_offd_j[jj];
            if (col_offd_S_to_A)
              i1 = col_offd_S_to_A[i1];
            if ((CF_marker_offd[i1]) > 0) {
              if ((P_marker_offd[i1]) < jj_begin_row_offd) {
                P_marker_offd[i1] = jj_counter_offd;
                P_offd_j[jj_counter_offd] = i1;
                P_offd_data[jj_counter_offd] = zero;
                jj_counter_offd++;
              }
            }
            else
              if ((CF_marker_offd[i1]) != (-3)) {
                P_marker_offd[i1] = strong_f_marker;
                for (kk = Sop_i[i1]; kk < (Sop_i[i1 + 1]); kk++) {
                  loc_col = Sop_j[kk];
                  if (loc_col > (-1)) {
                    if ((CF_marker[loc_col]) > 0) {
                      if ((P_marker[loc_col]) < jj_begin_row) {
                        P_marker[loc_col] = jj_counter;
                        P_diag_j[jj_counter] = fine_to_coarse[loc_col];
                        P_diag_data[jj_counter] = zero;
                        jj_counter++;
                      }
                    }
                  }
                  else {
                    loc_col = (-loc_col) - 1;
                    if ((CF_marker_offd[loc_col]) > 0) {
                      if ((P_marker_offd[loc_col]) < jj_begin_row_offd) {
                        P_marker_offd[loc_col] = jj_counter_offd;
                        P_offd_j[jj_counter_offd] = loc_col;
                        P_offd_data[jj_counter_offd] = zero;
                        jj_counter_offd++;
                      }
                    }
                  }
                }
              }
          }
        }
        jj_end_row = jj_counter;
        jj_end_row_offd = jj_counter_offd;
        diagonal = A_diag_data[A_diag_i[i]];
        for (jj = (A_diag_i[i]) + 1; jj < (A_diag_i[i + 1]); jj++) {
          i1 = A_diag_j[jj];
          if ((P_marker[i1]) >= jj_begin_row) {
            P_diag_data[P_marker[i1]] += A_diag_data[jj];
          }
          else
            if ((P_marker[i1]) == strong_f_marker) {
              sum = zero;
              sgn = 1;
              if ((A_diag_data[A_diag_i[i1]]) < 0)
                sgn = -1;
              for (jj1 = (A_diag_i[i1]) + 1; jj1 < (A_diag_i[i1 + 1]); jj1++) {
                i2 = A_diag_j[jj1];
                if (((P_marker[i2]) >= jj_begin_row) && ((sgn * (A_diag_data[jj1])) < 0))
                  sum += A_diag_data[jj1];
              }
              if (num_procs > 1) {
                for (jj1 = A_offd_i[i1]; jj1 < (A_offd_i[i1 + 1]); jj1++) {
                  i2 = A_offd_j[jj1];
                  if (((P_marker_offd[i2]) >= jj_begin_row_offd) && ((sgn * (A_offd_data[jj1])) < 0))
                    sum += A_offd_data[jj1];
                }
              }
              if (sum != 0) {
                distribute = (A_diag_data[jj]) / sum;
                for (jj1 = (A_diag_i[i1]) + 1; jj1 < (A_diag_i[i1 + 1]); jj1++) {
                  i2 = A_diag_j[jj1];
                  if (((P_marker[i2]) >= jj_begin_row) && ((sgn * (A_diag_data[jj1])) < 0))
                    P_diag_data[P_marker[i2]] += distribute * (A_diag_data[jj1]);
                }
                if (num_procs > 1) {
                  for (jj1 = A_offd_i[i1]; jj1 < (A_offd_i[i1 + 1]); jj1++) {
                    i2 = A_offd_j[jj1];
                    if (((P_marker_offd[i2]) >= jj_begin_row_offd) && ((sgn * (A_offd_data[jj1])) < 0))
                      P_offd_data[P_marker_offd[i2]] += distribute * (A_offd_data[jj1]);
                  }
                }
              }
              else {
                diagonal += A_diag_data[jj];
              }
            }
            else
              if ((CF_marker[i1]) != (-3)) {
                if ((num_functions == 1) || ((dof_func[i]) == (dof_func[i1])))
                  diagonal += A_diag_data[jj];
              }
        }
        if (num_procs > 1) {
          for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
            i1 = A_offd_j[jj];
            if ((P_marker_offd[i1]) >= jj_begin_row_offd)
              P_offd_data[P_marker_offd[i1]] += A_offd_data[jj];
            else
              if ((P_marker_offd[i1]) == strong_f_marker) {
                sum = zero;
                sgn = 1;
                if ((A_ext_data[A_ext_i[i1]]) < 0)
                  sgn = -1;
                for (jj1 = (A_ext_i[i1]) + 1; jj1 < (A_ext_i[i1 + 1]); jj1++) {
                  loc_col = A_ext_j[jj1];
                  if (loc_col > (-1)) {
                    if (((P_marker[loc_col]) >= jj_begin_row) && ((sgn * (A_ext_data[jj1])) < 0))
                      sum += A_ext_data[jj1];
                  }
                  else {
                    loc_col = (-loc_col) - 1;
                    if (((P_marker_offd[loc_col]) >= jj_begin_row_offd) && ((sgn * (A_ext_data[jj1])) < 0))
                      sum += A_ext_data[jj1];
                  }
                }
                if (sum != 0) {
                  distribute = (A_offd_data[jj]) / sum;
                  for (jj1 = (A_ext_i[i1]) + 1; jj1 < (A_ext_i[i1 + 1]); jj1++) {
                    loc_col = A_ext_j[jj1];
                    if (loc_col > (-1)) {
                      if (((P_marker[loc_col]) >= jj_begin_row) && ((sgn * (A_ext_data[jj1])) < 0))
                        P_diag_data[P_marker[loc_col]] += distribute * (A_ext_data[jj1]);
                    }
                    else {
                      loc_col = (-loc_col) - 1;
                      if (((P_marker_offd[loc_col]) >= jj_begin_row_offd) && ((sgn * (A_ext_data[jj1])) < 0))
                        P_offd_data[P_marker_offd[loc_col]] += distribute * (A_ext_data[jj1]);
                    }
                  }
                }
                else {
                  diagonal += A_offd_data[jj];
                }
              }
              else
                if ((CF_marker_offd[i1]) != (-3)) {
                  if ((num_functions == 1) || ((dof_func[i]) == (dof_func_offd[i1])))
                    diagonal += A_offd_data[jj];
                }
          }
        }
        for (jj = jj_begin_row; jj < jj_end_row; jj++)
          (P_diag_data[jj]) /= (-diagonal);
        for (jj = jj_begin_row_offd; jj < jj_end_row_offd; jj++)
          (P_offd_data[jj]) /= (-diagonal);
      }
    strong_f_marker--;
  }
  if (debug_flag == 4) {
    wall_time = time_getWallclockSeconds() - wall_time;
    printf("Proc = %d     fill structure    %f\n", my_id, wall_time);
    fflush((void*)0);
  }
  P = hypre_ParCSRMatrixCreate(comm, (A)->global_num_rows, total_global_cpts, (A)->col_starts, num_cpts_global, 0, P_diag_i[n_fine], P_offd_i[n_fine]);
  P_diag = (P)->diag;
  (P_diag)->data = P_diag_data;
  (P_diag)->i = P_diag_i;
  (P_diag)->j = P_diag_j;
  P_offd = (P)->offd;
  (P_offd)->data = P_offd_data;
  (P_offd)->i = P_offd_i;
  (P_offd)->j = P_offd_j;
  (P)->owns_row_starts = 0;
  if ((trunc_factor != 0.0) || (max_elmts > 0)) {
    hypre_BoomerAMGInterpTruncation(P, trunc_factor, max_elmts);
    P_diag_data = (P_diag)->data;
    P_diag_i = (P_diag)->i;
    P_diag_j = (P_diag)->j;
    P_offd_data = (P_offd)->data;
    P_offd_i = (P_offd)->i;
    P_offd_j = (P_offd)->j;
    P_diag_size = P_diag_i[n_fine];
    P_offd_size = P_offd_i[n_fine];
  }
  num_cols_P_offd = 0;
  if (P_offd_size) {
    num_cols_P_offd = 0;
    for (i = 0; i < P_offd_size; i++) {
      index = P_offd_j[i];
      if ((tmp_CF_marker_offd[index]) == 1) {
        num_cols_P_offd++;
        tmp_CF_marker_offd[index] = 2;
      }
    }
    if (num_cols_P_offd) {
      col_map_offd_P = (int*)(hypre_CAlloc((unsigned)num_cols_P_offd, (unsigned)(sizeof(int))));
      tmp_map_offd = (int*)(hypre_CAlloc((unsigned)num_cols_P_offd, (unsigned)(sizeof(int))));
    }
    index = 0;
    for (i = 0; i < num_cols_P_offd; i++) {
      while ((tmp_CF_marker_offd[index]) != 2)
        index++;
      col_map_offd_P[i] = fine_to_coarse_offd[index];
      tmp_map_offd[i] = index++;
    }
    hypre_BigQsortbi(col_map_offd_P, tmp_map_offd, 0, num_cols_P_offd - 1);
    for (i = 0; i < num_cols_P_offd; i++)
      tmp_CF_marker_offd[tmp_map_offd[i]] = i;
    for (i = 0; i < P_offd_size; i++)
      P_offd_j[i] = tmp_CF_marker_offd[P_offd_j[i]];
  }
  if (num_cols_P_offd) {
    (P)->col_map_offd = col_map_offd_P;
    (P_offd)->num_cols = num_cols_P_offd;
    hypre_Free((char*)tmp_map_offd), tmp_map_offd = (void*)0;
  }
  hypre_MatvecCommPkgCreate(P);
  for (i = 0; i < n_fine; i++)
    if ((CF_marker[i]) == (-3))
      CF_marker[i] = -1;
  *P_ptr = P;
  hypre_Free((char*)fine_to_coarse), fine_to_coarse = (void*)0;
  hypre_Free((char*)P_marker), P_marker = (void*)0;
  if (num_procs > 1) {
    hypre_BigCSRMatrixDestroy(Sop);
    hypre_BigCSRMatrixDestroy(A_ext);
    hypre_Free((char*)fine_to_coarse_offd), fine_to_coarse_offd = (void*)0;
    hypre_Free((char*)P_marker_offd), P_marker_offd = (void*)0;
    hypre_Free((char*)CF_marker_offd), CF_marker_offd = (void*)0;
    hypre_Free((char*)tmp_CF_marker_offd), tmp_CF_marker_offd = (void*)0;
    if (num_functions > 1)
      hypre_Free((char*)dof_func_offd), dof_func_offd = (void*)0;
    hypre_Free((char*)found), found = (void*)0;
    hypre_MatvecCommPkgDestroy(extend_comm_pkg);
  }
  return hypre__global_error;
}
//=================== par_multi_interp.c ===================
int hypre_BoomerAMGBuildMultipass(hypre_ParCSRMatrix* A, int* CF_marker, hypre_ParCSRMatrix* S, int* num_cpts_global, int num_functions, int* dof_func, int debug_flag, double trunc_factor, int P_max_elmts, int weight_option, int* col_offd_S_to_A, hypre_ParCSRMatrix** P_ptr) {
  MPI_Comm comm = (A)->comm;
  hypre_ParCSRCommPkg* comm_pkg = (S)->comm_pkg;
  hypre_ParCSRCommHandle* comm_handle;
  hypre_ParCSRCommPkg* tmp_comm_pkg;
  hypre_CSRMatrix* A_diag = (A)->diag;
  double* A_diag_data = (A_diag)->data;
  int* A_diag_i = (A_diag)->i;
  int* A_diag_j = (A_diag)->j;
  hypre_CSRMatrix* A_offd = (A)->offd;
  double* A_offd_data = (void*)0;
  int* A_offd_i = (A_offd)->i;
  int* A_offd_j = (void*)0;
  int* col_map_offd_A = (A)->col_map_offd;
  int num_cols_offd_A = (A_offd)->num_cols;
  hypre_CSRMatrix* S_diag = (S)->diag;
  int* S_diag_i = (S_diag)->i;
  int* S_diag_j = (S_diag)->j;
  hypre_CSRMatrix* S_offd = (S)->offd;
  int* S_offd_i = (S_offd)->i;
  int* S_offd_j = (void*)0;
  int* col_map_offd_S = (S)->col_map_offd;
  int num_cols_offd_S = (S_offd)->num_cols;
  int* col_map_offd = (void*)0;
  int num_cols_offd;
  hypre_ParCSRMatrix* P;
  hypre_CSRMatrix* P_diag;
  double* P_diag_data;
  int* P_diag_i;
  int* P_diag_j;
  hypre_CSRMatrix* P_offd;
  double* P_offd_data = (void*)0;
  int* P_offd_i;
  int* P_offd_j = (void*)0;
  int num_sends = 0;
  int* int_buf_data = (void*)0;
  int* big_buf_data = (void*)0;
  int* send_map_start;
  int* send_map_elmt;
  int* send_procs;
  int num_recvs = 0;
  int* recv_vec_start;
  int* recv_procs;
  int* new_recv_vec_start = (void*)0;
  int** Pext_send_map_start = (void*)0;
  int** Pext_recv_vec_start = (void*)0;
  int* Pext_start = (void*)0;
  int* P_ncols = (void*)0;
  int* CF_marker_offd = (void*)0;
  int* dof_func_offd = (void*)0;
  int* P_marker;
  int* P_marker_offd = (void*)0;
  int* C_array;
  int* C_array_offd = (void*)0;
  int* pass_array = (void*)0;
  int* pass_pointer = (void*)0;
  int* P_diag_start;
  int* P_offd_start = (void*)0;
  int** P_diag_pass;
  int** P_offd_pass = (void*)0;
  int** Pext_pass = (void*)0;
  int* big_temp_pass = (void*)0;
  int** new_elmts = (void*)0;
  int* new_counter = (void*)0;
  int* loc = (void*)0;
  int* Pext_i = (void*)0;
  int* Pext_send_buffer = (void*)0;
  int* map_S_to_new = (void*)0;
  int* map_A_to_S = (void*)0;
  int* new_col_map_offd = (void*)0;
  int* col_map_offd_P = (void*)0;
  int* big_permute = (void*)0;
  int* permute = (void*)0;
  int cnt;
  int cnt_nz;
  int total_nz;
  int pass;
  int num_passes;
  int max_num_passes = 10;
  int n_fine;
  int n_coarse = 0;
  int n_coarse_offd = 0;
  int n_SF = 0;
  int n_SF_offd = 0;
  int* fine_to_coarse = (void*)0;
  int* fine_to_coarse_offd = (void*)0;
  int* assigned = (void*)0;
  int* assigned_offd = (void*)0;
  double* Pext_send_data = (void*)0;
  double* Pext_data = (void*)0;
  double sum_C;
  double sum_N;
  double sum_C_pos;
  double sum_C_neg;
  double sum_N_pos;
  double sum_N_neg;
  double diagonal;
  double alfa = 1.0;
  double beta = 1.0;
  int j_start;
  int j_end;
  int i;
  int i1;
  int j;
  int j1;
  int k;
  int k1;
  int k2;
  int k3;
  int pass_array_size;
  int global_pass_array_size;
  int local_pass_array_size;
  int my_id;
  int num_procs;
  int index;
  int start;
  int my_first_cpt;
  int total_global_cpts;
  int big_value;
  int p_cnt;
  int total_nz_offd;
  int cnt_nz_offd;
  int cnt_offd;
  int cnt_new;
  int no_break;
  int not_found;
  int Pext_send_size;
  int Pext_recv_size;
  int old_Pext_send_size;
  int old_Pext_recv_size;
  int P_offd_size = 0;
  int local_index = -1;
  int new_num_cols_offd = 0;
  int num_cols_offd_P;
  int num_threads;
  int ns;
  int ne;
  int size;
  int rest;
  int pass_length;
  int* tmp_marker;
  int* tmp_marker_offd;
  int* tmp_array;
  int* tmp_array_offd;
  MPI_Comm_size(comm, &(num_procs));
  MPI_Comm_rank(comm, &(my_id));
  num_threads = 1;
  my_first_cpt = num_cpts_global[my_id];
  total_global_cpts = num_cpts_global[num_procs];
  if (!comm_pkg) {
    comm_pkg = (A)->comm_pkg;
    if (!comm_pkg) {
      hypre_MatvecCommPkgCreate(A);
      comm_pkg = (A)->comm_pkg;
    }
    col_offd_S_to_A = (void*)0;
  }
  if (col_offd_S_to_A) {
    col_map_offd = col_map_offd_S;
    num_cols_offd = num_cols_offd_S;
  }
  else {
    col_map_offd = col_map_offd_A;
    num_cols_offd = num_cols_offd_A;
  }
  if (num_cols_offd_A) {
    A_offd_data = (A_offd)->data;
    A_offd_j = (A_offd)->j;
  }
  if (num_cols_offd)
    S_offd_j = (S_offd)->j;
  n_fine = (A_diag)->num_rows;
  if (n_fine)
    fine_to_coarse = (int*)(hypre_CAlloc((unsigned)n_fine, (unsigned)(sizeof(int))));
  n_coarse = 0;
  n_SF = 0;
  for (i = 0; i < n_fine; i++)
    if ((CF_marker[i]) == 1)
      n_coarse++;
    else
      if ((CF_marker[i]) == (-3))
        n_SF++;
  pass_array_size = (n_fine - n_coarse) - n_SF;
  if (pass_array_size)
    pass_array = (int*)(hypre_CAlloc((unsigned)pass_array_size, (unsigned)(sizeof(int))));
  pass_pointer = (int*)(hypre_CAlloc((unsigned)(max_num_passes + 1), (unsigned)(sizeof(int))));
  if (n_fine)
    assigned = (int*)(hypre_CAlloc((unsigned)n_fine, (unsigned)(sizeof(int))));
  {
    P_diag_i = (int*)(hypre_CAlloc((unsigned)(n_fine + 1), (unsigned)(sizeof(int))));
    P_offd_i = (int*)(hypre_CAlloc((unsigned)(n_fine + 1), (unsigned)(sizeof(int))));
  }
  if (n_coarse)
    C_array = (int*)(hypre_CAlloc((unsigned)n_coarse, (unsigned)(sizeof(int))));
  if (num_cols_offd) {
    CF_marker_offd = (int*)(hypre_CAlloc((unsigned)num_cols_offd, (unsigned)(sizeof(int))));
    if (num_functions > 1)
      dof_func_offd = (int*)(hypre_CAlloc((unsigned)num_cols_offd, (unsigned)(sizeof(int))));
  }
  if (num_procs > 1) {
    num_sends = (comm_pkg)->num_sends;
    send_procs = (comm_pkg)->send_procs;
    send_map_start = (comm_pkg)->send_map_starts;
    send_map_elmt = (comm_pkg)->send_map_elmts;
    num_recvs = (comm_pkg)->num_recvs;
    recv_procs = (comm_pkg)->recv_procs;
    recv_vec_start = (comm_pkg)->recv_vec_starts;
    if (send_map_start[num_sends]) {
      int_buf_data = (int*)(hypre_CAlloc((unsigned)(send_map_start[num_sends]), (unsigned)(sizeof(int))));
      big_buf_data = (int*)(hypre_CAlloc((unsigned)(send_map_start[num_sends]), (unsigned)(sizeof(int))));
    }
  }
  index = 0;
  for (i = 0; i < num_sends; i++) {
    start = send_map_start[i];
    for (j = start; j < (send_map_start[i + 1]); j++)
      int_buf_data[index++] = CF_marker[send_map_elmt[j]];
  }
  if (num_procs > 1) {
    comm_handle = hypre_ParCSRCommHandleCreate(11, comm_pkg, int_buf_data, CF_marker_offd);
    hypre_ParCSRCommHandleDestroy(comm_handle);
  }
  if (num_functions > 1) {
    index = 0;
    for (i = 0; i < num_sends; i++) {
      start = send_map_start[i];
      for (j = start; j < (send_map_start[i + 1]); j++)
        int_buf_data[index++] = dof_func[send_map_elmt[j]];
    }
    if (num_procs > 1) {
      comm_handle = hypre_ParCSRCommHandleCreate(11, comm_pkg, int_buf_data, dof_func_offd);
      hypre_ParCSRCommHandleDestroy(comm_handle);
    }
  }
  n_coarse_offd = 0;
  n_SF_offd = 0;
  for (i = 0; i < num_cols_offd; i++)
    if ((CF_marker_offd[i]) == 1)
      n_coarse_offd++;
    else
      if ((CF_marker_offd[i]) == (-3))
        n_SF_offd++;
  if (num_cols_offd) {
    assigned_offd = (int*)(hypre_CAlloc((unsigned)num_cols_offd, (unsigned)(sizeof(int))));
    map_S_to_new = (int*)(hypre_CAlloc((unsigned)num_cols_offd, (unsigned)(sizeof(int))));
    fine_to_coarse_offd = (int*)(hypre_CAlloc((unsigned)num_cols_offd, (unsigned)(sizeof(int))));
    new_col_map_offd = (int*)(hypre_CAlloc((unsigned)n_coarse_offd, (unsigned)(sizeof(int))));
  }
  cnt = 0;
  p_cnt = pass_array_size - 1;
  P_diag_i[0] = 0;
  P_offd_i[0] = 0;
  for (i = 0; i < n_fine; i++) {
    if ((CF_marker[i]) == 1) {
      fine_to_coarse[i] = cnt;
      C_array[cnt++] = i;
      assigned[i] = 0;
      P_diag_i[i + 1] = 1;
      P_offd_i[i + 1] = 0;
    }
    else
      if ((CF_marker[i]) == (-1)) {
        pass_array[p_cnt--] = i;
        P_diag_i[i + 1] = 0;
        P_offd_i[i + 1] = 0;
        assigned[i] = -1;
        fine_to_coarse[i] = -1;
      }
      else {
        P_diag_i[i + 1] = 0;
        P_offd_i[i + 1] = 0;
        assigned[i] = -1;
        fine_to_coarse[i] = -1;
      }
  }
  index = 0;
  for (i = 0; i < num_sends; i++) {
    start = send_map_start[i];
    for (j = start; j < (send_map_start[i + 1]); j++) {
      big_buf_data[index] = (int)(fine_to_coarse[send_map_elmt[j]]);
      if ((big_buf_data[index]) > (-1))
        big_buf_data[index] += my_first_cpt;
      index++;
    }
  }
  if (num_procs > 1) {
    comm_handle = hypre_ParCSRCommHandleCreate(21, comm_pkg, big_buf_data, fine_to_coarse_offd);
    hypre_ParCSRCommHandleDestroy(comm_handle);
    hypre_Free((char*)big_buf_data), big_buf_data = (void*)0;
  }
  new_recv_vec_start = (int*)(hypre_CAlloc((unsigned)(num_recvs + 1), (unsigned)(sizeof(int))));
  if (n_coarse_offd)
    C_array_offd = (int*)(hypre_CAlloc((unsigned)n_coarse_offd, (unsigned)(sizeof(int))));
  cnt = 0;
  new_recv_vec_start[0] = 0;
  for (j = 0; j < num_recvs; j++) {
    for (i = recv_vec_start[j]; i < (recv_vec_start[j + 1]); i++) {
      if ((CF_marker_offd[i]) == 1) {
        map_S_to_new[i] = cnt;
        C_array_offd[cnt] = i;
        new_col_map_offd[cnt++] = fine_to_coarse_offd[i];
        assigned_offd[i] = 0;
      }
      else {
        assigned_offd[i] = -1;
        map_S_to_new[i] = -1;
      }
    }
    new_recv_vec_start[j + 1] = cnt;
  }
  cnt = 0;
  hypre_Free((char*)fine_to_coarse_offd), fine_to_coarse_offd = (void*)0;
  if (col_offd_S_to_A) {
    map_A_to_S = (int*)(hypre_CAlloc((unsigned)num_cols_offd_A, (unsigned)(sizeof(int))));
    for (i = 0; i < num_cols_offd_A; i++) {
      if ((cnt < num_cols_offd) && ((col_map_offd_A[i]) == (col_map_offd[cnt])))
        map_A_to_S[i] = cnt++;
      else
        map_A_to_S[i] = -1;
    }
  }
  pass_pointer[0] = 0;
  pass_pointer[1] = 0;
  total_nz = n_coarse;
  total_nz_offd = 0;
  cnt = 0;
  cnt_offd = 0;
  cnt_nz = 0;
  cnt_nz_offd = 0;
  for (i = pass_array_size - 1; i > (cnt - 1); i--) {
    i1 = pass_array[i];
    for (j = S_diag_i[i1]; j < (S_diag_i[i1 + 1]); j++) {
      j1 = S_diag_j[j];
      if ((CF_marker[j1]) == 1) {
        P_diag_i[i1 + 1]++;
        cnt_nz++;
        assigned[i1] = 1;
      }
    }
    for (j = S_offd_i[i1]; j < (S_offd_i[i1 + 1]); j++) {
      j1 = S_offd_j[j];
      if ((CF_marker_offd[j1]) == 1) {
        P_offd_i[i1 + 1]++;
        cnt_nz_offd++;
        assigned[i1] = 1;
      }
    }
    if ((assigned[i1]) == 1) {
      pass_array[i++] = pass_array[cnt];
      pass_array[cnt++] = i1;
    }
  }
  pass_pointer[2] = cnt;
  index = 0;
  for (i = 0; i < num_sends; i++) {
    start = send_map_start[i];
    for (j = start; j < (send_map_start[i + 1]); j++)
      int_buf_data[index++] = assigned[send_map_elmt[j]];
  }
  if (num_procs > 1) {
    comm_handle = hypre_ParCSRCommHandleCreate(11, comm_pkg, int_buf_data, assigned_offd);
    hypre_ParCSRCommHandleDestroy(comm_handle);
  }
  pass = 2;
  local_pass_array_size = (int)(pass_array_size - cnt);
  MPI_Allreduce(&(local_pass_array_size), &(global_pass_array_size), 1, MPI_INT, _SUM, comm);
  while (global_pass_array_size && (pass < max_num_passes)) {
    for (i = pass_array_size - 1; i > (cnt - 1); i--) {
      i1 = pass_array[i];
      no_break = 1;
      for (j = S_diag_i[i1]; j < (S_diag_i[i1 + 1]); j++) {
        j1 = S_diag_j[j];
        if ((assigned[j1]) == (pass - 1)) {
          pass_array[i++] = pass_array[cnt];
          pass_array[cnt++] = i1;
          assigned[i1] = pass;
          no_break = 0;
          break;
        }
      }
      if (no_break) {
        for (j = S_offd_i[i1]; j < (S_offd_i[i1 + 1]); j++) {
          j1 = S_offd_j[j];
          if ((assigned_offd[j1]) == (pass - 1)) {
            pass_array[i++] = pass_array[cnt];
            pass_array[cnt++] = i1;
            assigned[i1] = pass;
            break;
          }
        }
      }
    }
    pass++;
    pass_pointer[pass] = cnt;
    local_pass_array_size = (int)(pass_array_size - cnt);
    MPI_Allreduce(&(local_pass_array_size), &(global_pass_array_size), 1, MPI_INT, _SUM, comm);
    index = 0;
    for (i = 0; i < num_sends; i++) {
      start = send_map_start[i];
      for (j = start; j < (send_map_start[i + 1]); j++)
        int_buf_data[index++] = assigned[send_map_elmt[j]];
    }
    if (num_procs > 1) {
      comm_handle = hypre_ParCSRCommHandleCreate(11, comm_pkg, int_buf_data, assigned_offd);
      hypre_ParCSRCommHandleDestroy(comm_handle);
    }
  }
  hypre_Free((char*)int_buf_data), int_buf_data = (void*)0;
  num_passes = pass;
  P_marker = (int*)(hypre_CAlloc((unsigned)n_coarse, (unsigned)(sizeof(int))));
  for (i = 0; i < n_coarse; i++)
    P_marker[i] = -1;
  if (n_coarse_offd) {
    P_marker_offd = (int*)(hypre_CAlloc((unsigned)n_coarse_offd, (unsigned)(sizeof(int))));
    for (i = 0; i < n_coarse_offd; i++)
      P_marker_offd[i] = -1;
  }
  P_diag_pass = (int**)(hypre_CAlloc((unsigned)num_passes, (unsigned)(sizeof(int*))));
  P_diag_pass[1] = (int*)(hypre_CAlloc((unsigned)cnt_nz, (unsigned)(sizeof(int))));
  P_diag_start = (int*)(hypre_CAlloc((unsigned)n_fine, (unsigned)(sizeof(int))));
  P_offd_start = (int*)(hypre_CAlloc((unsigned)n_fine, (unsigned)(sizeof(int))));
  if (num_procs > 1) {
    P_offd_pass = (int**)(hypre_CAlloc((unsigned)num_passes, (unsigned)(sizeof(int*))));
    if (cnt_nz_offd)
      P_offd_pass[1] = (int*)(hypre_CAlloc((unsigned)cnt_nz_offd, (unsigned)(sizeof(int))));
    else
      P_offd_pass[1] = (void*)0;
    new_elmts = (int**)(hypre_CAlloc((unsigned)num_passes, (unsigned)(sizeof(int*))));
    new_counter = (int*)(hypre_CAlloc((unsigned)(num_passes + 1), (unsigned)(sizeof(int))));
    new_counter[0] = 0;
    new_counter[1] = n_coarse_offd;
    new_num_cols_offd = n_coarse_offd;
    new_elmts[0] = new_col_map_offd;
  }
  cnt_nz = 0;
  cnt_nz_offd = 0;
  for (i = pass_pointer[1]; i < (pass_pointer[2]); i++) {
    i1 = pass_array[i];
    P_diag_start[i1] = cnt_nz;
    P_offd_start[i1] = cnt_nz_offd;
    for (j = S_diag_i[i1]; j < (S_diag_i[i1 + 1]); j++) {
      j1 = S_diag_j[j];
      if ((CF_marker[j1]) == 1)
        P_diag_pass[1][cnt_nz++] = fine_to_coarse[j1];
    }
    for (j = S_offd_i[i1]; j < (S_offd_i[i1 + 1]); j++) {
      j1 = S_offd_j[j];
      if ((CF_marker_offd[j1]) == 1)
        P_offd_pass[1][cnt_nz_offd++] = map_S_to_new[j1];
    }
  }
  total_nz += cnt_nz;
  total_nz_offd += cnt_nz_offd;
  if (num_procs > 1) {
    tmp_comm_pkg = (hypre_ParCSRCommPkg*)(hypre_CAlloc((unsigned)1, (unsigned)(sizeof(hypre_ParCSRCommPkg))));
    Pext_send_map_start = (int**)(hypre_CAlloc((unsigned)num_passes, (unsigned)(sizeof(int*))));
    Pext_recv_vec_start = (int**)(hypre_CAlloc((unsigned)num_passes, (unsigned)(sizeof(int*))));
    Pext_pass = (int**)(hypre_CAlloc((unsigned)num_passes, (unsigned)(sizeof(int*))));
    Pext_i = (int*)(hypre_CAlloc((unsigned)(num_cols_offd + 1), (unsigned)(sizeof(int))));
    if (num_cols_offd)
      Pext_start = (int*)(hypre_CAlloc((unsigned)num_cols_offd, (unsigned)(sizeof(int))));
    if (send_map_start[num_sends])
      P_ncols = (int*)(hypre_CAlloc((unsigned)(send_map_start[num_sends]), (unsigned)(sizeof(int))));
  }
  old_Pext_send_size = 0;
  old_Pext_recv_size = 0;
  for (pass = 2; pass < num_passes; pass++) {
    if (num_procs > 1) {
      Pext_send_map_start[pass] = (int*)(hypre_CAlloc((unsigned)(num_sends + 1), (unsigned)(sizeof(int))));
      Pext_recv_vec_start[pass] = (int*)(hypre_CAlloc((unsigned)(num_recvs + 1), (unsigned)(sizeof(int))));
      Pext_send_size = 0;
      Pext_send_map_start[pass][0] = 0;
      for (i = 0; i < num_sends; i++) {
        for (j = send_map_start[i]; j < (send_map_start[i + 1]); j++) {
          j1 = send_map_elmt[j];
          if ((assigned[j1]) == (pass - 1)) {
            P_ncols[j] = (P_diag_i[j1 + 1]) + (P_offd_i[j1 + 1]);
            Pext_send_size += P_ncols[j];
          }
        }
        Pext_send_map_start[pass][i + 1] = Pext_send_size;
      }
      comm_handle = hypre_ParCSRCommHandleCreate(11, comm_pkg, P_ncols, &(Pext_i[1]));
      hypre_ParCSRCommHandleDestroy(comm_handle);
      if (Pext_send_size > old_Pext_send_size) {
        hypre_Free((char*)Pext_send_buffer), Pext_send_buffer = (void*)0;
        Pext_send_buffer = (int*)(hypre_CAlloc((unsigned)Pext_send_size, (unsigned)(sizeof(int))));
      }
      old_Pext_send_size = Pext_send_size;
    }
    cnt_offd = 0;
    for (i = 0; i < num_sends; i++) {
      for (j = send_map_start[i]; j < (send_map_start[i + 1]); j++) {
        j1 = send_map_elmt[j];
        if ((assigned[j1]) == (pass - 1)) {
          j_start = P_diag_start[j1];
          j_end = j_start + (P_diag_i[j1 + 1]);
          for (k = j_start; k < j_end; k++) {
            Pext_send_buffer[cnt_offd++] = my_first_cpt + (int)(P_diag_pass[pass - 1][k]);
          }
          j_start = P_offd_start[j1];
          j_end = j_start + (P_offd_i[j1 + 1]);
          for (k = j_start; k < j_end; k++) {
            k1 = P_offd_pass[pass - 1][k];
            k3 = 0;
            while (k3 < (pass - 1)) {
              if (k1 < (new_counter[k3 + 1])) {
                k2 = k1 - (new_counter[k3]);
                Pext_send_buffer[cnt_offd++] = new_elmts[k3][k2];
                break;
              }
              k3++;
            }
          }
        }
      }
    }
    if (num_procs > 1) {
      Pext_recv_size = 0;
      Pext_recv_vec_start[pass][0] = 0;
      cnt_offd = 0;
      for (i = 0; i < num_recvs; i++) {
        for (j = recv_vec_start[i]; j < (recv_vec_start[i + 1]); j++) {
          if ((assigned_offd[j]) == (pass - 1)) {
            Pext_start[j] = cnt_offd;
            cnt_offd += Pext_i[j + 1];
          }
        }
        Pext_recv_size = cnt_offd;
        Pext_recv_vec_start[pass][i + 1] = Pext_recv_size;
      }
      (tmp_comm_pkg)->comm = comm;
      (tmp_comm_pkg)->num_sends = num_sends;
      (tmp_comm_pkg)->send_procs = send_procs;
      (tmp_comm_pkg)->send_map_starts = Pext_send_map_start[pass];
      (tmp_comm_pkg)->num_recvs = num_recvs;
      (tmp_comm_pkg)->recv_procs = recv_procs;
      (tmp_comm_pkg)->recv_vec_starts = Pext_recv_vec_start[pass];
      if (Pext_recv_size) {
        Pext_pass[pass] = (int*)(hypre_CAlloc((unsigned)Pext_recv_size, (unsigned)(sizeof(int))));
        new_elmts[pass - 1] = (int*)(hypre_CAlloc((unsigned)Pext_recv_size, (unsigned)(sizeof(int))));
      }
      else {
        Pext_pass[pass] = (void*)0;
        new_elmts[pass - 1] = (void*)0;
      }
      if (Pext_recv_size > old_Pext_recv_size) {
        hypre_Free((char*)loc), loc = (void*)0;
        hypre_Free((char*)big_temp_pass), big_temp_pass = (void*)0;
        loc = (int*)(hypre_CAlloc((unsigned)Pext_recv_size, (unsigned)(sizeof(int))));
        big_temp_pass = (int*)(hypre_CAlloc((unsigned)Pext_recv_size, (unsigned)(sizeof(int))));
      }
      old_Pext_recv_size = Pext_recv_size;
      comm_handle = hypre_ParCSRCommHandleCreate(21, tmp_comm_pkg, Pext_send_buffer, big_temp_pass);
      hypre_ParCSRCommHandleDestroy(comm_handle);
    }
    cnt_new = 0;
    cnt_offd = 0;
    for (i = 0; i < num_recvs; i++) {
      for (j = recv_vec_start[i]; j < (recv_vec_start[i + 1]); j++) {
        if ((assigned_offd[j]) == (pass - 1)) {
          for (j1 = cnt_offd; j1 < (cnt_offd + (Pext_i[j + 1])); j1++) {
            big_value = big_temp_pass[j1];
            k2 = (int)(big_value - my_first_cpt);
            if ((k2 > (-1)) && (k2 < n_coarse)) {
              Pext_pass[pass][j1] = (-k2) - 1;
            }
            else {
              not_found = 1;
              k3 = 0;
              while ((k3 < (pass - 1)) && not_found) {
                k2 = hypre_BigBinarySearch(new_elmts[k3], big_value, (new_counter[k3 + 1]) - (new_counter[k3]));
                if (k2 > (-1)) {
                  Pext_pass[pass][j1] = k2 + (new_counter[k3]);
                  not_found = 0;
                }
                else {
                  k3++;
                }
              }
              if (not_found) {
                new_elmts[pass - 1][cnt_new] = big_value;
                loc[cnt_new++] = j1;
              }
            }
          }
          cnt_offd += Pext_i[j + 1];
        }
      }
    }
    if (cnt_new) {
      hypre_BigQsortbi(new_elmts[pass - 1], loc, 0, cnt_new - 1);
      cnt = 0;
      local_index = new_counter[pass - 1];
      Pext_pass[pass][loc[0]] = local_index;
      for (i = 1; i < cnt_new; i++) {
        if ((new_elmts[pass - 1][i]) > (new_elmts[pass - 1][cnt])) {
          new_elmts[pass - 1][++cnt] = new_elmts[pass - 1][i];
          local_index++;
        }
        Pext_pass[pass][loc[i]] = local_index;
      }
      new_counter[pass] = local_index + 1;
    }
    else
      if (num_procs > 1)
        new_counter[pass] = new_counter[pass - 1];
    if (new_num_cols_offd < (local_index + 1)) {
      new_num_cols_offd = local_index + 1;
      hypre_Free((char*)P_marker_offd), P_marker_offd = (void*)0;
      P_marker_offd = (int*)(hypre_CAlloc((unsigned)new_num_cols_offd, (unsigned)(sizeof(int))));
      for (i = 0; i < new_num_cols_offd; i++)
        P_marker_offd[i] = -1;
    }
    cnt_nz = 0;
    cnt_nz_offd = 0;
    for (i = pass_pointer[pass]; i < (pass_pointer[pass + 1]); i++) {
      i1 = pass_array[i];
      P_diag_start[i1] = cnt_nz;
      P_offd_start[i1] = cnt_nz_offd;
      for (j = S_diag_i[i1]; j < (S_diag_i[i1 + 1]); j++) {
        j1 = S_diag_j[j];
        if ((assigned[j1]) == (pass - 1)) {
          j_start = P_diag_start[j1];
          j_end = j_start + (P_diag_i[j1 + 1]);
          for (k = j_start; k < j_end; k++) {
            k1 = P_diag_pass[pass - 1][k];
            if ((P_marker[k1]) != i1) {
              cnt_nz++;
              P_diag_i[i1 + 1]++;
              P_marker[k1] = i1;
            }
          }
          j_start = P_offd_start[j1];
          j_end = j_start + (P_offd_i[j1 + 1]);
          for (k = j_start; k < j_end; k++) {
            k1 = P_offd_pass[pass - 1][k];
            if ((P_marker_offd[k1]) != i1) {
              cnt_nz_offd++;
              P_offd_i[i1 + 1]++;
              P_marker_offd[k1] = i1;
            }
          }
        }
      }
      j_start = 0;
      for (j = S_offd_i[i1]; j < (S_offd_i[i1 + 1]); j++) {
        j1 = S_offd_j[j];
        if ((assigned_offd[j1]) == (pass - 1)) {
          j_start = Pext_start[j1];
          j_end = j_start + (Pext_i[j1 + 1]);
          for (k = j_start; k < j_end; k++) {
            k1 = Pext_pass[pass][k];
            if (k1 < 0) {
              if ((P_marker[(-k1) - 1]) != i1) {
                cnt_nz++;
                P_diag_i[i1 + 1]++;
                P_marker[(-k1) - 1] = i1;
              }
            }
            else
              if ((P_marker_offd[k1]) != i1) {
                cnt_nz_offd++;
                P_offd_i[i1 + 1]++;
                P_marker_offd[k1] = i1;
              }
          }
        }
      }
    }
    total_nz += cnt_nz;
    total_nz_offd += cnt_nz_offd;
    P_diag_pass[pass] = (int*)(hypre_CAlloc((unsigned)cnt_nz, (unsigned)(sizeof(int))));
    if (cnt_nz_offd)
      P_offd_pass[pass] = (int*)(hypre_CAlloc((unsigned)cnt_nz_offd, (unsigned)(sizeof(int))));
    else
      if (num_procs > 1)
        P_offd_pass[pass] = (void*)0;
    cnt_nz = 0;
    cnt_nz_offd = 0;
    for (i = pass_pointer[pass]; i < (pass_pointer[pass + 1]); i++) {
      i1 = pass_array[i];
      for (j = S_diag_i[i1]; j < (S_diag_i[i1 + 1]); j++) {
        j1 = S_diag_j[j];
        if ((assigned[j1]) == (pass - 1)) {
          j_start = P_diag_start[j1];
          j_end = j_start + (P_diag_i[j1 + 1]);
          for (k = j_start; k < j_end; k++) {
            k1 = P_diag_pass[pass - 1][k];
            if ((P_marker[k1]) != ((-i1) - 1)) {
              P_diag_pass[pass][cnt_nz++] = k1;
              P_marker[k1] = (-i1) - 1;
            }
          }
          j_start = P_offd_start[j1];
          j_end = j_start + (P_offd_i[j1 + 1]);
          for (k = j_start; k < j_end; k++) {
            k1 = P_offd_pass[pass - 1][k];
            if ((P_marker_offd[k1]) != ((-i1) - 1)) {
              P_offd_pass[pass][cnt_nz_offd++] = k1;
              P_marker_offd[k1] = (-i1) - 1;
            }
          }
        }
      }
      for (j = S_offd_i[i1]; j < (S_offd_i[i1 + 1]); j++) {
        j1 = S_offd_j[j];
        if ((assigned_offd[j1]) == (pass - 1)) {
          j_start = Pext_start[j1];
          j_end = j_start + (Pext_i[j1 + 1]);
          for (k = j_start; k < j_end; k++) {
            k1 = Pext_pass[pass][k];
            if (k1 < 0) {
              if ((P_marker[(-k1) - 1]) != ((-i1) - 1)) {
                P_diag_pass[pass][cnt_nz++] = (-k1) - 1;
                P_marker[(-k1) - 1] = (-i1) - 1;
              }
            }
            else
              if ((P_marker_offd[k1]) != ((-i1) - 1)) {
                P_offd_pass[pass][cnt_nz_offd++] = k1;
                P_marker_offd[k1] = (-i1) - 1;
              }
          }
        }
      }
    }
  }
  hypre_Free((char*)loc), loc = (void*)0;
  hypre_Free((char*)P_ncols), P_ncols = (void*)0;
  hypre_Free((char*)Pext_send_buffer), Pext_send_buffer = (void*)0;
  hypre_Free((char*)big_temp_pass), big_temp_pass = (void*)0;
  hypre_Free((char*)new_recv_vec_start), new_recv_vec_start = (void*)0;
  hypre_Free((char*)P_marker), P_marker = (void*)0;
  hypre_Free((char*)P_marker_offd), P_marker_offd = (void*)0;
  P_marker_offd = (void*)0;
  P_diag_j = (void*)0;
  P_offd_j = (void*)0;
  {
    if (total_nz) {
      P_diag_j = (int*)(hypre_CAlloc((unsigned)total_nz, (unsigned)(sizeof(int))));
      P_diag_data = (double*)(hypre_CAlloc((unsigned)total_nz, (unsigned)(sizeof(double))));
    }
    if (total_nz_offd) {
      P_offd_j = (int*)(hypre_CAlloc((unsigned)total_nz_offd, (unsigned)(sizeof(int))));
      P_offd_data = (double*)(hypre_CAlloc((unsigned)total_nz_offd, (unsigned)(sizeof(double))));
    }
  }
  for (i = 0; i < n_fine; i++) {
    P_diag_i[i + 1] += P_diag_i[i];
    P_offd_i[i + 1] += P_offd_i[i];
  }
  for (i = 0; i < n_coarse; i++) {
    i1 = C_array[i];
    P_diag_j[P_diag_i[i1]] = fine_to_coarse[i1];
    P_diag_data[P_diag_i[i1]] = 1.0;
  }
  P_marker = (int*)(hypre_CAlloc((unsigned)n_fine, (unsigned)(sizeof(int))));
  for (i = 0; i < n_fine; i++)
    P_marker[i] = -1;
  if (num_cols_offd) {
    P_marker_offd = (int*)(hypre_CAlloc((unsigned)num_cols_offd, (unsigned)(sizeof(int))));
    for (i = 0; i < num_cols_offd; i++)
      P_marker_offd[i] = -1;
  }
  if (weight_option) {
    for (i = pass_pointer[1]; i < (pass_pointer[2]); i++) {
      i1 = pass_array[i];
      sum_C_pos = 0;
      sum_C_neg = 0;
      sum_N_pos = 0;
      sum_N_neg = 0;
      j_start = P_diag_start[i1];
      j_end = (j_start + (P_diag_i[i1 + 1])) - (P_diag_i[i1]);
      for (j = j_start; j < j_end; j++) {
        k1 = P_diag_pass[1][j];
        P_marker[C_array[k1]] = i1;
      }
      cnt = P_diag_i[i1];
      for (j = (A_diag_i[i1]) + 1; j < (A_diag_i[i1 + 1]); j++) {
        j1 = A_diag_j[j];
        if (((CF_marker[j1]) != (-3)) && ((num_functions == 1) || ((dof_func[i1]) == (dof_func[j1])))) {
          if ((A_diag_data[j]) < 0)
            sum_N_neg += A_diag_data[j];
          else
            sum_N_pos += A_diag_data[j];
        }
        if ((j1 != (-1)) && ((P_marker[j1]) == i1)) {
          P_diag_data[cnt] = A_diag_data[j];
          P_diag_j[cnt++] = fine_to_coarse[j1];
          if ((A_diag_data[j]) < 0)
            sum_C_neg += A_diag_data[j];
          else
            sum_C_pos += A_diag_data[j];
        }
      }
      j_start = P_offd_start[i1];
      j_end = (j_start + (P_offd_i[i1 + 1])) - (P_offd_i[i1]);
      for (j = j_start; j < j_end; j++) {
        k1 = P_offd_pass[1][j];
        P_marker_offd[C_array_offd[k1]] = i1;
      }
      cnt_offd = P_offd_i[i1];
      for (j = A_offd_i[i1]; j < (A_offd_i[i1 + 1]); j++) {
        if (col_offd_S_to_A)
          j1 = map_A_to_S[A_offd_j[j]];
        else
          j1 = A_offd_j[j];
        if (((CF_marker_offd[j1]) != (-3)) && ((num_functions == 1) || ((dof_func[i1]) == (dof_func_offd[j1])))) {
          if ((A_offd_data[j]) < 0)
            sum_N_neg += A_offd_data[j];
          else
            sum_N_pos += A_offd_data[j];
        }
        if ((j1 != (-1)) && ((P_marker_offd[j1]) == i1)) {
          P_offd_data[cnt_offd] = A_offd_data[j];
          P_offd_j[cnt_offd++] = map_S_to_new[j1];
          if ((A_offd_data[j]) < 0)
            sum_C_neg += A_offd_data[j];
          else
            sum_C_pos += A_offd_data[j];
        }
      }
      diagonal = A_diag_data[A_diag_i[i1]];
      if (sum_C_neg * diagonal)
        alfa = (-sum_N_neg) / (sum_C_neg * diagonal);
      if (sum_C_pos * diagonal)
        beta = (-sum_N_pos) / (sum_C_pos * diagonal);
      for (j = P_diag_i[i1]; j < cnt; j++)
        if ((P_diag_data[j]) < 0)
          (P_diag_data[j]) -= alfa;
        else
          (P_diag_data[j]) -= beta;
      for (j = P_offd_i[i1]; j < cnt_offd; j++)
        if ((P_offd_data[j]) < 0)
          (P_offd_data[j]) -= alfa;
        else
          (P_offd_data[j]) -= beta;
    }
    old_Pext_send_size = 0;
    old_Pext_recv_size = 0;
    hypre_Free((char*)(P_diag_pass[1])), P_diag_pass[1] = (void*)0;
    if (num_procs > 1)
      hypre_Free((char*)(P_offd_pass[1])), P_offd_pass[1] = (void*)0;
    if (new_num_cols_offd > n_coarse_offd) {
      hypre_Free((char*)C_array_offd), C_array_offd = (void*)0;
      C_array_offd = (int*)(hypre_CAlloc((unsigned)new_num_cols_offd, (unsigned)(sizeof(int))));
    }
    for (pass = 2; pass < num_passes; pass++) {
      if (num_procs > 1) {
        Pext_send_size = Pext_send_map_start[pass][num_sends];
        if (Pext_send_size > old_Pext_send_size) {
          hypre_Free((char*)Pext_send_data), Pext_send_data = (void*)0;
          Pext_send_data = (double*)(hypre_CAlloc((unsigned)Pext_send_size, (unsigned)(sizeof(double))));
        }
        old_Pext_send_size = Pext_send_size;
        cnt_offd = 0;
        for (i = 0; i < num_sends; i++) {
          for (j = send_map_start[i]; j < (send_map_start[i + 1]); j++) {
            j1 = send_map_elmt[j];
            if ((assigned[j1]) == (pass - 1)) {
              j_start = P_diag_i[j1];
              j_end = P_diag_i[j1 + 1];
              for (k = j_start; k < j_end; k++) {
                Pext_send_data[cnt_offd++] = P_diag_data[k];
              }
              j_start = P_offd_i[j1];
              j_end = P_offd_i[j1 + 1];
              for (k = j_start; k < j_end; k++) {
                Pext_send_data[cnt_offd++] = P_offd_data[k];
              }
            }
          }
        }
        (tmp_comm_pkg)->num_sends = num_sends;
        (tmp_comm_pkg)->send_map_starts = Pext_send_map_start[pass];
        (tmp_comm_pkg)->num_recvs = num_recvs;
        (tmp_comm_pkg)->recv_vec_starts = Pext_recv_vec_start[pass];
        Pext_recv_size = Pext_recv_vec_start[pass][num_recvs];
        if (Pext_recv_size > old_Pext_recv_size) {
          hypre_Free((char*)Pext_data), Pext_data = (void*)0;
          Pext_data = (double*)(hypre_CAlloc((unsigned)Pext_recv_size, (unsigned)(sizeof(double))));
        }
        old_Pext_recv_size = Pext_recv_size;
        comm_handle = hypre_ParCSRCommHandleCreate(1, tmp_comm_pkg, Pext_send_data, Pext_data);
        hypre_ParCSRCommHandleDestroy(comm_handle);
        hypre_Free((char*)(Pext_send_map_start[pass])), Pext_send_map_start[pass] = (void*)0;
        hypre_Free((char*)(Pext_recv_vec_start[pass])), Pext_recv_vec_start[pass] = (void*)0;
      }
      for (i = pass_pointer[pass]; i < (pass_pointer[pass + 1]); i++) {
        i1 = pass_array[i];
        sum_C_neg = 0;
        sum_C_pos = 0;
        sum_N_neg = 0;
        sum_N_pos = 0;
        j_start = P_diag_start[i1];
        j_end = (j_start + (P_diag_i[i1 + 1])) - (P_diag_i[i1]);
        cnt = P_diag_i[i1];
        for (j = j_start; j < j_end; j++) {
          k1 = P_diag_pass[pass][j];
          C_array[k1] = cnt;
          P_diag_data[cnt] = 0;
          P_diag_j[cnt++] = k1;
        }
        j_start = P_offd_start[i1];
        j_end = (j_start + (P_offd_i[i1 + 1])) - (P_offd_i[i1]);
        cnt_offd = P_offd_i[i1];
        for (j = j_start; j < j_end; j++) {
          k1 = P_offd_pass[pass][j];
          C_array_offd[k1] = cnt_offd;
          P_offd_data[cnt_offd] = 0;
          P_offd_j[cnt_offd++] = k1;
        }
        for (j = S_diag_i[i1]; j < (S_diag_i[i1 + 1]); j++) {
          j1 = S_diag_j[j];
          if ((assigned[j1]) == (pass - 1))
            P_marker[j1] = i1;
        }
        for (j = S_offd_i[i1]; j < (S_offd_i[i1 + 1]); j++) {
          j1 = S_offd_j[j];
          if ((assigned_offd[j1]) == (pass - 1))
            P_marker_offd[j1] = i1;
        }
        for (j = (A_diag_i[i1]) + 1; j < (A_diag_i[i1 + 1]); j++) {
          j1 = A_diag_j[j];
          if ((P_marker[j1]) == i1) {
            for (k = P_diag_i[j1]; k < (P_diag_i[j1 + 1]); k++) {
              k1 = P_diag_j[k];
              alfa = (A_diag_data[j]) * (P_diag_data[k]);
              P_diag_data[C_array[k1]] += alfa;
              if (alfa < 0) {
                sum_C_neg += alfa;
                sum_N_neg += alfa;
              }
              else {
                sum_C_pos += alfa;
                sum_N_pos += alfa;
              }
            }
            for (k = P_offd_i[j1]; k < (P_offd_i[j1 + 1]); k++) {
              k1 = P_offd_j[k];
              alfa = (A_diag_data[j]) * (P_offd_data[k]);
              P_offd_data[C_array_offd[k1]] += alfa;
              if (alfa < 0) {
                sum_C_neg += alfa;
                sum_N_neg += alfa;
              }
              else {
                sum_C_pos += alfa;
                sum_N_pos += alfa;
              }
            }
          }
          else {
            if (((CF_marker[j1]) != (-3)) && ((num_functions == 1) || ((dof_func[i1]) == (dof_func[j1])))) {
              if ((A_diag_data[j]) < 0)
                sum_N_neg += A_diag_data[j];
              else
                sum_N_pos += A_diag_data[j];
            }
          }
        }
        for (j = A_offd_i[i1]; j < (A_offd_i[i1 + 1]); j++) {
          if (col_offd_S_to_A)
            j1 = map_A_to_S[A_offd_j[j]];
          else
            j1 = A_offd_j[j];
          if ((j1 > (-1)) && ((P_marker_offd[j1]) == i1)) {
            j_start = Pext_start[j1];
            j_end = j_start + (Pext_i[j1 + 1]);
            for (k = j_start; k < j_end; k++) {
              k1 = Pext_pass[pass][k];
              alfa = (A_offd_data[j]) * (Pext_data[k]);
              if (k1 < 0)
                P_diag_data[C_array[(-k1) - 1]] += alfa;
              else
                P_offd_data[C_array_offd[k1]] += alfa;
              if (alfa < 0) {
                sum_C_neg += alfa;
                sum_N_neg += alfa;
              }
              else {
                sum_C_pos += alfa;
                sum_N_pos += alfa;
              }
            }
          }
          else {
            if (((CF_marker_offd[j1]) != (-3)) && ((num_functions == 1) || ((dof_func_offd[j1]) == (dof_func[i1])))) {
              if ((A_offd_data[j]) < 0)
                sum_N_neg += A_offd_data[j];
              else
                sum_N_pos += A_offd_data[j];
            }
          }
        }
        diagonal = A_diag_data[A_diag_i[i1]];
        if (sum_C_neg * diagonal)
          alfa = (-sum_N_neg) / (sum_C_neg * diagonal);
        if (sum_C_pos * diagonal)
          beta = (-sum_N_pos) / (sum_C_pos * diagonal);
        for (j = P_diag_i[i1]; j < (P_diag_i[i1 + 1]); j++)
          if ((P_diag_data[j]) < 0)
            (P_diag_data[j]) -= alfa;
          else
            (P_diag_data[j]) -= beta;
        for (j = P_offd_i[i1]; j < (P_offd_i[i1 + 1]); j++)
          if ((P_offd_data[j]) < 0)
            (P_offd_data[j]) -= alfa;
          else
            (P_offd_data[j]) -= beta;
      }
      hypre_Free((char*)(P_diag_pass[pass])), P_diag_pass[pass] = (void*)0;
      if (num_procs > 1) {
        hypre_Free((char*)(P_offd_pass[pass])), P_offd_pass[pass] = (void*)0;
        hypre_Free((char*)(Pext_pass[pass])), Pext_pass[pass] = (void*)0;
      }
    }
  }
  else {
    pass_length = (pass_pointer[2]) - (pass_pointer[1]);
    for (k = 0; k < num_threads; k++) {
      size = pass_length / num_threads;
      rest = pass_length - (size * num_threads);
      if (k < rest) {
        ns = (k * size) + k;
        ne = (((k + 1) * size) + k) + 1;
      }
      else {
        ns = (k * size) + rest;
        ne = ((k + 1) * size) + rest;
      }
      ns = (pass_pointer[1]) + ns;
      ne = (pass_pointer[1]) + ne;
      tmp_marker = (void*)0;
      if (n_fine)
        tmp_marker = (int*)(hypre_CAlloc((unsigned)n_fine, (unsigned)(sizeof(int))));
      tmp_marker_offd = (void*)0;
      if (num_cols_offd)
        tmp_marker_offd = (int*)(hypre_CAlloc((unsigned)num_cols_offd, (unsigned)(sizeof(int))));
      for (i = 0; i < n_fine; i++)
        tmp_marker[i] = -1;
      for (i = 0; i < num_cols_offd; i++)
        tmp_marker_offd[i] = -1;
      for (i = ns; i < ne; i++) {
        i1 = pass_array[i];
        sum_C = 0;
        sum_N = 0;
        j_start = P_diag_start[i1];
        j_end = (j_start + (P_diag_i[i1 + 1])) - (P_diag_i[i1]);
        for (j = j_start; j < j_end; j++) {
          k1 = P_diag_pass[1][j];
          tmp_marker[C_array[k1]] = i1;
        }
        cnt = P_diag_i[i1];
        for (j = (A_diag_i[i1]) + 1; j < (A_diag_i[i1 + 1]); j++) {
          j1 = A_diag_j[j];
          if (((CF_marker[j1]) != (-3)) && ((num_functions == 1) || ((dof_func[i1]) == (dof_func[j1]))))
            sum_N += A_diag_data[j];
          if ((j1 != (-1)) && ((tmp_marker[j1]) == i1)) {
            P_diag_data[cnt] = A_diag_data[j];
            P_diag_j[cnt++] = fine_to_coarse[j1];
            sum_C += A_diag_data[j];
          }
        }
        j_start = P_offd_start[i1];
        j_end = (j_start + (P_offd_i[i1 + 1])) - (P_offd_i[i1]);
        for (j = j_start; j < j_end; j++) {
          k1 = P_offd_pass[1][j];
          tmp_marker_offd[C_array_offd[k1]] = i1;
        }
        cnt_offd = P_offd_i[i1];
        for (j = A_offd_i[i1]; j < (A_offd_i[i1 + 1]); j++) {
          if (col_offd_S_to_A)
            j1 = map_A_to_S[A_offd_j[j]];
          else
            j1 = A_offd_j[j];
          if (((CF_marker_offd[j1]) != (-3)) && ((num_functions == 1) || ((dof_func[i1]) == (dof_func_offd[j1]))))
            sum_N += A_offd_data[j];
          if ((j1 != (-1)) && ((tmp_marker_offd[j1]) == i1)) {
            P_offd_data[cnt_offd] = A_offd_data[j];
            P_offd_j[cnt_offd++] = map_S_to_new[j1];
            sum_C += A_offd_data[j];
          }
        }
        diagonal = A_diag_data[A_diag_i[i1]];
        if (sum_C * diagonal)
          alfa = (-sum_N) / (sum_C * diagonal);
        for (j = P_diag_i[i1]; j < cnt; j++)
          (P_diag_data[j]) -= alfa;
        for (j = P_offd_i[i1]; j < cnt_offd; j++)
          (P_offd_data[j]) -= alfa;
      }
      hypre_Free((char*)tmp_marker), tmp_marker = (void*)0;
      hypre_Free((char*)tmp_marker_offd), tmp_marker_offd = (void*)0;
    }
    old_Pext_send_size = 0;
    old_Pext_recv_size = 0;
    hypre_Free((char*)(P_diag_pass[1])), P_diag_pass[1] = (void*)0;
    if (num_procs > 1)
      hypre_Free((char*)(P_offd_pass[1])), P_offd_pass[1] = (void*)0;
    for (pass = 2; pass < num_passes; pass++) {
      if (num_procs > 1) {
        Pext_send_size = Pext_send_map_start[pass][num_sends];
        if (Pext_send_size > old_Pext_send_size) {
          hypre_Free((char*)Pext_send_data), Pext_send_data = (void*)0;
          Pext_send_data = (double*)(hypre_CAlloc((unsigned)Pext_send_size, (unsigned)(sizeof(double))));
        }
        old_Pext_send_size = Pext_send_size;
        cnt_offd = 0;
        for (i = 0; i < num_sends; i++) {
          for (j = send_map_start[i]; j < (send_map_start[i + 1]); j++) {
            j1 = send_map_elmt[j];
            if ((assigned[j1]) == (pass - 1)) {
              j_start = P_diag_i[j1];
              j_end = P_diag_i[j1 + 1];
              for (k = j_start; k < j_end; k++) {
                Pext_send_data[cnt_offd++] = P_diag_data[k];
              }
              j_start = P_offd_i[j1];
              j_end = P_offd_i[j1 + 1];
              for (k = j_start; k < j_end; k++) {
                Pext_send_data[cnt_offd++] = P_offd_data[k];
              }
            }
          }
        }
        (tmp_comm_pkg)->num_sends = num_sends;
        (tmp_comm_pkg)->send_map_starts = Pext_send_map_start[pass];
        (tmp_comm_pkg)->num_recvs = num_recvs;
        (tmp_comm_pkg)->recv_vec_starts = Pext_recv_vec_start[pass];
        Pext_recv_size = Pext_recv_vec_start[pass][num_recvs];
        if (Pext_recv_size > old_Pext_recv_size) {
          hypre_Free((char*)Pext_data), Pext_data = (void*)0;
          Pext_data = (double*)(hypre_CAlloc((unsigned)Pext_recv_size, (unsigned)(sizeof(double))));
        }
        old_Pext_recv_size = Pext_recv_size;
        comm_handle = hypre_ParCSRCommHandleCreate(1, tmp_comm_pkg, Pext_send_data, Pext_data);
        hypre_ParCSRCommHandleDestroy(comm_handle);
        hypre_Free((char*)(Pext_send_map_start[pass])), Pext_send_map_start[pass] = (void*)0;
        hypre_Free((char*)(Pext_recv_vec_start[pass])), Pext_recv_vec_start[pass] = (void*)0;
      }
      pass_length = (pass_pointer[pass + 1]) - (pass_pointer[pass]);
      for (k = 0; k < num_threads; k++) {
        size = pass_length / num_threads;
        rest = pass_length - (size * num_threads);
        if (k < rest) {
          ns = (k * size) + k;
          ne = (((k + 1) * size) + k) + 1;
        }
        else {
          ns = (k * size) + rest;
          ne = ((k + 1) * size) + rest;
        }
        ns = (pass_pointer[pass]) + ns;
        ne = (pass_pointer[pass]) + ne;
        tmp_marker = (void*)0;
        if (n_fine)
          tmp_marker = (int*)(hypre_CAlloc((unsigned)n_fine, (unsigned)(sizeof(int))));
        tmp_marker_offd = (void*)0;
        if (num_cols_offd)
          tmp_marker_offd = (int*)(hypre_CAlloc((unsigned)num_cols_offd, (unsigned)(sizeof(int))));
        tmp_array = (void*)0;
        if (n_coarse)
          tmp_array = (int*)(hypre_CAlloc((unsigned)n_coarse, (unsigned)(sizeof(int))));
        tmp_array_offd = (void*)0;
        if (new_num_cols_offd > n_coarse_offd)
          tmp_array_offd = (int*)(hypre_CAlloc((unsigned)new_num_cols_offd, (unsigned)(sizeof(int))));
        else
          tmp_array_offd = (int*)(hypre_CAlloc((unsigned)n_coarse_offd, (unsigned)(sizeof(int))));
        for (i = 0; i < n_fine; i++)
          tmp_marker[i] = -1;
        for (i = 0; i < num_cols_offd; i++)
          tmp_marker_offd[i] = -1;
        for (i = ns; i < ne; i++) {
          i1 = pass_array[i];
          sum_C = 0;
          sum_N = 0;
          j_start = P_diag_start[i1];
          j_end = (j_start + (P_diag_i[i1 + 1])) - (P_diag_i[i1]);
          cnt = P_diag_i[i1];
          for (j = j_start; j < j_end; j++) {
            k1 = P_diag_pass[pass][j];
            tmp_array[k1] = cnt;
            P_diag_data[cnt] = 0;
            P_diag_j[cnt++] = k1;
          }
          j_start = P_offd_start[i1];
          j_end = (j_start + (P_offd_i[i1 + 1])) - (P_offd_i[i1]);
          cnt_offd = P_offd_i[i1];
          for (j = j_start; j < j_end; j++) {
            k1 = P_offd_pass[pass][j];
            tmp_array_offd[k1] = cnt_offd;
            P_offd_data[cnt_offd] = 0;
            P_offd_j[cnt_offd++] = k1;
          }
          for (j = S_diag_i[i1]; j < (S_diag_i[i1 + 1]); j++) {
            j1 = S_diag_j[j];
            if ((assigned[j1]) == (pass - 1))
              tmp_marker[j1] = i1;
          }
          for (j = S_offd_i[i1]; j < (S_offd_i[i1 + 1]); j++) {
            j1 = S_offd_j[j];
            if ((assigned_offd[j1]) == (pass - 1))
              tmp_marker_offd[j1] = i1;
          }
          for (j = (A_diag_i[i1]) + 1; j < (A_diag_i[i1 + 1]); j++) {
            j1 = A_diag_j[j];
            if ((tmp_marker[j1]) == i1) {
              for (k2 = P_diag_i[j1]; k2 < (P_diag_i[j1 + 1]); k2++) {
                k1 = P_diag_j[k2];
                alfa = (A_diag_data[j]) * (P_diag_data[k2]);
                P_diag_data[tmp_array[k1]] += alfa;
                sum_C += alfa;
                sum_N += alfa;
              }
              for (k2 = P_offd_i[j1]; k2 < (P_offd_i[j1 + 1]); k2++) {
                k1 = P_offd_j[k2];
                alfa = (A_diag_data[j]) * (P_offd_data[k2]);
                P_offd_data[tmp_array_offd[k1]] += alfa;
                sum_C += alfa;
                sum_N += alfa;
              }
            }
            else {
              if (((CF_marker[j1]) != (-3)) && ((num_functions == 1) || ((dof_func[i1]) == (dof_func[j1]))))
                sum_N += A_diag_data[j];
            }
          }
          for (j = A_offd_i[i1]; j < (A_offd_i[i1 + 1]); j++) {
            if (col_offd_S_to_A)
              j1 = map_A_to_S[A_offd_j[j]];
            else
              j1 = A_offd_j[j];
            if ((j1 > (-1)) && ((tmp_marker_offd[j1]) == i1)) {
              j_start = Pext_start[j1];
              j_end = j_start + (Pext_i[j1 + 1]);
              for (k2 = j_start; k2 < j_end; k2++) {
                k1 = Pext_pass[pass][k2];
                alfa = (A_offd_data[j]) * (Pext_data[k2]);
                if (k1 < 0)
                  P_diag_data[tmp_array[(-k1) - 1]] += alfa;
                else
                  P_offd_data[tmp_array_offd[k1]] += alfa;
                sum_C += alfa;
                sum_N += alfa;
              }
            }
            else {
              if (((CF_marker_offd[j1]) != (-3)) && ((num_functions == 1) || ((dof_func_offd[j1]) == (dof_func[i1]))))
                sum_N += A_offd_data[j];
            }
          }
          diagonal = A_diag_data[A_diag_i[i1]];
          if (sum_C * diagonal)
            alfa = (-sum_N) / (sum_C * diagonal);
          for (j = P_diag_i[i1]; j < (P_diag_i[i1 + 1]); j++)
            (P_diag_data[j]) -= alfa;
          for (j = P_offd_i[i1]; j < (P_offd_i[i1 + 1]); j++)
            (P_offd_data[j]) -= alfa;
        }
        hypre_Free((char*)tmp_marker), tmp_marker = (void*)0;
        hypre_Free((char*)tmp_marker_offd), tmp_marker_offd = (void*)0;
        hypre_Free((char*)tmp_array), tmp_array = (void*)0;
        hypre_Free((char*)tmp_array_offd), tmp_array_offd = (void*)0;
      }
      hypre_Free((char*)(P_diag_pass[pass])), P_diag_pass[pass] = (void*)0;
      if (num_procs > 1) {
        hypre_Free((char*)(P_offd_pass[pass])), P_offd_pass[pass] = (void*)0;
        hypre_Free((char*)(Pext_pass[pass])), Pext_pass[pass] = (void*)0;
      }
    }
  }
  hypre_Free((char*)CF_marker_offd), CF_marker_offd = (void*)0;
  hypre_Free((char*)Pext_send_map_start), Pext_send_map_start = (void*)0;
  hypre_Free((char*)Pext_recv_vec_start), Pext_recv_vec_start = (void*)0;
  if (n_coarse)
    hypre_Free((char*)C_array), C_array = (void*)0;
  hypre_Free((char*)C_array_offd), C_array_offd = (void*)0;
  hypre_Free((char*)dof_func_offd), dof_func_offd = (void*)0;
  hypre_Free((char*)Pext_send_data), Pext_send_data = (void*)0;
  hypre_Free((char*)Pext_data), Pext_data = (void*)0;
  hypre_Free((char*)P_diag_pass), P_diag_pass = (void*)0;
  hypre_Free((char*)P_offd_pass), P_offd_pass = (void*)0;
  hypre_Free((char*)Pext_pass), Pext_pass = (void*)0;
  hypre_Free((char*)P_diag_start), P_diag_start = (void*)0;
  hypre_Free((char*)P_offd_start), P_offd_start = (void*)0;
  hypre_Free((char*)Pext_start), Pext_start = (void*)0;
  hypre_Free((char*)Pext_i), Pext_i = (void*)0;
  hypre_Free((char*)fine_to_coarse), fine_to_coarse = (void*)0;
  hypre_Free((char*)assigned), assigned = (void*)0;
  hypre_Free((char*)assigned_offd), assigned_offd = (void*)0;
  hypre_Free((char*)pass_pointer), pass_pointer = (void*)0;
  hypre_Free((char*)pass_array), pass_array = (void*)0;
  hypre_Free((char*)map_S_to_new), map_S_to_new = (void*)0;
  hypre_Free((char*)map_A_to_S), map_A_to_S = (void*)0;
  hypre_Free((char*)P_marker), P_marker = (void*)0;
  if (num_procs > 1)
    hypre_Free((char*)tmp_comm_pkg), tmp_comm_pkg = (void*)0;
  P = hypre_ParCSRMatrixCreate(comm, (A)->global_num_rows, total_global_cpts, (A)->col_starts, num_cpts_global, 0, P_diag_i[n_fine], P_offd_i[n_fine]);
  P_diag = (P)->diag;
  (P_diag)->data = P_diag_data;
  (P_diag)->i = P_diag_i;
  (P_diag)->j = P_diag_j;
  P_offd = (P)->offd;
  (P_offd)->data = P_offd_data;
  (P_offd)->i = P_offd_i;
  (P_offd)->j = P_offd_j;
  (P)->owns_row_starts = 0;
  if ((trunc_factor != 0.0) || (P_max_elmts != 0)) {
    hypre_BoomerAMGInterpTruncation(P, trunc_factor, P_max_elmts);
    P_diag_data = (P_diag)->data;
    P_diag_i = (P_diag)->i;
    P_diag_j = (P_diag)->j;
    P_offd_data = (P_offd)->data;
    P_offd_i = (P_offd)->i;
    P_offd_j = (P_offd)->j;
  }
  P_offd_size = P_offd_i[n_fine];
  num_cols_offd_P = 0;
  if (P_offd_size) {
    if (new_num_cols_offd > num_cols_offd) {
      hypre_Free((char*)P_marker_offd), P_marker_offd = (void*)0;
      P_marker_offd = (int*)(hypre_CAlloc((unsigned)new_num_cols_offd, (unsigned)(sizeof(int))));
    }
    for (i = 0; i < new_num_cols_offd; i++)
      P_marker_offd[i] = 0;
    num_cols_offd_P = 0;
    for (i = 0; i < P_offd_size; i++) {
      index = P_offd_j[i];
      if (!(P_marker_offd[index])) {
        num_cols_offd_P++;
        P_marker_offd[index] = 1;
      }
    }
    col_map_offd_P = (int*)(hypre_CAlloc((unsigned)num_cols_offd_P, (unsigned)(sizeof(int))));
    permute = (int*)(hypre_CAlloc((unsigned)(new_counter[num_passes - 1]), (unsigned)(sizeof(int))));
    big_permute = (int*)(hypre_CAlloc((unsigned)(new_counter[num_passes - 1]), (unsigned)(sizeof(int))));
    for (i = 0; i < (new_counter[num_passes - 1]); i++)
      big_permute[i] = -1;
    cnt = 0;
    for (i = 0; i < (num_passes - 1); i++) {
      for (j = new_counter[i]; j < (new_counter[i + 1]); j++) {
        if (P_marker_offd[j]) {
          col_map_offd_P[cnt] = new_elmts[i][j - (new_counter[i])];
          big_permute[j] = col_map_offd_P[cnt++];
        }
      }
    }
    hypre_BigQsort0(col_map_offd_P, 0, num_cols_offd_P - 1);
    for (i = 0; i < (new_counter[num_passes - 1]); i++) {
      big_value = big_permute[i];
      if (big_value != (-1))
        permute[i] = hypre_BigBinarySearch(col_map_offd_P, big_value, num_cols_offd_P);
    }
    for (i = 0; i < P_offd_size; i++)
      P_offd_j[i] = permute[P_offd_j[i]];
  }
  if (num_procs > 1) {
    for (i = 0; i < (num_passes - 1); i++)
      hypre_Free((char*)(new_elmts[i])), new_elmts[i] = (void*)0;
  }
  hypre_Free((char*)P_marker_offd), P_marker_offd = (void*)0;
  hypre_Free((char*)permute), permute = (void*)0;
  hypre_Free((char*)big_permute), big_permute = (void*)0;
  hypre_Free((char*)new_elmts), new_elmts = (void*)0;
  hypre_Free((char*)new_counter), new_counter = (void*)0;
  if (num_cols_offd_P) {
    (P)->col_map_offd = col_map_offd_P;
    (P_offd)->num_cols = num_cols_offd_P;
  }
  if (n_SF) {
    for (i = 0; i < n_fine; i++)
      if ((CF_marker[i]) == (-3))
        CF_marker[i] = -1;
  }
  if (num_procs > 1) {
    hypre_MatvecCommPkgCreate(P);
  }
  *P_ptr = P;
  return 0;
}
//=================== par_nodal_systems.c ==================
int hypre_BoomerAMGCreateNodalA(hypre_ParCSRMatrix* A, int num_functions, int* dof_func, int option, hypre_ParCSRMatrix** AN_ptr) {
  MPI_Comm comm = (A)->comm;
  hypre_CSRMatrix* A_diag = (A)->diag;
  int* A_diag_i = (A_diag)->i;
  double* A_diag_data = (A_diag)->data;
  hypre_CSRMatrix* A_offd = (A)->offd;
  int* A_offd_i = (A_offd)->i;
  double* A_offd_data = (A_offd)->data;
  int* A_diag_j = (A_diag)->j;
  int* A_offd_j = (A_offd)->j;
  int* row_starts = (A)->row_starts;
  int* col_map_offd = (A)->col_map_offd;
  int num_variables = (A_diag)->num_rows;
  int num_nonzeros_offd = 0;
  int num_cols_offd = 0;
  hypre_ParCSRMatrix* AN;
  hypre_CSRMatrix* AN_diag;
  int* AN_diag_i;
  int* AN_diag_j;
  double* AN_diag_data;
  hypre_CSRMatrix* AN_offd;
  int* AN_offd_i;
  int* AN_offd_j = (void*)0;
  double* AN_offd_data = (void*)0;
  int* col_map_offd_AN = (void*)0;
  int* new_col_map_offd = (void*)0;
  int* row_starts_AN;
  int AN_num_nonzeros_diag = 0;
  int AN_num_nonzeros_offd = 0;
  int num_cols_offd_AN;
  int new_num_cols_offd;
  hypre_ParCSRCommPkg* comm_pkg = (A)->comm_pkg;
  int num_sends;
  int num_recvs;
  int* send_procs;
  int* send_map_starts;
  int* send_map_elmts;
  int* new_send_map_elmts;
  int* recv_procs;
  int* recv_vec_starts;
  hypre_ParCSRCommPkg* comm_pkg_AN;
  int* send_procs_AN;
  int* send_map_starts_AN;
  int* send_map_elmts_AN;
  int* recv_procs_AN;
  int* recv_vec_starts_AN;
  int i;
  int j;
  int k;
  int k_map;
  int ierr = 0;
  int index;
  int row;
  int start_index;
  int num_procs;
  int mode;
  int node;
  int cnt;
  int big_node;
  int new_send_elmts_size;
  int global_num_nodes;
  int num_nodes;
  int num_fun2;
  int* big_map_to_node = (void*)0;
  int* map_to_node = (void*)0;
  int* map_to_map;
  int* counter;
  MPI_Comm_size(comm, &(num_procs));
  if (!comm_pkg) {
    hypre_MatvecCommPkgCreate(A);
    comm_pkg = (A)->comm_pkg;
  }
  mode = fabs(option);
  comm_pkg_AN = (void*)0;
  col_map_offd_AN = (void*)0;
  row_starts_AN = (int*)(hypre_CAlloc((unsigned)(num_procs + 1), (unsigned)(sizeof(int))));
  for (i = 0; i < (num_procs + 1); i++) {
    row_starts_AN[i] = (row_starts[i]) / (int)num_functions;
    if (((row_starts_AN[i]) * (int)num_functions) < (row_starts[i])) {
      printf("nodes not properly aligned or incomplete info!\n");
      return 87;
    }
  }
  global_num_nodes = row_starts_AN[num_procs];
  num_nodes = num_variables / num_functions;
  num_fun2 = num_functions * num_functions;
  map_to_node = (int*)(hypre_CAlloc((unsigned)num_variables, (unsigned)(sizeof(int))));
  AN_diag_i = (int*)(hypre_CAlloc((unsigned)(num_nodes + 1), (unsigned)(sizeof(int))));
  counter = (int*)(hypre_CAlloc((unsigned)num_nodes, (unsigned)(sizeof(int))));
  for (i = 0; i < num_variables; i++)
    map_to_node[i] = i / num_functions;
  for (i = 0; i < num_nodes; i++)
    counter[i] = -1;
  AN_num_nonzeros_diag = 0;
  row = 0;
  for (i = 0; i < num_nodes; i++) {
    AN_diag_i[i] = AN_num_nonzeros_diag;
    for (j = 0; j < num_functions; j++) {
      for (k = A_diag_i[row]; k < (A_diag_i[row + 1]); k++) {
        k_map = map_to_node[A_diag_j[k]];
        if ((counter[k_map]) < i) {
          counter[k_map] = i;
          AN_num_nonzeros_diag++;
        }
      }
      row++;
    }
  }
  AN_diag_i[num_nodes] = AN_num_nonzeros_diag;
  AN_diag_j = (int*)(hypre_CAlloc((unsigned)AN_num_nonzeros_diag, (unsigned)(sizeof(int))));
  AN_diag_data = (double*)(hypre_CAlloc((unsigned)AN_num_nonzeros_diag, (unsigned)(sizeof(double))));
  AN_diag = hypre_CSRMatrixCreate(num_nodes, num_nodes, AN_num_nonzeros_diag);
  (AN_diag)->i = AN_diag_i;
  (AN_diag)->j = AN_diag_j;
  (AN_diag)->data = AN_diag_data;
  for (i = 0; i < num_nodes; i++)
    counter[i] = -1;
  index = 0;
  start_index = 0;
  row = 0;
  switch (mode) {
    case 7:
{
      for (i = 0; i < num_nodes; i++) {
        for (j = 0; j < num_functions; j++) {
          for (k = A_diag_i[row]; k < (A_diag_i[row + 1]); k++) {
            k_map = map_to_node[A_diag_j[k]];
            if ((counter[k_map]) < start_index) {
              counter[k_map] = index;
              AN_diag_j[index] = k_map;
              AN_diag_data[index] = (A_diag_data[k]) * (A_diag_data[k]);
              index++;
            }
            else {
              AN_diag_data[counter[k_map]] += (A_diag_data[k]) * (A_diag_data[k]);
            }
          }
          row++;
        }
        start_index = index;
      }
      for (i = 0; i < AN_num_nonzeros_diag; i++)
        AN_diag_data[i] = sqrt(AN_diag_data[i]);
      for (i = 0; i < num_nodes; i++) {
        index = AN_diag_i[i];
        AN_diag_data[index] = -(AN_diag_data[index]);
      }
    }
      break;
    case 1:
{
      for (i = 0; i < num_nodes; i++) {
        for (j = 0; j < num_functions; j++) {
          for (k = A_diag_i[row]; k < (A_diag_i[row + 1]); k++) {
            k_map = map_to_node[A_diag_j[k]];
            if ((counter[k_map]) < start_index) {
              counter[k_map] = index;
              AN_diag_j[index] = k_map;
              AN_diag_data[index] = (A_diag_data[k]) * (A_diag_data[k]);
              index++;
            }
            else {
              AN_diag_data[counter[k_map]] += (A_diag_data[k]) * (A_diag_data[k]);
            }
          }
          row++;
        }
        start_index = index;
      }
      for (i = 0; i < AN_num_nonzeros_diag; i++)
        AN_diag_data[i] = sqrt(AN_diag_data[i]);
    }
      break;
    case 2:
{
      for (i = 0; i < num_nodes; i++) {
        for (j = 0; j < num_functions; j++) {
          for (k = A_diag_i[row]; k < (A_diag_i[row + 1]); k++) {
            k_map = map_to_node[A_diag_j[k]];
            if ((counter[k_map]) < start_index) {
              counter[k_map] = index;
              AN_diag_j[index] = k_map;
              AN_diag_data[index] = fabs(A_diag_data[k]);
              index++;
            }
            else {
              AN_diag_data[counter[k_map]] += fabs(A_diag_data[k]);
            }
          }
          row++;
        }
        start_index = index;
      }
      for (i = 0; i < AN_num_nonzeros_diag; i++)
        (AN_diag_data[i]) /= num_fun2;
    }
      break;
    case 3:
{
      for (i = 0; i < num_nodes; i++) {
        for (j = 0; j < num_functions; j++) {
          for (k = A_diag_i[row]; k < (A_diag_i[row + 1]); k++) {
            k_map = map_to_node[A_diag_j[k]];
            if ((counter[k_map]) < start_index) {
              counter[k_map] = index;
              AN_diag_j[index] = k_map;
              AN_diag_data[index] = A_diag_data[k];
              index++;
            }
            else {
              if (fabs(A_diag_data[k]) > fabs(AN_diag_data[counter[k_map]]))
                AN_diag_data[counter[k_map]] = A_diag_data[k];
            }
          }
          row++;
        }
        start_index = index;
      }
    }
      break;
  }
  num_nonzeros_offd = A_offd_i[num_variables];
  AN_offd_i = (int*)(hypre_CAlloc((unsigned)(num_nodes + 1), (unsigned)(sizeof(int))));
  num_cols_offd_AN = 0;
  if (comm_pkg) {
    comm_pkg_AN = (hypre_ParCSRCommPkg*)(hypre_CAlloc((unsigned)1, (unsigned)(sizeof(hypre_ParCSRCommPkg))));
    (comm_pkg_AN)->comm = comm;
    num_sends = (comm_pkg)->num_sends;
    (comm_pkg_AN)->num_sends = num_sends;
    num_recvs = (comm_pkg)->num_recvs;
    (comm_pkg_AN)->num_recvs = num_recvs;
    send_procs = (comm_pkg)->send_procs;
    send_map_starts = (comm_pkg)->send_map_starts;
    send_map_elmts = (comm_pkg)->send_map_elmts;
    recv_procs = (comm_pkg)->recv_procs;
    recv_vec_starts = (comm_pkg)->recv_vec_starts;
    send_procs_AN = (void*)0;
    send_map_elmts_AN = (void*)0;
    if (num_sends) {
      send_procs_AN = (int*)(hypre_CAlloc((unsigned)num_sends, (unsigned)(sizeof(int))));
      send_map_elmts_AN = (int*)(hypre_CAlloc((unsigned)(send_map_starts[num_sends]), (unsigned)(sizeof(int))));
    }
    send_map_starts_AN = (int*)(hypre_CAlloc((unsigned)(num_sends + 1), (unsigned)(sizeof(int))));
    recv_vec_starts_AN = (int*)(hypre_CAlloc((unsigned)(num_recvs + 1), (unsigned)(sizeof(int))));
    recv_procs_AN = (void*)0;
    if (num_recvs)
      recv_procs_AN = (int*)(hypre_CAlloc((unsigned)num_recvs, (unsigned)(sizeof(int))));
    for (i = 0; i < num_sends; i++)
      send_procs_AN[i] = send_procs[i];
    for (i = 0; i < num_recvs; i++)
      recv_procs_AN[i] = recv_procs[i];
    send_map_starts_AN[0] = 0;
    cnt = 0;
    for (i = 0; i < num_sends; i++) {
      k_map = send_map_starts[i];
      if ((send_map_starts[i + 1]) - k_map)
        send_map_elmts_AN[cnt++] = (send_map_elmts[k_map]) / num_functions;
      for (j = (send_map_starts[i]) + 1; j < (send_map_starts[i + 1]); j++) {
        node = (send_map_elmts[j]) / num_functions;
        if (node > (send_map_elmts_AN[cnt - 1]))
          send_map_elmts_AN[cnt++] = node;
      }
      send_map_starts_AN[i + 1] = cnt;
    }
    (comm_pkg_AN)->send_procs = send_procs_AN;
    (comm_pkg_AN)->send_map_starts = send_map_starts_AN;
    (comm_pkg_AN)->send_map_elmts = send_map_elmts_AN;
    (comm_pkg_AN)->recv_procs = recv_procs_AN;
    (comm_pkg_AN)->recv_vec_starts = recv_vec_starts_AN;
  }
  num_cols_offd = (A_offd)->num_cols;
  hypre_Free((char*)map_to_node), map_to_node = (void*)0;
  if (num_cols_offd) {
    if (num_cols_offd > num_variables) {
      big_map_to_node = (int*)(hypre_CAlloc((unsigned)num_cols_offd, (unsigned)(sizeof(int))));
    }
    num_cols_offd_AN = 1;
    big_map_to_node[0] = (col_map_offd[0]) / (int)num_functions;
    for (i = 1; i < num_cols_offd; i++) {
      big_map_to_node[i] = (col_map_offd[i]) / (int)num_functions;
      if ((big_map_to_node[i]) > (big_map_to_node[i - 1]))
        num_cols_offd_AN++;
    }
    if (num_cols_offd_AN > num_nodes) {
      hypre_Free((char*)counter), counter = (void*)0;
      counter = (int*)(hypre_CAlloc((unsigned)num_cols_offd_AN, (unsigned)(sizeof(int))));
    }
    map_to_map = (void*)0;
    col_map_offd_AN = (void*)0;
    map_to_map = (int*)(hypre_CAlloc((unsigned)num_cols_offd, (unsigned)(sizeof(int))));
    col_map_offd_AN = (int*)(hypre_CAlloc((unsigned)num_cols_offd_AN, (unsigned)(sizeof(int))));
    col_map_offd_AN[0] = big_map_to_node[0];
    recv_vec_starts_AN[0] = 0;
    cnt = 1;
    for (i = 0; i < num_recvs; i++) {
      for (j = recv_vec_starts[i]; j < (recv_vec_starts[i + 1]); j++) {
        big_node = big_map_to_node[j];
        if (big_node > (col_map_offd_AN[cnt - 1])) {
          col_map_offd_AN[cnt++] = big_node;
        }
        map_to_map[j] = cnt - 1;
      }
      recv_vec_starts_AN[i + 1] = cnt;
    }
    for (i = 0; i < num_cols_offd_AN; i++)
      counter[i] = -1;
    AN_num_nonzeros_offd = 0;
    row = 0;
    for (i = 0; i < num_nodes; i++) {
      AN_offd_i[i] = AN_num_nonzeros_offd;
      for (j = 0; j < num_functions; j++) {
        for (k = A_offd_i[row]; k < (A_offd_i[row + 1]); k++) {
          k_map = map_to_map[A_offd_j[k]];
          if ((counter[k_map]) < i) {
            counter[k_map] = i;
            AN_num_nonzeros_offd++;
          }
        }
        row++;
      }
    }
    AN_offd_i[num_nodes] = AN_num_nonzeros_offd;
  }
  AN_offd = hypre_CSRMatrixCreate(num_nodes, num_cols_offd_AN, AN_num_nonzeros_offd);
  (AN_offd)->i = AN_offd_i;
  if (AN_num_nonzeros_offd) {
    AN_offd_j = (int*)(hypre_CAlloc((unsigned)AN_num_nonzeros_offd, (unsigned)(sizeof(int))));
    AN_offd_data = (double*)(hypre_CAlloc((unsigned)AN_num_nonzeros_offd, (unsigned)(sizeof(double))));
    (AN_offd)->j = AN_offd_j;
    (AN_offd)->data = AN_offd_data;
    for (i = 0; i < num_cols_offd_AN; i++)
      counter[i] = -1;
    index = 0;
    row = 0;
    AN_offd_i[0] = 0;
    start_index = 0;
    switch (mode) {
      case 1:
{
        for (i = 0; i < num_nodes; i++) {
          for (j = 0; j < num_functions; j++) {
            for (k = A_offd_i[row]; k < (A_offd_i[row + 1]); k++) {
              k_map = map_to_map[A_offd_j[k]];
              if ((counter[k_map]) < start_index) {
                counter[k_map] = index;
                AN_offd_j[index] = k_map;
                AN_offd_data[index] = (A_offd_data[k]) * (A_offd_data[k]);
                index++;
              }
              else {
                AN_offd_data[counter[k_map]] += (A_offd_data[k]) * (A_offd_data[k]);
              }
            }
            row++;
          }
          start_index = index;
        }
        for (i = 0; i < AN_num_nonzeros_offd; i++)
          AN_offd_data[i] = sqrt(AN_offd_data[i]);
      }
        break;
      case 2:
{
        for (i = 0; i < num_nodes; i++) {
          for (j = 0; j < num_functions; j++) {
            for (k = A_offd_i[row]; k < (A_offd_i[row + 1]); k++) {
              k_map = map_to_map[A_offd_j[k]];
              if ((counter[k_map]) < start_index) {
                counter[k_map] = index;
                AN_offd_j[index] = k_map;
                AN_offd_data[index] = fabs(A_offd_data[k]);
                index++;
              }
              else {
                AN_offd_data[counter[k_map]] += fabs(A_offd_data[k]);
              }
            }
            row++;
          }
          start_index = index;
        }
        for (i = 0; i < AN_num_nonzeros_offd; i++)
          (AN_offd_data[i]) /= num_fun2;
      }
        break;
      case 3:
{
        for (i = 0; i < num_nodes; i++) {
          for (j = 0; j < num_functions; j++) {
            for (k = A_offd_i[row]; k < (A_offd_i[row + 1]); k++) {
              k_map = map_to_map[A_offd_j[k]];
              if ((counter[k_map]) < start_index) {
                counter[k_map] = index;
                AN_offd_j[index] = k_map;
                AN_offd_data[index] = A_offd_data[k];
                index++;
              }
              else {
                if (fabs(A_offd_data[k]) > fabs(AN_offd_data[counter[k_map]]))
                  AN_offd_data[counter[k_map]] = A_offd_data[k];
              }
            }
            row++;
          }
          start_index = index;
        }
      }
        break;
    }
    hypre_Free((char*)map_to_map), map_to_map = (void*)0;
  }
  AN = hypre_ParCSRMatrixCreate(comm, global_num_nodes, global_num_nodes, row_starts_AN, row_starts_AN, num_cols_offd_AN, AN_num_nonzeros_diag, AN_num_nonzeros_offd);
  hypre_CSRMatrixDestroy((AN)->diag);
  hypre_CSRMatrixDestroy((AN)->offd);
  (AN)->diag = AN_diag;
  (AN)->offd = AN_offd;
  (AN)->col_map_offd = col_map_offd_AN;
  (AN)->comm_pkg = comm_pkg_AN;
  new_num_cols_offd = num_functions * num_cols_offd_AN;
  if (new_num_cols_offd > num_cols_offd) {
    new_col_map_offd = (int*)(hypre_CAlloc((unsigned)new_num_cols_offd, (unsigned)(sizeof(int))));
    cnt = 0;
    for (i = 0; i < num_cols_offd_AN; i++) {
      for (j = 0; j < num_functions; j++) {
        new_col_map_offd[cnt++] = ((int)num_functions * (col_map_offd_AN[i])) + (int)j;
      }
    }
    cnt = 0;
    for (i = 0; i < num_cols_offd; i++) {
      while ((col_map_offd[i]) > (new_col_map_offd[cnt]))
        cnt++;
      col_map_offd[i] = cnt++;
    }
    for (i = 0; i < (num_recvs + 1); i++) {
      recv_vec_starts[i] = num_functions * (recv_vec_starts_AN[i]);
    }
    for (i = 0; i < num_nonzeros_offd; i++) {
      j = A_offd_j[i];
      A_offd_j[i] = col_map_offd[j];
    }
    (A)->col_map_offd = new_col_map_offd;
    (A_offd)->num_cols = new_num_cols_offd;
    hypre_Free((char*)col_map_offd), col_map_offd = (void*)0;
  }
  hypre_Free((char*)big_map_to_node), big_map_to_node = (void*)0;
  new_send_elmts_size = (send_map_starts_AN[num_sends]) * num_functions;
  if (new_send_elmts_size > (send_map_starts[num_sends])) {
    new_send_map_elmts = (int*)(hypre_CAlloc((unsigned)new_send_elmts_size, (unsigned)(sizeof(int))));
    cnt = 0;
    send_map_starts[0] = 0;
    for (i = 0; i < num_sends; i++) {
      send_map_starts[i + 1] = (send_map_starts_AN[i + 1]) * num_functions;
      for (j = send_map_starts_AN[i]; j < (send_map_starts_AN[i + 1]); j++) {
        for (k = 0; k < num_functions; k++)
          new_send_map_elmts[cnt++] = ((send_map_elmts_AN[j]) * num_functions) + k;
      }
    }
    hypre_Free((char*)send_map_elmts), send_map_elmts = (void*)0;
    (comm_pkg)->send_map_elmts = new_send_map_elmts;
  }
  *AN_ptr = AN;
  hypre_Free((char*)counter), counter = (void*)0;
  return ierr;
}
int hypre_BoomerAMGCreateScalarCFS(hypre_ParCSRMatrix* SN, int* CFN_marker, int* col_offd_SN_to_AN, int num_functions, int nodal, int data, int** dof_func_ptr, int** CF_marker_ptr, int** col_offd_S_to_A_ptr, hypre_ParCSRMatrix** S_ptr) {
  MPI_Comm comm = (SN)->comm;
  hypre_ParCSRMatrix* S;
  hypre_CSRMatrix* S_diag;
  int* S_diag_i;
  int* S_diag_j;
  double* S_diag_data;
  hypre_CSRMatrix* S_offd;
  int* S_offd_i;
  int* S_offd_j;
  double* S_offd_data;
  int* row_starts_S;
  int* col_starts_S;
  int* row_starts_SN = (SN)->row_starts;
  int* col_starts_SN = (SN)->col_starts;
  hypre_CSRMatrix* SN_diag = (SN)->diag;
  int* SN_diag_i = (SN_diag)->i;
  int* SN_diag_j = (SN_diag)->j;
  double* SN_diag_data;
  hypre_CSRMatrix* SN_offd = (SN)->offd;
  int* SN_offd_i = (SN_offd)->i;
  int* SN_offd_j = (SN_offd)->j;
  double* SN_offd_data;
  int* CF_marker;
  int* col_map_offd_SN = (SN)->col_map_offd;
  int* col_map_offd_S;
  int* dof_func;
  int num_nodes = (SN_diag)->num_rows;
  int num_variables;
  hypre_ParCSRCommPkg* comm_pkg = (SN)->comm_pkg;
  int num_sends;
  int num_recvs;
  int* send_procs;
  int* send_map_starts;
  int* send_map_elmts;
  int* recv_procs;
  int* recv_vec_starts;
  hypre_ParCSRCommPkg* comm_pkg_S;
  int* send_procs_S;
  int* send_map_starts_S;
  int* send_map_elmts_S;
  int* recv_procs_S;
  int* recv_vec_starts_S;
  int* col_offd_S_to_A = (void*)0;
  int num_coarse_nodes;
  int i;
  int j;
  int k;
  int k1;
  int jj;
  int cnt;
  int row;
  int start;
  int end;
  int num_procs;
  int num_cols_offd_SN = (SN_offd)->num_cols;
  int num_cols_offd_S;
  int SN_num_nonzeros_diag;
  int SN_num_nonzeros_offd;
  int S_num_nonzeros_diag;
  int S_num_nonzeros_offd;
  int global_num_vars;
  int global_num_cols;
  int global_num_nodes;
  int ierr = 0;
  MPI_Comm_size(comm, &(num_procs));
  num_variables = num_functions * num_nodes;
  CF_marker = (int*)(hypre_CAlloc((unsigned)num_variables, (unsigned)(sizeof(int))));
  if (nodal < 0) {
    cnt = 0;
    num_coarse_nodes = 0;
    for (i = 0; i < num_nodes; i++) {
      if ((CFN_marker[i]) == 1)
        num_coarse_nodes++;
      for (j = 0; j < num_functions; j++)
        CF_marker[cnt++] = CFN_marker[i];
    }
    dof_func = (int*)(hypre_CAlloc((unsigned)(num_coarse_nodes * num_functions), (unsigned)(sizeof(int))));
    cnt = 0;
    for (i = 0; i < num_nodes; i++) {
      if ((CFN_marker[i]) == 1) {
        for (k = 0; k < num_functions; k++)
          dof_func[cnt++] = k;
      }
    }
    *dof_func_ptr = dof_func;
  }
  else {
    cnt = 0;
    for (i = 0; i < num_nodes; i++)
      for (j = 0; j < num_functions; j++)
        CF_marker[cnt++] = CFN_marker[i];
  }
  *CF_marker_ptr = CF_marker;
  row_starts_S = (int*)(hypre_CAlloc((unsigned)(num_procs + 1), (unsigned)(sizeof(int))));
  for (i = 0; i < (num_procs + 1); i++)
    row_starts_S[i] = num_functions * (row_starts_SN[i]);
  if (row_starts_SN != col_starts_SN) {
    col_starts_S = (int*)(hypre_CAlloc((unsigned)(num_procs + 1), (unsigned)(sizeof(int))));
    for (i = 0; i < (num_procs + 1); i++)
      col_starts_S[i] = num_functions * (col_starts_SN[i]);
  }
  else {
    col_starts_S = row_starts_S;
  }
  SN_num_nonzeros_diag = SN_diag_i[num_nodes];
  SN_num_nonzeros_offd = SN_offd_i[num_nodes];
  global_num_nodes = (SN)->global_num_rows;
  global_num_cols = (SN)->global_num_cols * num_functions;
  global_num_vars = global_num_nodes * num_functions;
  S_num_nonzeros_diag = num_functions * SN_num_nonzeros_diag;
  S_num_nonzeros_offd = num_functions * SN_num_nonzeros_offd;
  num_cols_offd_S = num_functions * num_cols_offd_SN;
  S = hypre_ParCSRMatrixCreate(comm, global_num_vars, global_num_cols, row_starts_S, col_starts_S, num_cols_offd_S, S_num_nonzeros_diag, S_num_nonzeros_offd);
  S_diag = (S)->diag;
  S_offd = (S)->offd;
  S_diag_i = (int*)(hypre_CAlloc((unsigned)(num_variables + 1), (unsigned)(sizeof(int))));
  S_offd_i = (int*)(hypre_CAlloc((unsigned)(num_variables + 1), (unsigned)(sizeof(int))));
  S_diag_j = (int*)(hypre_CAlloc((unsigned)S_num_nonzeros_diag, (unsigned)(sizeof(int))));
  (S_diag)->i = S_diag_i;
  (S_diag)->j = S_diag_j;
  if (data) {
    SN_diag_data = (SN_diag)->data;
    S_diag_data = (double*)(hypre_CAlloc((unsigned)S_num_nonzeros_diag, (unsigned)(sizeof(double))));
    (S_diag)->data = S_diag_data;
    if (num_cols_offd_S) {
      SN_offd_data = (SN_offd)->data;
      S_offd_data = (double*)(hypre_CAlloc((unsigned)S_num_nonzeros_offd, (unsigned)(sizeof(double))));
      (S_offd)->data = S_offd_data;
    }
  }
  (S_offd)->i = S_offd_i;
  if (comm_pkg) {
    comm_pkg_S = (hypre_ParCSRCommPkg*)(hypre_CAlloc((unsigned)1, (unsigned)(sizeof(hypre_ParCSRCommPkg))));
    (comm_pkg_S)->comm = comm;
    num_sends = (comm_pkg)->num_sends;
    (comm_pkg_S)->num_sends = num_sends;
    num_recvs = (comm_pkg)->num_recvs;
    (comm_pkg_S)->num_recvs = num_recvs;
    send_procs = (comm_pkg)->send_procs;
    send_map_starts = (comm_pkg)->send_map_starts;
    send_map_elmts = (comm_pkg)->send_map_elmts;
    recv_procs = (comm_pkg)->recv_procs;
    recv_vec_starts = (comm_pkg)->recv_vec_starts;
    send_procs_S = (void*)0;
    send_map_elmts_S = (void*)0;
    if (num_sends) {
      send_procs_S = (int*)(hypre_CAlloc((unsigned)num_sends, (unsigned)(sizeof(int))));
      send_map_elmts_S = (int*)(hypre_CAlloc((unsigned)(num_functions * (send_map_starts[num_sends])), (unsigned)(sizeof(int))));
    }
    send_map_starts_S = (int*)(hypre_CAlloc((unsigned)(num_sends + 1), (unsigned)(sizeof(int))));
    recv_vec_starts_S = (int*)(hypre_CAlloc((unsigned)(num_recvs + 1), (unsigned)(sizeof(int))));
    recv_procs_S = (void*)0;
    if (num_recvs)
      recv_procs_S = (int*)(hypre_CAlloc((unsigned)num_recvs, (unsigned)(sizeof(int))));
    send_map_starts_S[0] = 0;
    for (i = 0; i < num_sends; i++) {
      send_procs_S[i] = send_procs[i];
      send_map_starts_S[i + 1] = num_functions * (send_map_starts[i + 1]);
    }
    recv_vec_starts_S[0] = 0;
    for (i = 0; i < num_recvs; i++) {
      recv_procs_S[i] = recv_procs[i];
      recv_vec_starts_S[i + 1] = num_functions * (recv_vec_starts[i + 1]);
    }
    cnt = 0;
    for (i = 0; i < (send_map_starts[num_sends]); i++) {
      k1 = num_functions * (send_map_elmts[i]);
      for (j = 0; j < num_functions; j++) {
        send_map_elmts_S[cnt++] = k1 + j;
      }
    }
    (comm_pkg_S)->send_procs = send_procs_S;
    (comm_pkg_S)->send_map_starts = send_map_starts_S;
    (comm_pkg_S)->send_map_elmts = send_map_elmts_S;
    (comm_pkg_S)->recv_procs = recv_procs_S;
    (comm_pkg_S)->recv_vec_starts = recv_vec_starts_S;
    (S)->comm_pkg = comm_pkg_S;
  }
  if (num_cols_offd_S) {
    S_offd_j = (int*)(hypre_CAlloc((unsigned)S_num_nonzeros_offd, (unsigned)(sizeof(int))));
    (S_offd)->j = S_offd_j;
    col_map_offd_S = (int*)(hypre_CAlloc((unsigned)num_cols_offd_S, (unsigned)(sizeof(int))));
    cnt = 0;
    for (i = 0; i < num_cols_offd_SN; i++) {
      k1 = (col_map_offd_SN[i]) * num_functions;
      for (j = 0; j < num_functions; j++)
        col_map_offd_S[cnt++] = k1 + j;
    }
    (S)->col_map_offd = col_map_offd_S;
  }
  if (col_offd_SN_to_AN) {
    col_offd_S_to_A = (int*)(hypre_CAlloc((unsigned)num_cols_offd_S, (unsigned)(sizeof(int))));
    cnt = 0;
    for (i = 0; i < num_cols_offd_SN; i++) {
      k1 = (col_offd_SN_to_AN[i]) * num_functions;
      for (j = 0; j < num_functions; j++)
        col_offd_S_to_A[cnt++] = k1 + j;
    }
    *col_offd_S_to_A_ptr = col_offd_S_to_A;
  }
  cnt = 0;
  row = 0;
  for (i = 0; i < num_nodes; i++) {
    row++;
    start = cnt;
    for (j = SN_diag_i[i]; j < (SN_diag_i[i + 1]); j++) {
      jj = SN_diag_j[j];
      if (data)
        S_diag_data[cnt] = SN_diag_data[j];
      S_diag_j[cnt++] = jj * num_functions;
    }
    end = cnt;
    S_diag_i[row] = cnt;
    for (k1 = 1; k1 < num_functions; k1++) {
      row++;
      for (k = start; k < end; k++) {
        if (data)
          S_diag_data[cnt] = S_diag_data[k];
        S_diag_j[cnt++] = (S_diag_j[k]) + k1;
      }
      S_diag_i[row] = cnt;
    }
  }
  cnt = 0;
  row = 0;
  for (i = 0; i < num_nodes; i++) {
    row++;
    start = cnt;
    for (j = SN_offd_i[i]; j < (SN_offd_i[i + 1]); j++) {
      jj = SN_offd_j[j];
      if (data)
        S_offd_data[cnt] = SN_offd_data[j];
      S_offd_j[cnt++] = jj * num_functions;
    }
    end = cnt;
    S_offd_i[row] = cnt;
    for (k1 = 1; k1 < num_functions; k1++) {
      row++;
      for (k = start; k < end; k++) {
        if (data)
          S_offd_data[cnt] = S_offd_data[k];
        S_offd_j[cnt++] = (S_offd_j[k]) + k1;
      }
      S_offd_i[row] = cnt;
    }
  }
  *S_ptr = S;
  return ierr;
}
//======================== par_rap.c =======================
hypre_BigCSRMatrix* hypre_ExchangeRAPData(hypre_BigCSRMatrix* RAP_int, hypre_ParCSRCommPkg* comm_pkg_RT) {
  int* RAP_int_i;
  int* RAP_int_j = (void*)0;
  double* RAP_int_data = (void*)0;
  int num_cols = 0;
  MPI_Comm comm = (comm_pkg_RT)->comm;
  int num_recvs = (comm_pkg_RT)->num_recvs;
  int* recv_procs = (comm_pkg_RT)->recv_procs;
  int* recv_vec_starts = (comm_pkg_RT)->recv_vec_starts;
  int num_sends = (comm_pkg_RT)->num_sends;
  int* send_procs = (comm_pkg_RT)->send_procs;
  int* send_map_starts = (comm_pkg_RT)->send_map_starts;
  hypre_BigCSRMatrix* RAP_ext;
  int* RAP_ext_i;
  int* RAP_ext_j = (void*)0;
  double* RAP_ext_data = (void*)0;
  hypre_ParCSRCommHandle* comm_handle;
  hypre_ParCSRCommPkg* tmp_comm_pkg;
  int* jdata_recv_vec_starts;
  int* jdata_send_map_starts;
  int num_rows;
  int num_nonzeros;
  int i;
  int j;
  int num_procs;
  MPI_Comm_size(comm, &(num_procs));
  RAP_ext_i = (int*)(hypre_CAlloc((unsigned)((send_map_starts[num_sends]) + 1), (unsigned)(sizeof(int))));
  jdata_recv_vec_starts = (int*)(hypre_CAlloc((unsigned)(num_recvs + 1), (unsigned)(sizeof(int))));
  jdata_send_map_starts = (int*)(hypre_CAlloc((unsigned)(num_sends + 1), (unsigned)(sizeof(int))));
  if (num_recvs) {
    RAP_int_i = (RAP_int)->i;
    RAP_int_j = (RAP_int)->j;
    RAP_int_data = (RAP_int)->data;
    num_cols = (RAP_int)->num_cols;
  }
  jdata_recv_vec_starts[0] = 0;
  for (i = 0; i < num_recvs; i++) {
    jdata_recv_vec_starts[i + 1] = RAP_int_i[recv_vec_starts[i + 1]];
  }
  for (i = num_recvs; i > 0; i--)
    for (j = recv_vec_starts[i]; j > (recv_vec_starts[i - 1]); j--)
      (RAP_int_i[j]) -= (RAP_int_i[j - 1]);
  if (num_recvs && num_sends)
    comm_handle = hypre_ParCSRCommHandleCreate(12, comm_pkg_RT, &(RAP_int_i[1]), &(RAP_ext_i[1]));
  else
    if (num_recvs)
      comm_handle = hypre_ParCSRCommHandleCreate(12, comm_pkg_RT, &(RAP_int_i[1]), (void*)0);
    else
      if (num_sends)
        comm_handle = hypre_ParCSRCommHandleCreate(12, comm_pkg_RT, (void*)0, &(RAP_ext_i[1]));
  tmp_comm_pkg = (hypre_ParCSRCommPkg*)(hypre_CAlloc((unsigned)1, (unsigned)(sizeof(hypre_ParCSRCommPkg))));
  (tmp_comm_pkg)->comm = comm;
  (tmp_comm_pkg)->num_sends = num_recvs;
  (tmp_comm_pkg)->num_recvs = num_sends;
  (tmp_comm_pkg)->send_procs = recv_procs;
  (tmp_comm_pkg)->recv_procs = send_procs;
  hypre_ParCSRCommHandleDestroy(comm_handle);
  comm_handle = (void*)0;
  for (i = 0; i < num_sends; i++)
    for (j = send_map_starts[i]; j < (send_map_starts[i + 1]); j++)
      RAP_ext_i[j + 1] += RAP_ext_i[j];
  num_rows = send_map_starts[num_sends];
  num_nonzeros = RAP_ext_i[num_rows];
  if (num_nonzeros) {
    RAP_ext_j = (int*)(hypre_CAlloc((unsigned)num_nonzeros, (unsigned)(sizeof(int))));
    RAP_ext_data = (double*)(hypre_CAlloc((unsigned)num_nonzeros, (unsigned)(sizeof(double))));
  }
  for (i = 0; i < (num_sends + 1); i++) {
    jdata_send_map_starts[i] = RAP_ext_i[send_map_starts[i]];
  }
  (tmp_comm_pkg)->recv_vec_starts = jdata_send_map_starts;
  (tmp_comm_pkg)->send_map_starts = jdata_recv_vec_starts;
  comm_handle = hypre_ParCSRCommHandleCreate(1, tmp_comm_pkg, RAP_int_data, RAP_ext_data);
  hypre_ParCSRCommHandleDestroy(comm_handle);
  comm_handle = (void*)0;
  comm_handle = hypre_ParCSRCommHandleCreate(21, tmp_comm_pkg, RAP_int_j, RAP_ext_j);
  RAP_ext = hypre_BigCSRMatrixCreate(num_rows, num_cols, num_nonzeros);
  (RAP_ext)->i = RAP_ext_i;
  if (num_nonzeros) {
    (RAP_ext)->j = RAP_ext_j;
    (RAP_ext)->data = RAP_ext_data;
  }
  hypre_ParCSRCommHandleDestroy(comm_handle);
  comm_handle = (void*)0;
  hypre_Free((char*)jdata_recv_vec_starts), jdata_recv_vec_starts = (void*)0;
  hypre_Free((char*)jdata_send_map_starts), jdata_send_map_starts = (void*)0;
  hypre_Free((char*)tmp_comm_pkg), tmp_comm_pkg = (void*)0;
  return RAP_ext;
}
int hypre_BoomerAMGBuildCoarseOperator(hypre_ParCSRMatrix* RT, hypre_ParCSRMatrix* A, hypre_ParCSRMatrix* P, hypre_ParCSRMatrix** RAP_ptr) {
  MPI_Comm comm = (A)->comm;
  hypre_CSRMatrix* RT_diag = (RT)->diag;
  hypre_CSRMatrix* RT_offd = (RT)->offd;
  int num_cols_diag_RT = (RT_diag)->num_cols;
  int num_cols_offd_RT = (RT_offd)->num_cols;
  int num_rows_offd_RT = (RT_offd)->num_rows;
  hypre_ParCSRCommPkg* comm_pkg_RT = (RT)->comm_pkg;
  int num_recvs_RT = 0;
  int num_sends_RT = 0;
  int* send_map_starts_RT;
  int* send_map_elmts_RT;
  hypre_CSRMatrix* A_diag = (A)->diag;
  double* A_diag_data = (A_diag)->data;
  int* A_diag_i = (A_diag)->i;
  int* A_diag_j = (A_diag)->j;
  hypre_CSRMatrix* A_offd = (A)->offd;
  double* A_offd_data = (A_offd)->data;
  int* A_offd_i = (A_offd)->i;
  int* A_offd_j = (A_offd)->j;
  int num_cols_diag_A = (A_diag)->num_cols;
  int num_cols_offd_A = (A_offd)->num_cols;
  hypre_CSRMatrix* P_diag = (P)->diag;
  double* P_diag_data = (P_diag)->data;
  int* P_diag_i = (P_diag)->i;
  int* P_diag_j = (P_diag)->j;
  hypre_CSRMatrix* P_offd = (P)->offd;
  int* col_map_offd_P = (P)->col_map_offd;
  double* P_offd_data = (P_offd)->data;
  int* P_offd_i = (P_offd)->i;
  int* P_offd_j = (P_offd)->j;
  int first_col_diag_P = (P)->first_col_diag;
  int last_col_diag_P;
  int num_cols_diag_P = (P_diag)->num_cols;
  int num_cols_offd_P = (P_offd)->num_cols;
  int* coarse_partitioning = (P)->col_starts;
  int* RT_partitioning = (RT)->col_starts;
  hypre_ParCSRMatrix* RAP;
  int* col_map_offd_RAP;
  int* new_col_map_offd_RAP;
  hypre_BigCSRMatrix* RAP_int = (void*)0;
  double* RAP_int_data;
  int* RAP_int_i;
  int* RAP_int_j;
  hypre_BigCSRMatrix* RAP_ext;
  double* RAP_ext_data;
  int* RAP_ext_i;
  int* RAP_ext_j;
  int* int_RAP_ext_j = (void*)0;
  hypre_CSRMatrix* RAP_diag;
  double* RAP_diag_data;
  int* RAP_diag_i;
  int* RAP_diag_j;
  hypre_CSRMatrix* RAP_offd;
  double* RAP_offd_data;
  int* RAP_offd_i;
  int* RAP_offd_j;
  int RAP_size;
  int RAP_ext_size;
  int RAP_diag_size;
  int RAP_offd_size;
  int P_ext_diag_size;
  int P_ext_offd_size;
  int first_col_diag_RAP;
  int last_col_diag_RAP;
  int num_cols_offd_RAP = 0;
  hypre_CSRMatrix* R_diag;
  double* R_diag_data;
  int* R_diag_i;
  int* R_diag_j;
  hypre_CSRMatrix* R_offd;
  double* R_offd_data;
  int* R_offd_i;
  int* R_offd_j;
  hypre_BigCSRMatrix* Ps_ext;
  double* Ps_ext_data;
  int* Ps_ext_i;
  int* Ps_ext_j;
  double* P_ext_diag_data;
  int* P_ext_diag_i;
  int* P_ext_diag_j;
  double* P_ext_offd_data;
  int* P_ext_offd_i;
  int* P_ext_offd_j;
  int* col_map_offd_Pext;
  int* map_P_to_Pext;
  int* map_P_to_RAP;
  int* map_Pext_to_RAP;
  int* P_marker;
  int** P_mark_array;
  int** A_mark_array;
  int* A_marker;
  int* temp;
  int n_coarse;
  int n_coarse_RT;
  int value;
  int square = 1;
  int num_cols_offd_Pext = 0;
  int ic;
  int i;
  int j;
  int k;
  int i1;
  int i2;
  int i3;
  int ii;
  int ns;
  int ne;
  int size;
  int rest;
  int cnt;
  int cnt_offd;
  int cnt_diag;
  int jj1;
  int jj2;
  int jj3;
  int jcol;
  int* jj_count;
  int* jj_cnt_diag;
  int* jj_cnt_offd;
  int jj_counter;
  int jj_count_diag;
  int jj_count_offd;
  int jj_row_begining;
  int jj_row_begin_diag;
  int jj_row_begin_offd;
  int start_indexing = 0;
  int num_nz_cols_A;
  int num_procs;
  int num_threads;
  double r_entry;
  double r_a_product;
  double r_a_p_product;
  double zero = 0.0;
  int tmp_ii;
  int tmp_ii_1;
  int tmp_ii_2;
  int tmp_ii_10;
  int tmp_ii_11;
  MPI_Comm_size(comm, &(num_procs));
  num_threads = 1;
  if (comm_pkg_RT) {
    num_recvs_RT = (comm_pkg_RT)->num_recvs;
    num_sends_RT = (comm_pkg_RT)->num_sends;
    send_map_starts_RT = (comm_pkg_RT)->send_map_starts;
    send_map_elmts_RT = (comm_pkg_RT)->send_map_elmts;
  }
  hypre_CSRMatrixTranspose(RT_diag, &(R_diag), 1);
  if (num_cols_offd_RT) {
    hypre_CSRMatrixTranspose(RT_offd, &(R_offd), 1);
    R_offd_data = (R_offd)->data;
    R_offd_i = (R_offd)->i;
    R_offd_j = (R_offd)->j;
  }
  R_diag_data = (R_diag)->data;
  R_diag_i = (R_diag)->i;
  R_diag_j = (R_diag)->j;
  n_coarse = (P)->global_num_cols;
  num_nz_cols_A = num_cols_diag_A + num_cols_offd_A;
  n_coarse_RT = (RT)->global_num_cols;
  if (n_coarse != n_coarse_RT)
    square = 0;
  if (num_procs > 1) {
    Ps_ext = hypre_ParCSRMatrixExtractBigExt(P, A, 1);
    Ps_ext_data = (Ps_ext)->data;
    Ps_ext_i = (Ps_ext)->i;
    Ps_ext_j = (Ps_ext)->j;
  }
  P_ext_diag_i = (int*)(hypre_CAlloc((unsigned)(num_cols_offd_A + 1), (unsigned)(sizeof(int))));
  P_ext_offd_i = (int*)(hypre_CAlloc((unsigned)(num_cols_offd_A + 1), (unsigned)(sizeof(int))));
  P_ext_diag_size = 0;
  P_ext_offd_size = 0;
  last_col_diag_P = (first_col_diag_P + (int)num_cols_diag_P) - 1;
  for (i = 0; i < num_cols_offd_A; i++) {
    for (j = Ps_ext_i[i]; j < (Ps_ext_i[i + 1]); j++)
      if (((Ps_ext_j[j]) < first_col_diag_P) || ((Ps_ext_j[j]) > last_col_diag_P))
        P_ext_offd_size++;
      else
        P_ext_diag_size++;
    P_ext_diag_i[i + 1] = P_ext_diag_size;
    P_ext_offd_i[i + 1] = P_ext_offd_size;
  }
  if (P_ext_diag_size) {
    P_ext_diag_j = (int*)(hypre_CAlloc((unsigned)P_ext_diag_size, (unsigned)(sizeof(int))));
    P_ext_diag_data = (double*)(hypre_CAlloc((unsigned)P_ext_diag_size, (unsigned)(sizeof(double))));
  }
  if (P_ext_offd_size) {
    P_ext_offd_j = (int*)(hypre_CAlloc((unsigned)P_ext_offd_size, (unsigned)(sizeof(int))));
    P_ext_offd_data = (double*)(hypre_CAlloc((unsigned)P_ext_offd_size, (unsigned)(sizeof(double))));
  }
  if (P_ext_offd_size || num_cols_offd_P)
    temp = (int*)(hypre_CAlloc((unsigned)(P_ext_offd_size + num_cols_offd_P), (unsigned)(sizeof(int))));
  cnt_offd = 0;
  cnt_diag = 0;
  cnt = 0;
  for (i = 0; i < num_cols_offd_A; i++) {
    for (j = Ps_ext_i[i]; j < (Ps_ext_i[i + 1]); j++) {
      value = Ps_ext_j[j];
      if ((value < first_col_diag_P) || (value > last_col_diag_P)) {
        Ps_ext_j[cnt_offd] = value;
        temp[cnt_offd] = value;
        P_ext_offd_data[cnt_offd++] = Ps_ext_data[j];
      }
      else {
        P_ext_diag_j[cnt_diag] = (int)(value - first_col_diag_P);
        P_ext_diag_data[cnt_diag++] = Ps_ext_data[j];
      }
    }
  }
  if (P_ext_offd_size || num_cols_offd_P) {
    cnt = P_ext_offd_size;
    for (i = 0; i < num_cols_offd_P; i++)
      temp[cnt++] = col_map_offd_P[i];
  }
  if (cnt) {
    hypre_BigQsort0(temp, 0, cnt - 1);
    num_cols_offd_Pext = 1;
    value = temp[0];
    for (i = 1; i < cnt; i++) {
      if ((temp[i]) > value) {
        value = temp[i];
        temp[num_cols_offd_Pext++] = value;
      }
    }
  }
  if (num_cols_offd_Pext)
    col_map_offd_Pext = (int*)(hypre_CAlloc((unsigned)num_cols_offd_Pext, (unsigned)(sizeof(int))));
  for (i = 0; i < num_cols_offd_Pext; i++)
    col_map_offd_Pext[i] = temp[i];
  for (i = 0; i < P_ext_offd_size; i++)
    P_ext_offd_j[i] = hypre_BigBinarySearch(col_map_offd_Pext, Ps_ext_j[i], num_cols_offd_Pext);
  if (P_ext_offd_size || num_cols_offd_P)
    hypre_Free((char*)temp), temp = (void*)0;
  if (num_procs > 1) {
    hypre_BigCSRMatrixDestroy(Ps_ext);
    Ps_ext = (void*)0;
  }
  if (num_cols_offd_P) {
    map_P_to_Pext = (int*)(hypre_CAlloc((unsigned)num_cols_offd_P, (unsigned)(sizeof(int))));
    cnt = 0;
    for (i = 0; i < num_cols_offd_Pext; i++)
      if ((col_map_offd_Pext[i]) == (col_map_offd_P[cnt])) {
        map_P_to_Pext[cnt++] = i;
        if (cnt == num_cols_offd_P)
          break;
      }
  }
  P_mark_array = (int**)(hypre_CAlloc((unsigned)num_threads, (unsigned)(sizeof(int*))));
  A_mark_array = (int**)(hypre_CAlloc((unsigned)num_threads, (unsigned)(sizeof(int*))));
  if (num_cols_offd_RT) {
    jj_count = (int*)(hypre_CAlloc((unsigned)num_threads, (unsigned)(sizeof(int))));
    for (ii = 0; ii < num_threads; ii++) {
      size = num_cols_offd_RT / num_threads;
      rest = num_cols_offd_RT - (size * num_threads);
      if (ii < rest) {
        ns = (ii * size) + ii;
        ne = (((ii + 1) * size) + ii) + 1;
      }
      else {
        ns = (ii * size) + rest;
        ne = ((ii + 1) * size) + rest;
      }
      if (num_cols_offd_Pext || num_cols_diag_P) {
        P_mark_array[ii] = (int*)(hypre_CAlloc((unsigned)(num_cols_diag_P + num_cols_offd_Pext), (unsigned)(sizeof(int))));
        P_marker = P_mark_array[ii];
      }
      A_mark_array[ii] = (int*)(hypre_CAlloc((unsigned)num_nz_cols_A, (unsigned)(sizeof(int))));
      A_marker = A_mark_array[ii];
      jj_counter = start_indexing;
      for (ic = 0; ic < (num_cols_diag_P + num_cols_offd_Pext); ic++) {
        P_marker[ic] = -1;
      }
      for (i = 0; i < num_nz_cols_A; i++) {
        A_marker[i] = -1;
      }
      for (ic = ns; ic < ne; ic++) {
        jj_row_begining = jj_counter;
        for (jj1 = R_offd_i[ic]; jj1 < (R_offd_i[ic + 1]); jj1++) {
          i1 = R_offd_j[jj1];
          for (jj2 = A_offd_i[i1]; jj2 < (A_offd_i[i1 + 1]); jj2++) {
            i2 = A_offd_j[jj2];
            if ((A_marker[i2]) != ic) {
              A_marker[i2] = ic;
              for (jj3 = P_ext_diag_i[i2]; jj3 < (P_ext_diag_i[i2 + 1]); jj3++) {
                i3 = P_ext_diag_j[jj3];
                if ((P_marker[i3]) < jj_row_begining) {
                  P_marker[i3] = jj_counter;
                  jj_counter++;
                }
              }
              for (jj3 = P_ext_offd_i[i2]; jj3 < (P_ext_offd_i[i2 + 1]); jj3++) {
                i3 = (P_ext_offd_j[jj3]) + num_cols_diag_P;
                if ((P_marker[i3]) < jj_row_begining) {
                  P_marker[i3] = jj_counter;
                  jj_counter++;
                }
              }
            }
          }
          for (jj2 = A_diag_i[i1]; jj2 < (A_diag_i[i1 + 1]); jj2++) {
            i2 = A_diag_j[jj2];
            if ((A_marker[i2 + num_cols_offd_A]) != ic) {
              A_marker[i2 + num_cols_offd_A] = ic;
              for (jj3 = P_diag_i[i2]; jj3 < (P_diag_i[i2 + 1]); jj3++) {
                i3 = P_diag_j[jj3];
                if ((P_marker[i3]) < jj_row_begining) {
                  P_marker[i3] = jj_counter;
                  jj_counter++;
                }
              }
              for (jj3 = P_offd_i[i2]; jj3 < (P_offd_i[i2 + 1]); jj3++) {
                i3 = (map_P_to_Pext[P_offd_j[jj3]]) + num_cols_diag_P;
                if ((P_marker[i3]) < jj_row_begining) {
                  P_marker[i3] = jj_counter;
                  jj_counter++;
                }
              }
            }
          }
        }
      }
      jj_count[ii] = jj_counter;
    }
    for (i = 0; i < (num_threads - 1); i++)
      jj_count[i + 1] += jj_count[i];
    RAP_size = jj_count[num_threads - 1];
    RAP_int_i = (int*)(hypre_CAlloc((unsigned)(num_cols_offd_RT + 1), (unsigned)(sizeof(int))));
    RAP_int_data = (double*)(hypre_CAlloc((unsigned)RAP_size, (unsigned)(sizeof(double))));
    RAP_int_j = (int*)(hypre_CAlloc((unsigned)RAP_size, (unsigned)(sizeof(int))));
    RAP_int_i[num_cols_offd_RT] = RAP_size;
    for (ii = 0; ii < num_threads; ii++) {
      size = num_cols_offd_RT / num_threads;
      rest = num_cols_offd_RT - (size * num_threads);
      if (ii < rest) {
        ns = (ii * size) + ii;
        ne = (((ii + 1) * size) + ii) + 1;
      }
      else {
        ns = (ii * size) + rest;
        ne = ((ii + 1) * size) + rest;
      }
      if (num_cols_offd_Pext || num_cols_diag_P)
        P_marker = P_mark_array[ii];
      A_marker = A_mark_array[ii];
      jj_counter = start_indexing;
      if (ii > 0)
        jj_counter = jj_count[ii - 1];
      for (ic = 0; ic < (num_cols_diag_P + num_cols_offd_Pext); ic++) {
        P_marker[ic] = -1;
      }
      for (i = 0; i < num_nz_cols_A; i++) {
        A_marker[i] = -1;
      }
      for (ic = ns; ic < ne; ic++) {
        jj_row_begining = jj_counter;
        RAP_int_i[ic] = jj_counter;
        for (jj1 = R_offd_i[ic]; jj1 < (R_offd_i[ic + 1]); jj1++) {
          i1 = R_offd_j[jj1];
          r_entry = R_offd_data[jj1];
          for (jj2 = A_offd_i[i1]; jj2 < (A_offd_i[i1 + 1]); jj2++) {
            i2 = A_offd_j[jj2];
            r_a_product = r_entry * (A_offd_data[jj2]);
            if ((A_marker[i2]) != ic) {
              A_marker[i2] = ic;
              for (jj3 = P_ext_diag_i[i2]; jj3 < (P_ext_diag_i[i2 + 1]); jj3++) {
                i3 = P_ext_diag_j[jj3];
                r_a_p_product = r_a_product * (P_ext_diag_data[jj3]);
                if ((P_marker[i3]) < jj_row_begining) {
                  P_marker[i3] = jj_counter;
                  RAP_int_data[jj_counter] = r_a_p_product;
                  RAP_int_j[jj_counter] = (int)i3 + first_col_diag_P;
                  jj_counter++;
                }
                else {
                  RAP_int_data[P_marker[i3]] += r_a_p_product;
                }
              }
              for (jj3 = P_ext_offd_i[i2]; jj3 < (P_ext_offd_i[i2 + 1]); jj3++) {
                i3 = (P_ext_offd_j[jj3]) + num_cols_diag_P;
                r_a_p_product = r_a_product * (P_ext_offd_data[jj3]);
                if ((P_marker[i3]) < jj_row_begining) {
                  P_marker[i3] = jj_counter;
                  RAP_int_data[jj_counter] = r_a_p_product;
                  RAP_int_j[jj_counter] = col_map_offd_Pext[i3 - num_cols_diag_P];
                  jj_counter++;
                }
                else {
                  RAP_int_data[P_marker[i3]] += r_a_p_product;
                }
              }
            }
            else {
              for (jj3 = P_ext_diag_i[i2]; jj3 < (P_ext_diag_i[i2 + 1]); jj3++) {
                i3 = P_ext_diag_j[jj3];
                r_a_p_product = r_a_product * (P_ext_diag_data[jj3]);
                RAP_int_data[P_marker[i3]] += r_a_p_product;
              }
              for (jj3 = P_ext_offd_i[i2]; jj3 < (P_ext_offd_i[i2 + 1]); jj3++) {
                i3 = (P_ext_offd_j[jj3]) + num_cols_diag_P;
                r_a_p_product = r_a_product * (P_ext_offd_data[jj3]);
                RAP_int_data[P_marker[i3]] += r_a_p_product;
              }
            }
          }
          for (jj2 = A_diag_i[i1]; jj2 < (A_diag_i[i1 + 1]); jj2++) {
            i2 = A_diag_j[jj2];
            r_a_product = r_entry * (A_diag_data[jj2]);
            if ((A_marker[i2 + num_cols_offd_A]) != ic) {
              A_marker[i2 + num_cols_offd_A] = ic;
              for (jj3 = P_diag_i[i2]; jj3 < (P_diag_i[i2 + 1]); jj3++) {
                i3 = P_diag_j[jj3];
                r_a_p_product = r_a_product * (P_diag_data[jj3]);
                if ((P_marker[i3]) < jj_row_begining) {
                  P_marker[i3] = jj_counter;
                  RAP_int_data[jj_counter] = r_a_p_product;
                  RAP_int_j[jj_counter] = (int)i3 + first_col_diag_P;
                  jj_counter++;
                }
                else {
                  RAP_int_data[P_marker[i3]] += r_a_p_product;
                }
              }
              for (jj3 = P_offd_i[i2]; jj3 < (P_offd_i[i2 + 1]); jj3++) {
                i3 = (map_P_to_Pext[P_offd_j[jj3]]) + num_cols_diag_P;
                r_a_p_product = r_a_product * (P_offd_data[jj3]);
                if ((P_marker[i3]) < jj_row_begining) {
                  P_marker[i3] = jj_counter;
                  RAP_int_data[jj_counter] = r_a_p_product;
                  RAP_int_j[jj_counter] = col_map_offd_Pext[i3 - num_cols_diag_P];
                  jj_counter++;
                }
                else {
                  RAP_int_data[P_marker[i3]] += r_a_p_product;
                }
              }
            }
            else {
              for (jj3 = P_diag_i[i2]; jj3 < (P_diag_i[i2 + 1]); jj3++) {
                i3 = P_diag_j[jj3];
                r_a_p_product = r_a_product * (P_diag_data[jj3]);
                RAP_int_data[P_marker[i3]] += r_a_p_product;
              }
              for (jj3 = P_offd_i[i2]; jj3 < (P_offd_i[i2 + 1]); jj3++) {
                i3 = (map_P_to_Pext[P_offd_j[jj3]]) + num_cols_diag_P;
                r_a_p_product = r_a_product * (P_offd_data[jj3]);
                RAP_int_data[P_marker[i3]] += r_a_p_product;
              }
            }
          }
        }
      }
      if (num_cols_offd_Pext || num_cols_diag_P)
        hypre_Free((char*)(P_mark_array[ii])), P_mark_array[ii] = (void*)0;
      hypre_Free((char*)(A_mark_array[ii])), A_mark_array[ii] = (void*)0;
    }
    RAP_int = hypre_BigCSRMatrixCreate(num_cols_offd_RT, num_rows_offd_RT, RAP_size);
    (RAP_int)->i = RAP_int_i;
    (RAP_int)->j = RAP_int_j;
    (RAP_int)->data = RAP_int_data;
    hypre_Free((char*)jj_count), jj_count = (void*)0;
  }
  RAP_ext_size = 0;
  if (num_sends_RT || num_recvs_RT) {
    RAP_ext = hypre_ExchangeRAPData(RAP_int, comm_pkg_RT);
    RAP_ext_i = (RAP_ext)->i;
    RAP_ext_j = (RAP_ext)->j;
    RAP_ext_data = (RAP_ext)->data;
    RAP_ext_size = RAP_ext_i[(RAP_ext)->num_rows];
  }
  if (num_cols_offd_RT) {
    hypre_BigCSRMatrixDestroy(RAP_int);
    RAP_int = (void*)0;
  }
  RAP_diag_i = (int*)(hypre_CAlloc((unsigned)(num_cols_diag_RT + 1), (unsigned)(sizeof(int))));
  RAP_offd_i = (int*)(hypre_CAlloc((unsigned)(num_cols_diag_RT + 1), (unsigned)(sizeof(int))));
  first_col_diag_RAP = first_col_diag_P;
  last_col_diag_RAP = (first_col_diag_P + (int)num_cols_diag_P) - 1;
  if (RAP_ext_size || num_cols_offd_Pext) {
    temp = (int*)(hypre_CAlloc((unsigned)(RAP_ext_size + num_cols_offd_Pext), (unsigned)(sizeof(int))));
    cnt = 0;
    for (i = 0; i < RAP_ext_size; i++)
      if (((RAP_ext_j[i]) < first_col_diag_RAP) || ((RAP_ext_j[i]) > last_col_diag_RAP))
        temp[cnt++] = RAP_ext_j[i];
    for (i = 0; i < num_cols_offd_Pext; i++)
      temp[cnt++] = col_map_offd_Pext[i];
    if (cnt) {
      hypre_BigQsort0(temp, 0, cnt - 1);
      value = temp[0];
      num_cols_offd_RAP = 1;
      for (i = 1; i < cnt; i++) {
        if ((temp[i]) > value) {
          value = temp[i];
          temp[num_cols_offd_RAP++] = value;
        }
      }
    }
    if (num_cols_offd_RAP)
      col_map_offd_RAP = (int*)(hypre_CAlloc((unsigned)num_cols_offd_RAP, (unsigned)(sizeof(int))));
    for (i = 0; i < num_cols_offd_RAP; i++)
      col_map_offd_RAP[i] = temp[i];
    hypre_Free((char*)temp), temp = (void*)0;
  }
  if (num_cols_offd_P) {
    map_P_to_RAP = (int*)(hypre_CAlloc((unsigned)num_cols_offd_P, (unsigned)(sizeof(int))));
    cnt = 0;
    for (i = 0; i < num_cols_offd_RAP; i++)
      if ((col_map_offd_RAP[i]) == (col_map_offd_P[cnt])) {
        map_P_to_RAP[cnt++] = i;
        if (cnt == num_cols_offd_P)
          break;
      }
  }
  if (num_cols_offd_Pext) {
    map_Pext_to_RAP = (int*)(hypre_CAlloc((unsigned)num_cols_offd_Pext, (unsigned)(sizeof(int))));
    cnt = 0;
    for (i = 0; i < num_cols_offd_RAP; i++)
      if ((col_map_offd_RAP[i]) == (col_map_offd_Pext[cnt])) {
        map_Pext_to_RAP[cnt++] = i;
        if (cnt == num_cols_offd_Pext)
          break;
      }
  }
  int_RAP_ext_j = (int*)(hypre_CAlloc((unsigned)RAP_ext_size, (unsigned)(sizeof(int))));
  for (i = 0; i < RAP_ext_size; i++)
    if (((RAP_ext_j[i]) < first_col_diag_RAP) || ((RAP_ext_j[i]) > last_col_diag_RAP))
      int_RAP_ext_j[i] = num_cols_diag_P + hypre_BigBinarySearch(col_map_offd_RAP, RAP_ext_j[i], num_cols_offd_RAP);
    else
      int_RAP_ext_j[i] = (int)((RAP_ext_j[i]) - first_col_diag_RAP);
  jj_cnt_diag = (int*)(hypre_CAlloc((unsigned)num_threads, (unsigned)(sizeof(int))));
  jj_cnt_offd = (int*)(hypre_CAlloc((unsigned)num_threads, (unsigned)(sizeof(int))));
  size = num_cols_diag_RT / num_threads;
  rest = num_cols_diag_RT - (size * num_threads);
  for (ii = 0; ii < num_threads; ii++) {
    if (ii < rest) {
      ns = (ii * size) + ii;
      ne = (((ii + 1) * size) + ii) + 1;
    }
    else {
      ns = (ii * size) + rest;
      ne = ((ii + 1) * size) + rest;
    }
    P_mark_array[ii] = (int*)(hypre_CAlloc((unsigned)(num_cols_diag_P + num_cols_offd_RAP), (unsigned)(sizeof(int))));
    A_mark_array[ii] = (int*)(hypre_CAlloc((unsigned)num_nz_cols_A, (unsigned)(sizeof(int))));
    P_marker = P_mark_array[ii];
    A_marker = A_mark_array[ii];
    jj_count_diag = start_indexing;
    jj_count_offd = start_indexing;
    for (ic = 0; ic < (num_cols_diag_P + num_cols_offd_RAP); ic++) {
      P_marker[ic] = -1;
    }
    for (i = 0; i < num_nz_cols_A; i++) {
      A_marker[i] = -1;
    }
    for (ic = ns; ic < ne; ic++) {
      jj_row_begin_diag = jj_count_diag;
      jj_row_begin_offd = jj_count_offd;
      if (square)
        P_marker[ic] = jj_count_diag++;
      for (i = 0; i < num_sends_RT; i++) {
        tmp_ii_10 = send_map_starts_RT[i + 1];
        for (j = send_map_starts_RT[i]; j < tmp_ii_10; j++)
          if ((send_map_elmts_RT[j]) == ic) {
            for (k = RAP_ext_i[j]; k < (RAP_ext_i[j + 1]); k++) {
              jcol = int_RAP_ext_j[k];
              if (jcol < num_cols_diag_P) {
                if ((P_marker[jcol]) < jj_row_begin_diag) {
                  P_marker[jcol] = jj_count_diag;
                  jj_count_diag++;
                }
              }
              else {
                if ((P_marker[jcol]) < jj_row_begin_offd) {
                  P_marker[jcol] = jj_count_offd;
                  jj_count_offd++;
                }
              }
            }
            break;
          }
      }
      for (jj1 = R_diag_i[ic]; jj1 < (R_diag_i[ic + 1]); jj1++) {
        i1 = R_diag_j[jj1];
        if (num_cols_offd_A) {
          for (jj2 = A_offd_i[i1]; jj2 < (A_offd_i[i1 + 1]); jj2++) {
            i2 = A_offd_j[jj2];
            if ((A_marker[i2]) != ic) {
              A_marker[i2] = ic;
              for (jj3 = P_ext_diag_i[i2]; jj3 < (P_ext_diag_i[i2 + 1]); jj3++) {
                i3 = P_ext_diag_j[jj3];
                if ((P_marker[i3]) < jj_row_begin_diag) {
                  P_marker[i3] = jj_count_diag;
                  jj_count_diag++;
                }
              }
              for (jj3 = P_ext_offd_i[i2]; jj3 < (P_ext_offd_i[i2 + 1]); jj3++) {
                i3 = (map_Pext_to_RAP[P_ext_offd_j[jj3]]) + num_cols_diag_P;
                if ((P_marker[i3]) < jj_row_begin_offd) {
                  P_marker[i3] = jj_count_offd;
                  jj_count_offd++;
                }
              }
            }
          }
        }
        tmp_ii = A_diag_i[i1 + 1];
        for (jj2 = A_diag_i[i1]; jj2 < tmp_ii; jj2++) {
          i2 = A_diag_j[jj2];
          if ((A_marker[i2 + num_cols_offd_A]) != ic) {
            A_marker[i2 + num_cols_offd_A] = ic;
            tmp_ii_1 = P_diag_i[i2 + 1];
            for (jj3 = P_diag_i[i2]; jj3 < tmp_ii_1; jj3++) {
              i3 = P_diag_j[jj3];
              if ((P_marker[i3]) < jj_row_begin_diag) {
                P_marker[i3] = jj_count_diag;
                jj_count_diag++;
              }
            }
            if (num_cols_offd_P) {
              for (jj3 = P_offd_i[i2]; jj3 < (P_offd_i[i2 + 1]); jj3++) {
                i3 = (map_P_to_RAP[P_offd_j[jj3]]) + num_cols_diag_P;
                if ((P_marker[i3]) < jj_row_begin_offd) {
                  P_marker[i3] = jj_count_offd;
                  jj_count_offd++;
                }
              }
            }
          }
        }
      }
    }
    jj_cnt_diag[ii] = jj_count_diag;
    jj_cnt_offd[ii] = jj_count_offd;
  }
  for (i = 0; i < (num_threads - 1); i++) {
    jj_cnt_diag[i + 1] += jj_cnt_diag[i];
    jj_cnt_offd[i + 1] += jj_cnt_offd[i];
  }
  jj_count_diag = jj_cnt_diag[num_threads - 1];
  jj_count_offd = jj_cnt_offd[num_threads - 1];
  RAP_diag_i[num_cols_diag_RT] = jj_count_diag;
  RAP_offd_i[num_cols_diag_RT] = jj_count_offd;
  RAP_diag_size = jj_count_diag;
  if (RAP_diag_size) {
    RAP_diag_data = (double*)(hypre_CAlloc((unsigned)RAP_diag_size, (unsigned)(sizeof(double))));
    RAP_diag_j = (int*)(hypre_CAlloc((unsigned)RAP_diag_size, (unsigned)(sizeof(int))));
  }
  RAP_offd_size = jj_count_offd;
  if (RAP_offd_size) {
    RAP_offd_data = (double*)(hypre_CAlloc((unsigned)RAP_offd_size, (unsigned)(sizeof(double))));
    RAP_offd_j = (int*)(hypre_CAlloc((unsigned)RAP_offd_size, (unsigned)(sizeof(int))));
  }
  if ((RAP_offd_size == 0) && (num_cols_offd_RAP != 0)) {
    num_cols_offd_RAP = 0;
    hypre_Free((char*)col_map_offd_RAP), col_map_offd_RAP = (void*)0;
  }
  for (ii = 0; ii < num_threads; ii++) {
    size = num_cols_diag_RT / num_threads;
    rest = num_cols_diag_RT - (size * num_threads);
    if (ii < rest) {
      ns = (ii * size) + ii;
      ne = (((ii + 1) * size) + ii) + 1;
    }
    else {
      ns = (ii * size) + rest;
      ne = ((ii + 1) * size) + rest;
    }
    P_marker = P_mark_array[ii];
    A_marker = A_mark_array[ii];
    for (ic = 0; ic < (num_cols_diag_P + num_cols_offd_RAP); ic++) {
      P_marker[ic] = -1;
    }
    for (i = 0; i < num_nz_cols_A; i++) {
      A_marker[i] = -1;
    }
    jj_count_diag = start_indexing;
    jj_count_offd = start_indexing;
    if (ii > 0) {
      jj_count_diag = jj_cnt_diag[ii - 1];
      jj_count_offd = jj_cnt_offd[ii - 1];
    }
    for (ic = ns; ic < ne; ic++) {
      jj_row_begin_diag = jj_count_diag;
      jj_row_begin_offd = jj_count_offd;
      RAP_diag_i[ic] = jj_row_begin_diag;
      RAP_offd_i[ic] = jj_row_begin_offd;
      if (square) {
        P_marker[ic] = jj_count_diag;
        RAP_diag_data[jj_count_diag] = zero;
        RAP_diag_j[jj_count_diag] = ic;
        jj_count_diag++;
      }
      for (i = 0; i < num_sends_RT; i++) {
        tmp_ii_11 = send_map_starts_RT[i + 1];
        for (j = send_map_starts_RT[i]; j < tmp_ii_11; j++)
          if ((send_map_elmts_RT[j]) == ic) {
            for (k = RAP_ext_i[j]; k < (RAP_ext_i[j + 1]); k++) {
              jcol = int_RAP_ext_j[k];
              if (jcol < num_cols_diag_P) {
                if ((P_marker[jcol]) < jj_row_begin_diag) {
                  P_marker[jcol] = jj_count_diag;
                  RAP_diag_data[jj_count_diag] = RAP_ext_data[k];
                  RAP_diag_j[jj_count_diag] = jcol;
                  jj_count_diag++;
                }
                else
                  RAP_diag_data[P_marker[jcol]] += RAP_ext_data[k];
              }
              else {
                if ((P_marker[jcol]) < jj_row_begin_offd) {
                  P_marker[jcol] = jj_count_offd;
                  RAP_offd_data[jj_count_offd] = RAP_ext_data[k];
                  RAP_offd_j[jj_count_offd] = jcol - num_cols_diag_P;
                  jj_count_offd++;
                }
                else
                  RAP_offd_data[P_marker[jcol]] += RAP_ext_data[k];
              }
            }
            break;
          }
      }
      for (jj1 = R_diag_i[ic]; jj1 < (R_diag_i[ic + 1]); jj1++) {
        i1 = R_diag_j[jj1];
        r_entry = R_diag_data[jj1];
        if (num_cols_offd_A) {
          for (jj2 = A_offd_i[i1]; jj2 < (A_offd_i[i1 + 1]); jj2++) {
            i2 = A_offd_j[jj2];
            r_a_product = r_entry * (A_offd_data[jj2]);
            if ((A_marker[i2]) != ic) {
              A_marker[i2] = ic;
              for (jj3 = P_ext_diag_i[i2]; jj3 < (P_ext_diag_i[i2 + 1]); jj3++) {
                i3 = P_ext_diag_j[jj3];
                r_a_p_product = r_a_product * (P_ext_diag_data[jj3]);
                if ((P_marker[i3]) < jj_row_begin_diag) {
                  P_marker[i3] = jj_count_diag;
                  RAP_diag_data[jj_count_diag] = r_a_p_product;
                  RAP_diag_j[jj_count_diag] = i3;
                  jj_count_diag++;
                }
                else
                  RAP_diag_data[P_marker[i3]] += r_a_p_product;
              }
              for (jj3 = P_ext_offd_i[i2]; jj3 < (P_ext_offd_i[i2 + 1]); jj3++) {
                i3 = (map_Pext_to_RAP[P_ext_offd_j[jj3]]) + num_cols_diag_P;
                r_a_p_product = r_a_product * (P_ext_offd_data[jj3]);
                if ((P_marker[i3]) < jj_row_begin_offd) {
                  P_marker[i3] = jj_count_offd;
                  RAP_offd_data[jj_count_offd] = r_a_p_product;
                  RAP_offd_j[jj_count_offd] = i3 - num_cols_diag_P;
                  jj_count_offd++;
                }
                else
                  RAP_offd_data[P_marker[i3]] += r_a_p_product;
              }
            }
            else {
              for (jj3 = P_ext_diag_i[i2]; jj3 < (P_ext_diag_i[i2 + 1]); jj3++) {
                i3 = P_ext_diag_j[jj3];
                r_a_p_product = r_a_product * (P_ext_diag_data[jj3]);
                RAP_diag_data[P_marker[i3]] += r_a_p_product;
              }
              for (jj3 = P_ext_offd_i[i2]; jj3 < (P_ext_offd_i[i2 + 1]); jj3++) {
                i3 = (map_Pext_to_RAP[P_ext_offd_j[jj3]]) + num_cols_diag_P;
                r_a_p_product = r_a_product * (P_ext_offd_data[jj3]);
                RAP_offd_data[P_marker[i3]] += r_a_p_product;
              }
            }
          }
        }
        tmp_ii = A_diag_i[i1 + 1];
        for (jj2 = A_diag_i[i1]; jj2 < tmp_ii; jj2++) {
          i2 = A_diag_j[jj2];
          r_a_product = r_entry * (A_diag_data[jj2]);
          if ((A_marker[i2 + num_cols_offd_A]) != ic) {
            A_marker[i2 + num_cols_offd_A] = ic;
            tmp_ii_1 = P_diag_i[i2 + 1];
            for (jj3 = P_diag_i[i2]; jj3 < tmp_ii_1; jj3++) {
              i3 = P_diag_j[jj3];
              r_a_p_product = r_a_product * (P_diag_data[jj3]);
              if ((P_marker[i3]) < jj_row_begin_diag) {
                P_marker[i3] = jj_count_diag;
                RAP_diag_data[jj_count_diag] = r_a_p_product;
                RAP_diag_j[jj_count_diag] = P_diag_j[jj3];
                jj_count_diag++;
              }
              else {
                RAP_diag_data[P_marker[i3]] += r_a_p_product;
              }
            }
            if (num_cols_offd_P) {
              for (jj3 = P_offd_i[i2]; jj3 < (P_offd_i[i2 + 1]); jj3++) {
                i3 = (map_P_to_RAP[P_offd_j[jj3]]) + num_cols_diag_P;
                r_a_p_product = r_a_product * (P_offd_data[jj3]);
                if ((P_marker[i3]) < jj_row_begin_offd) {
                  P_marker[i3] = jj_count_offd;
                  RAP_offd_data[jj_count_offd] = r_a_p_product;
                  RAP_offd_j[jj_count_offd] = i3 - num_cols_diag_P;
                  jj_count_offd++;
                }
                else {
                  RAP_offd_data[P_marker[i3]] += r_a_p_product;
                }
              }
            }
          }
          else {
            tmp_ii_2 = P_diag_i[i2 + 1];
            for (jj3 = P_diag_i[i2]; jj3 < tmp_ii_2; jj3++) {
              i3 = P_diag_j[jj3];
              r_a_p_product = r_a_product * (P_diag_data[jj3]);
              RAP_diag_data[P_marker[i3]] += r_a_p_product;
            }
            if (num_cols_offd_P) {
              for (jj3 = P_offd_i[i2]; jj3 < (P_offd_i[i2 + 1]); jj3++) {
                i3 = (map_P_to_RAP[P_offd_j[jj3]]) + num_cols_diag_P;
                r_a_p_product = r_a_product * (P_offd_data[jj3]);
                RAP_offd_data[P_marker[i3]] += r_a_p_product;
              }
            }
          }
        }
      }
    }
    hypre_Free((char*)(P_mark_array[ii])), P_mark_array[ii] = (void*)0;
    hypre_Free((char*)(A_mark_array[ii])), A_mark_array[ii] = (void*)0;
  }
  P_marker = (int*)(hypre_CAlloc((unsigned)num_cols_offd_RAP, (unsigned)(sizeof(int))));
  for (i = 0; i < num_cols_offd_RAP; i++)
    P_marker[i] = -1;
  jj_count_offd = 0;
  for (i = 0; i < RAP_offd_size; i++) {
    i3 = RAP_offd_j[i];
    if (P_marker[i3]) {
      P_marker[i3] = 0;
      jj_count_offd++;
    }
  }
  if (jj_count_offd < num_cols_offd_RAP) {
    new_col_map_offd_RAP = (int*)(hypre_CAlloc((unsigned)jj_count_offd, (unsigned)(sizeof(int))));
    jj_counter = 0;
    for (i = 0; i < num_cols_offd_RAP; i++)
      if (!(P_marker[i])) {
        P_marker[i] = jj_counter;
        new_col_map_offd_RAP[jj_counter++] = col_map_offd_RAP[i];
      }
    for (i = 0; i < RAP_offd_size; i++) {
      i3 = RAP_offd_j[i];
      RAP_offd_j[i] = P_marker[i3];
    }
    num_cols_offd_RAP = jj_count_offd;
    hypre_Free((char*)col_map_offd_RAP), col_map_offd_RAP = (void*)0;
    col_map_offd_RAP = new_col_map_offd_RAP;
  }
  hypre_Free((char*)P_marker), P_marker = (void*)0;
  RAP = hypre_ParCSRMatrixCreate(comm, n_coarse_RT, n_coarse, RT_partitioning, coarse_partitioning, num_cols_offd_RAP, RAP_diag_size, RAP_offd_size);
  hypre_ParCSRMatrixSetColStartsOwner(P, 0);
  hypre_ParCSRMatrixSetColStartsOwner(RT, 0);
  RAP_diag = (RAP)->diag;
  (RAP_diag)->i = RAP_diag_i;
  if (RAP_diag_size) {
    (RAP_diag)->data = RAP_diag_data;
    (RAP_diag)->j = RAP_diag_j;
  }
  RAP_offd = (RAP)->offd;
  (RAP_offd)->i = RAP_offd_i;
  if (num_cols_offd_RAP) {
    (RAP_offd)->data = RAP_offd_data;
    (RAP_offd)->j = RAP_offd_j;
    (RAP)->col_map_offd = col_map_offd_RAP;
  }
  if (num_procs > 1) {
    hypre_MatvecCommPkgCreate(RAP);
  }
  *RAP_ptr = RAP;
  hypre_CSRMatrixDestroy(R_diag);
  R_diag = (void*)0;
  if (num_cols_offd_RT) {
    hypre_CSRMatrixDestroy(R_offd);
    R_offd = (void*)0;
  }
  if (num_sends_RT || num_recvs_RT) {
    hypre_BigCSRMatrixDestroy(RAP_ext);
    RAP_ext = (void*)0;
  }
  hypre_Free((char*)P_mark_array), P_mark_array = (void*)0;
  hypre_Free((char*)A_mark_array), A_mark_array = (void*)0;
  hypre_Free((char*)P_ext_diag_i), P_ext_diag_i = (void*)0;
  hypre_Free((char*)P_ext_offd_i), P_ext_offd_i = (void*)0;
  hypre_Free((char*)jj_cnt_diag), jj_cnt_diag = (void*)0;
  hypre_Free((char*)jj_cnt_offd), jj_cnt_offd = (void*)0;
  hypre_Free((char*)int_RAP_ext_j), int_RAP_ext_j = (void*)0;
  if (num_cols_offd_P) {
    hypre_Free((char*)map_P_to_Pext), map_P_to_Pext = (void*)0;
    hypre_Free((char*)map_P_to_RAP), map_P_to_RAP = (void*)0;
  }
  if (num_cols_offd_Pext) {
    hypre_Free((char*)col_map_offd_Pext), col_map_offd_Pext = (void*)0;
    hypre_Free((char*)map_Pext_to_RAP), map_Pext_to_RAP = (void*)0;
  }
  if (P_ext_diag_size) {
    hypre_Free((char*)P_ext_diag_data), P_ext_diag_data = (void*)0;
    hypre_Free((char*)P_ext_diag_j), P_ext_diag_j = (void*)0;
  }
  if (P_ext_offd_size) {
    hypre_Free((char*)P_ext_offd_data), P_ext_offd_data = (void*)0;
    hypre_Free((char*)P_ext_offd_j), P_ext_offd_j = (void*)0;
  }
  return 0;
}
//================= par_rap_communication.c ================
int hypre_GetCommPkgRTFromCommPkgA(hypre_ParCSRMatrix* RT, hypre_ParCSRMatrix* A, int* fine_to_coarse, int* tmp_map_offd) {
  MPI_Comm comm = (RT)->comm;
  hypre_ParCSRCommPkg* comm_pkg_A = (A)->comm_pkg;
  hypre_ParCSRCommHandle* comm_handle;
  int num_recvs_A = (comm_pkg_A)->num_recvs;
  int* recv_procs_A = (comm_pkg_A)->recv_procs;
  int* recv_vec_starts_A = (comm_pkg_A)->recv_vec_starts;
  int num_sends_A = (comm_pkg_A)->num_sends;
  int* send_procs_A = (comm_pkg_A)->send_procs;
  int* send_map_starts_A = (comm_pkg_A)->send_map_starts;
  hypre_ParCSRCommPkg* comm_pkg;
  int num_recvs_RT;
  int* recv_procs_RT;
  int* recv_vec_starts_RT;
  int num_sends_RT;
  int* send_procs_RT;
  int* send_map_starts_RT;
  int* send_map_elmts_RT;
  int* col_map_offd_RT = (RT)->col_map_offd;
  int num_cols_offd_RT = ((RT)->offd)->num_cols;
  int num_cols_A_offd = ((A)->offd)->num_cols;
  int n_fine = ((A)->diag)->num_rows;
  int first_col_diag = (RT)->first_col_diag;
  int* fine_to_coarse_offd;
  int* big_buf_data;
  int* send_big_elmts;
  int i;
  int j;
  int vec_len;
  int vec_start;
  int num_procs;
  int my_id;
  int num_threads;
  int ierr = 0;
  int num_requests;
  int offd_col;
  int proc_num;
  int* proc_mark;
  int* change_array;
  int* coarse_counter;
  int coarse_shift;
  int ns;
  int ne;
  int index;
  int size;
  int rest;
  int start;
  int my_first_cpt;
  MPI_Request* requests;
  MPI_Status* status;
  MPI_Comm_size(comm, &(num_procs));
  MPI_Comm_rank(comm, &(my_id));
  num_threads = 1;
  proc_mark = (int*)(hypre_CAlloc((unsigned)num_recvs_A, (unsigned)(sizeof(int))));
  for (i = 0; i < num_recvs_A; i++)
    proc_mark[i] = 0;
  proc_num = 0;
  num_recvs_RT = 0;
  if (num_cols_offd_RT) {
    for (i = 0; i < num_recvs_A; i++) {
      for (j = recv_vec_starts_A[i]; j < (recv_vec_starts_A[i + 1]); j++) {
        offd_col = tmp_map_offd[proc_num];
        if (offd_col == j) {
          proc_mark[i]++;
          proc_num++;
          if (proc_num == num_cols_offd_RT)
            break;
        }
      }
      if (proc_mark[i])
        num_recvs_RT++;
      if (proc_num == num_cols_offd_RT)
        break;
    }
  }
  fine_to_coarse_offd = (int*)(hypre_CAlloc((unsigned)num_cols_A_offd, (unsigned)(sizeof(int))));
  big_buf_data = (int*)(hypre_CAlloc((unsigned)(send_map_starts_A[num_sends_A]), (unsigned)(sizeof(int))));
  coarse_counter = (int*)(hypre_CAlloc((unsigned)num_threads, (unsigned)(sizeof(int))));
  my_first_cpt = (RT)->col_starts[my_id];
  for (j = 0; j < num_threads; j++) {
    coarse_shift = 0;
    if (j > 0)
      coarse_shift = coarse_counter[j - 1];
    size = n_fine / num_threads;
    rest = n_fine - (size * num_threads);
    if (j < rest) {
      ns = (j * size) + j;
      ne = (((j + 1) * size) + j) + 1;
    }
    else {
      ns = (j * size) + rest;
      ne = ((j + 1) * size) + rest;
    }
    for (i = ns; i < ne; i++)
      fine_to_coarse[i] += coarse_shift;
  }
  index = 0;
  for (i = 0; i < num_sends_A; i++) {
    start = (comm_pkg_A)->send_map_starts[i];
    for (j = start; j < ((comm_pkg_A)->send_map_starts[i + 1]); j++)
      big_buf_data[index++] = my_first_cpt + (int)(fine_to_coarse[(comm_pkg_A)->send_map_elmts[j]]);
  }
  comm_handle = hypre_ParCSRCommHandleCreate(21, comm_pkg_A, big_buf_data, fine_to_coarse_offd);
  hypre_ParCSRCommHandleDestroy(comm_handle);
  for (i = 0; i < num_cols_offd_RT; i++)
    col_map_offd_RT[i] = fine_to_coarse_offd[tmp_map_offd[i]];
  hypre_Free((char*)fine_to_coarse_offd), fine_to_coarse_offd = (void*)0;
  hypre_Free((char*)coarse_counter), coarse_counter = (void*)0;
  recv_procs_RT = (int*)(hypre_CAlloc((unsigned)num_recvs_RT, (unsigned)(sizeof(int))));
  recv_vec_starts_RT = (int*)(hypre_CAlloc((unsigned)(num_recvs_RT + 1), (unsigned)(sizeof(int))));
  j = 0;
  recv_vec_starts_RT[0] = 0;
  for (i = 0; i < num_recvs_A; i++)
    if (proc_mark[i]) {
      recv_procs_RT[j] = recv_procs_A[i];
      recv_vec_starts_RT[j + 1] = (recv_vec_starts_RT[j]) + (proc_mark[i]);
      j++;
    }
  num_requests = num_recvs_A + num_sends_A;
  requests = (MPI_Request*)(hypre_CAlloc((unsigned)num_requests, (unsigned)(sizeof(MPI_Request))));
  status = (MPI_Status*)(hypre_CAlloc((unsigned)num_requests, (unsigned)(sizeof(MPI_Status))));
  change_array = (int*)(hypre_CAlloc((unsigned)num_sends_A, (unsigned)(sizeof(int))));
  j = 0;
  for (i = 0; i < num_sends_A; i++)
    MPI_Irecv(&(change_array[i]), 1, MPI_INT, send_procs_A[i], 0, comm, &(requests[j++]));
  for (i = 0; i < num_recvs_A; i++)
    MPI_Isend(&(proc_mark[i]), 1, MPI_INT, recv_procs_A[i], 0, comm, &(requests[j++]));
  MPI_Waitall(num_requests, requests, status);
  hypre_Free((char*)proc_mark), proc_mark = (void*)0;
  num_sends_RT = 0;
  for (i = 0; i < num_sends_A; i++)
    if (change_array[i]) {
      num_sends_RT++;
    }
  send_procs_RT = (int*)(hypre_CAlloc((unsigned)num_sends_RT, (unsigned)(sizeof(int))));
  send_map_starts_RT = (int*)(hypre_CAlloc((unsigned)(num_sends_RT + 1), (unsigned)(sizeof(int))));
  j = 0;
  send_map_starts_RT[0] = 0;
  for (i = 0; i < num_sends_A; i++)
    if (change_array[i]) {
      send_procs_RT[j] = send_procs_A[i];
      send_map_starts_RT[j + 1] = (send_map_starts_RT[j]) + (change_array[i]);
      j++;
    }
  send_map_elmts_RT = (int*)(hypre_CAlloc((unsigned)(send_map_starts_RT[num_sends_RT]), (unsigned)(sizeof(int))));
  send_big_elmts = (int*)(hypre_CAlloc((unsigned)(send_map_starts_RT[num_sends_RT]), (unsigned)(sizeof(int))));
  j = 0;
  for (i = 0; i < num_sends_RT; i++) {
    vec_start = send_map_starts_RT[i];
    vec_len = (send_map_starts_RT[i + 1]) - vec_start;
    MPI_Irecv(&(send_big_elmts[vec_start]), vec_len, MPI_INT, send_procs_RT[i], 0, comm, &(requests[j++]));
  }
  for (i = 0; i < num_recvs_RT; i++) {
    vec_start = recv_vec_starts_RT[i];
    vec_len = (recv_vec_starts_RT[i + 1]) - vec_start;
    MPI_Isend(&(col_map_offd_RT[vec_start]), vec_len, MPI_INT, recv_procs_RT[i], 0, comm, &(requests[j++]));
  }
  MPI_Waitall(j, requests, status);
  for (i = 0; i < (send_map_starts_RT[num_sends_RT]); i++)
    send_map_elmts_RT[i] = (int)((send_big_elmts[i]) - first_col_diag);
  comm_pkg = (hypre_ParCSRCommPkg*)(hypre_CAlloc((unsigned)1, (unsigned)(sizeof(hypre_ParCSRCommPkg))));
  (comm_pkg)->comm = comm;
  (comm_pkg)->num_sends = num_sends_RT;
  (comm_pkg)->num_recvs = num_recvs_RT;
  (comm_pkg)->send_procs = send_procs_RT;
  (comm_pkg)->recv_procs = recv_procs_RT;
  (comm_pkg)->recv_vec_starts = recv_vec_starts_RT;
  (comm_pkg)->send_map_starts = send_map_starts_RT;
  (comm_pkg)->send_map_elmts = send_map_elmts_RT;
  hypre_Free((char*)status), status = (void*)0;
  hypre_Free((char*)requests), requests = (void*)0;
  hypre_Free((char*)send_big_elmts), send_big_elmts = (void*)0;
  (RT)->comm_pkg = comm_pkg;
  hypre_Free((char*)change_array), change_array = (void*)0;
  return ierr;
}
//======================= par_relax.c ======================
int hypre_BoomerAMGRelax(hypre_ParCSRMatrix* A, hypre_ParVector* f, int* cf_marker, int relax_type, int relax_points, double relax_weight, double omega, double* l1_norms, hypre_ParVector* u, hypre_ParVector* Vtemp, hypre_ParVector* Ztemp) {
  MPI_Comm comm = (A)->comm;
  hypre_CSRMatrix* A_diag = (A)->diag;
  double* A_diag_data = (A_diag)->data;
  int* A_diag_i = (A_diag)->i;
  int* A_diag_j = (A_diag)->j;
  hypre_CSRMatrix* A_offd = (A)->offd;
  int* A_offd_i = (A_offd)->i;
  double* A_offd_data = (A_offd)->data;
  int* A_offd_j = (A_offd)->j;
  hypre_ParCSRCommPkg* comm_pkg = (A)->comm_pkg;
  hypre_ParCSRCommHandle* comm_handle;
  int global_num_rows = (A)->global_num_rows;
  int n = (A_diag)->num_rows;
  int num_cols_offd = (A_offd)->num_cols;
  int first_index = (u)->first_index;
  hypre_Vector* u_local = (u)->local_vector;
  double* u_data = (u_local)->data;
  hypre_Vector* f_local = (f)->local_vector;
  double* f_data = (f_local)->data;
  hypre_Vector* Vtemp_local = (Vtemp)->local_vector;
  double* Vtemp_data = (Vtemp_local)->data;
  double* Vext_data;
  double* v_buf_data;
  double* tmp_data;
  hypre_Vector* Ztemp_local;
  double* Ztemp_data;
  hypre_CSRMatrix* A_CSR;
  int* A_CSR_i;
  int* A_CSR_j;
  double* A_CSR_data;
  hypre_Vector* f_vector;
  double* f_vector_data;
  int i;
  int j;
  int jr;
  int ii;
  int jj;
  int i1;
  int ns;
  int ne;
  int size;
  int rest;
  int column;
  int relax_error = 0;
  int num_sends;
  int num_recvs;
  int index;
  int start;
  int num_procs;
  int num_threads;
  int my_id;
  int ip;
  int p;
  int vec_start;
  int vec_len;
  int n_coarse;
  int n_start;
  int n_end;
  MPI_Status* status;
  MPI_Request* requests;
  double* A_mat;
  double* b_vec;
  double zero = 0.0;
  double res;
  double res0;
  double res2;
  double one_minus_weight;
  double one_minus_omega;
  double prod;
  one_minus_weight = 1.0 - relax_weight;
  one_minus_omega = 1.0 - omega;
  MPI_Comm_size(comm, &(num_procs));
  MPI_Comm_rank(comm, &(my_id));
  num_threads = 1;
  n_start = 0;
  n_end = n;
  if (relax_points < (-1)) {
    n_start = -relax_points;
    relax_points = 0;
  }
  if (relax_points > 1) {
    n_end = relax_points;
    relax_points = 0;
  }
  switch (relax_type) {
    case 0:
{
      if (num_procs > 1) {
        num_sends = (comm_pkg)->num_sends;
        v_buf_data = (double*)(hypre_CAlloc((unsigned)((comm_pkg)->send_map_starts[num_sends]), (unsigned)(sizeof(double))));
        Vext_data = (double*)(hypre_CAlloc((unsigned)num_cols_offd, (unsigned)(sizeof(double))));
        if (num_cols_offd) {
          A_offd_j = (A_offd)->j;
          A_offd_data = (A_offd)->data;
        }
        index = 0;
        for (i = 0; i < num_sends; i++) {
          start = (comm_pkg)->send_map_starts[i];
          for (j = start; j < ((comm_pkg)->send_map_starts[i + 1]); j++)
            v_buf_data[index++] = u_data[(comm_pkg)->send_map_elmts[j]];
        }
        comm_handle = hypre_ParCSRCommHandleCreate(1, comm_pkg, v_buf_data, Vext_data);
      }
      for (i = 0; i < n; i++) {
        Vtemp_data[i] = u_data[i];
      }
      if (num_procs > 1) {
        hypre_ParCSRCommHandleDestroy(comm_handle);
        comm_handle = (void*)0;
      }
      if (relax_points == 0) {
        for (i = 0; i < n; i++) {
          if ((A_diag_data[A_diag_i[i]]) != zero) {
            res = f_data[i];
            for (jj = (A_diag_i[i]) + 1; jj < (A_diag_i[i + 1]); jj++) {
              ii = A_diag_j[jj];
              res -= ((A_diag_data[jj]) * (Vtemp_data[ii]));
            }
            for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
              ii = A_offd_j[jj];
              res -= ((A_offd_data[jj]) * (Vext_data[ii]));
            }
            (u_data[i]) -= one_minus_weight;
            u_data[i] += (relax_weight * res) / (A_diag_data[A_diag_i[i]]);
          }
        }
      }
      else {
        for (i = 0; i < n; i++) {
          if (((cf_marker[i]) == relax_points) && ((A_diag_data[A_diag_i[i]]) != zero)) {
            res = f_data[i];
            for (jj = (A_diag_i[i]) + 1; jj < (A_diag_i[i + 1]); jj++) {
              ii = A_diag_j[jj];
              res -= ((A_diag_data[jj]) * (Vtemp_data[ii]));
            }
            for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
              ii = A_offd_j[jj];
              res -= ((A_offd_data[jj]) * (Vext_data[ii]));
            }
            (u_data[i]) -= one_minus_weight;
            u_data[i] += (relax_weight * res) / (A_diag_data[A_diag_i[i]]);
          }
        }
      }
      if (num_procs > 1) {
        hypre_Free((char*)Vext_data), Vext_data = (void*)0;
        hypre_Free((char*)v_buf_data), v_buf_data = (void*)0;
      }
    }
      break;
    case 20:
{
      if (num_threads > 1) {
        Ztemp_local = (Ztemp)->local_vector;
        Ztemp_data = (Ztemp_local)->data;
      }
      if (num_procs > 1) {
        num_sends = (comm_pkg)->num_sends;
        v_buf_data = (double*)(hypre_CAlloc((unsigned)((comm_pkg)->send_map_starts[num_sends]), (unsigned)(sizeof(double))));
        Vext_data = (double*)(hypre_CAlloc((unsigned)num_cols_offd, (unsigned)(sizeof(double))));
        if (num_cols_offd) {
          A_offd_j = (A_offd)->j;
          A_offd_data = (A_offd)->data;
        }
        index = 0;
        for (i = 0; i < num_sends; i++) {
          start = (comm_pkg)->send_map_starts[i];
          for (j = start; j < ((comm_pkg)->send_map_starts[i + 1]); j++)
            v_buf_data[index++] = u_data[(comm_pkg)->send_map_elmts[j]];
        }
        comm_handle = hypre_ParCSRCommHandleCreate(1, comm_pkg, v_buf_data, Vext_data);
        hypre_ParCSRCommHandleDestroy(comm_handle);
        comm_handle = (void*)0;
      }
      if ((relax_weight == 1) && (omega == 1)) {
        if (relax_points == 0) {
          if (num_threads > 1) {
            tmp_data = Ztemp_data;
            for (i = 0; i < n; i++)
              tmp_data[i] = u_data[i];
            for (j = 0; j < num_threads; j++) {
              size = n / num_threads;
              rest = n - (size * num_threads);
              if (j < rest) {
                ns = (j * size) + j;
                ne = (((j + 1) * size) + j) + 1;
              }
              else {
                ns = (j * size) + rest;
                ne = ((j + 1) * size) + rest;
              }
              for (i = ns; i < ne; i++) {
                if ((l1_norms[i]) != zero) {
                  res = f_data[i];
                  for (jj = A_diag_i[i]; jj < (A_diag_i[i + 1]); jj++) {
                    ii = A_diag_j[jj];
                    if ((ii >= ns) && (ii < ne)) {
                      res -= ((A_diag_data[jj]) * (u_data[ii]));
                    }
                    else
                      res -= ((A_diag_data[jj]) * (tmp_data[ii]));
                  }
                  for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
                    ii = A_offd_j[jj];
                    res -= ((A_offd_data[jj]) * (Vext_data[ii]));
                  }
                  u_data[i] += res / (l1_norms[i]);
                }
              }
              for (i = ne - 1; i > (ns - 1); i--) {
                if ((l1_norms[i]) != zero) {
                  res = f_data[i];
                  for (jj = A_diag_i[i]; jj < (A_diag_i[i + 1]); jj++) {
                    ii = A_diag_j[jj];
                    if ((ii >= ns) && (ii < ne)) {
                      res -= ((A_diag_data[jj]) * (u_data[ii]));
                    }
                    else
                      res -= ((A_diag_data[jj]) * (tmp_data[ii]));
                  }
                  for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
                    ii = A_offd_j[jj];
                    res -= ((A_offd_data[jj]) * (Vext_data[ii]));
                  }
                  u_data[i] += res / (l1_norms[i]);
                }
              }
            }
          }
          else {
            for (i = 0; i < n; i++) {
              if ((l1_norms[i]) != zero) {
                res = f_data[i];
                for (jj = A_diag_i[i]; jj < (A_diag_i[i + 1]); jj++) {
                  ii = A_diag_j[jj];
                  res -= ((A_diag_data[jj]) * (u_data[ii]));
                }
                for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
                  ii = A_offd_j[jj];
                  res -= ((A_offd_data[jj]) * (Vext_data[ii]));
                }
                u_data[i] += res / (l1_norms[i]);
              }
            }
            for (i = n - 1; i > (-1); i--) {
              if ((l1_norms[i]) != zero) {
                res = f_data[i];
                for (jj = A_diag_i[i]; jj < (A_diag_i[i + 1]); jj++) {
                  ii = A_diag_j[jj];
                  res -= ((A_diag_data[jj]) * (u_data[ii]));
                }
                for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
                  ii = A_offd_j[jj];
                  res -= ((A_offd_data[jj]) * (Vext_data[ii]));
                }
                u_data[i] += res / (l1_norms[i]);
              }
            }
          }
        }
        else {
          if (num_threads > 1) {
            tmp_data = Ztemp_data;
            for (i = 0; i < n; i++)
              tmp_data[i] = u_data[i];
            for (j = 0; j < num_threads; j++) {
              size = n / num_threads;
              rest = n - (size * num_threads);
              if (j < rest) {
                ns = (j * size) + j;
                ne = (((j + 1) * size) + j) + 1;
              }
              else {
                ns = (j * size) + rest;
                ne = ((j + 1) * size) + rest;
              }
              for (i = ns; i < ne; i++) {
                if (((cf_marker[i]) == relax_points) && ((l1_norms[i]) != zero)) {
                  res = f_data[i];
                  for (jj = A_diag_i[i]; jj < (A_diag_i[i + 1]); jj++) {
                    ii = A_diag_j[jj];
                    if ((ii >= ns) && (ii < ne)) {
                      res -= ((A_diag_data[jj]) * (u_data[ii]));
                    }
                    else
                      res -= ((A_diag_data[jj]) * (tmp_data[ii]));
                  }
                  for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
                    ii = A_offd_j[jj];
                    res -= ((A_offd_data[jj]) * (Vext_data[ii]));
                  }
                  u_data[i] += res / (l1_norms[i]);
                }
              }
              for (i = ne - 1; i > (ns - 1); i--) {
                if (((cf_marker[i]) == relax_points) && ((l1_norms[i]) != zero)) {
                  res = f_data[i];
                  for (jj = A_diag_i[i]; jj < (A_diag_i[i + 1]); jj++) {
                    ii = A_diag_j[jj];
                    if ((ii >= ns) && (ii < ne)) {
                      res -= ((A_diag_data[jj]) * (u_data[ii]));
                    }
                    else
                      res -= ((A_diag_data[jj]) * (tmp_data[ii]));
                  }
                  for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
                    ii = A_offd_j[jj];
                    res -= ((A_offd_data[jj]) * (Vext_data[ii]));
                  }
                  u_data[i] += res / (l1_norms[i]);
                }
              }
            }
          }
          else {
            for (i = 0; i < n; i++) {
              if (((cf_marker[i]) == relax_points) && ((l1_norms[i]) != zero)) {
                res = f_data[i];
                for (jj = A_diag_i[i]; jj < (A_diag_i[i + 1]); jj++) {
                  ii = A_diag_j[jj];
                  res -= ((A_diag_data[jj]) * (u_data[ii]));
                }
                for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
                  ii = A_offd_j[jj];
                  res -= ((A_offd_data[jj]) * (Vext_data[ii]));
                }
                u_data[i] += res / (l1_norms[i]);
              }
            }
            for (i = n - 1; i > (-1); i--) {
              if (((cf_marker[i]) == relax_points) && ((l1_norms[i]) != zero)) {
                res = f_data[i];
                for (jj = A_diag_i[i]; jj < (A_diag_i[i + 1]); jj++) {
                  ii = A_diag_j[jj];
                  res -= ((A_diag_data[jj]) * (u_data[ii]));
                }
                for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
                  ii = A_offd_j[jj];
                  res -= ((A_offd_data[jj]) * (Vext_data[ii]));
                }
                u_data[i] += res / (l1_norms[i]);
              }
            }
          }
        }
      }
      else {
        for (i = 0; i < n; i++) {
          Vtemp_data[i] = u_data[i];
        }
        prod = 1.0 - (relax_weight * omega);
        if (relax_points == 0) {
          if (num_threads > 1) {
            tmp_data = Ztemp_data;
            for (i = 0; i < n; i++)
              tmp_data[i] = u_data[i];
            for (j = 0; j < num_threads; j++) {
              size = n / num_threads;
              rest = n - (size * num_threads);
              if (j < rest) {
                ns = (j * size) + j;
                ne = (((j + 1) * size) + j) + 1;
              }
              else {
                ns = (j * size) + rest;
                ne = ((j + 1) * size) + rest;
              }
              for (i = ns; i < ne; i++) {
                if ((l1_norms[i]) != zero) {
                  res0 = 0.0;
                  res2 = 0.0;
                  res = f_data[i];
                  for (jj = (A_diag_i[i]) + 1; jj < (A_diag_i[i + 1]); jj++) {
                    ii = A_diag_j[jj];
                    if ((ii >= ns) && (ii < ne)) {
                      res0 -= ((A_diag_data[jj]) * (u_data[ii]));
                      res2 += (A_diag_data[jj]) * (Vtemp_data[ii]);
                    }
                    else
                      res -= ((A_diag_data[jj]) * (tmp_data[ii]));
                  }
                  for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
                    ii = A_offd_j[jj];
                    res -= ((A_offd_data[jj]) * (Vext_data[ii]));
                  }
                  (u_data[i]) -= prod;
                  u_data[i] += (relax_weight * (((omega * res) + res0) + (one_minus_omega * res2))) / (l1_norms[i]);
                }
              }
              for (i = ne - 1; i > (ns - 1); i--) {
                if ((l1_norms[i]) != zero) {
                  res0 = 0.0;
                  res2 = 0.0;
                  res = f_data[i];
                  for (jj = (A_diag_i[i]) + 1; jj < (A_diag_i[i + 1]); jj++) {
                    ii = A_diag_j[jj];
                    if ((ii >= ns) && (ii < ne)) {
                      res0 -= ((A_diag_data[jj]) * (u_data[ii]));
                      res2 += (A_diag_data[jj]) * (Vtemp_data[ii]);
                    }
                    else
                      res -= ((A_diag_data[jj]) * (tmp_data[ii]));
                  }
                  for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
                    ii = A_offd_j[jj];
                    res -= ((A_offd_data[jj]) * (Vext_data[ii]));
                  }
                  (u_data[i]) -= prod;
                  u_data[i] += (relax_weight * (((omega * res) + res0) + (one_minus_omega * res2))) / (l1_norms[i]);
                }
              }
            }
          }
          else {
            for (i = 0; i < n; i++) {
              if ((l1_norms[i]) != zero) {
                res0 = 0.0;
                res = f_data[i];
                res2 = 0.0;
                for (jj = (A_diag_i[i]) + 1; jj < (A_diag_i[i + 1]); jj++) {
                  ii = A_diag_j[jj];
                  res0 -= ((A_diag_data[jj]) * (u_data[ii]));
                  res2 += (A_diag_data[jj]) * (Vtemp_data[ii]);
                }
                for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
                  ii = A_offd_j[jj];
                  res -= ((A_offd_data[jj]) * (Vext_data[ii]));
                }
                (u_data[i]) -= prod;
                u_data[i] += (relax_weight * (((omega * res) + res0) + (one_minus_omega * res2))) / (l1_norms[i]);
              }
            }
            for (i = n - 1; i > (-1); i--) {
              if ((l1_norms[i]) != zero) {
                res0 = 0.0;
                res = f_data[i];
                res2 = 0.0;
                for (jj = (A_diag_i[i]) + 1; jj < (A_diag_i[i + 1]); jj++) {
                  ii = A_diag_j[jj];
                  res0 -= ((A_diag_data[jj]) * (u_data[ii]));
                  res2 += (A_diag_data[jj]) * (Vtemp_data[ii]);
                }
                for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
                  ii = A_offd_j[jj];
                  res -= ((A_offd_data[jj]) * (Vext_data[ii]));
                }
                (u_data[i]) -= prod;
                u_data[i] += (relax_weight * (((omega * res) + res0) + (one_minus_omega * res2))) / (l1_norms[i]);
              }
            }
          }
        }
        else {
          if (num_threads > 1) {
            tmp_data = Ztemp_data;
            for (i = 0; i < n; i++)
              tmp_data[i] = u_data[i];
            for (j = 0; j < num_threads; j++) {
              size = n / num_threads;
              rest = n - (size * num_threads);
              if (j < rest) {
                ns = (j * size) + j;
                ne = (((j + 1) * size) + j) + 1;
              }
              else {
                ns = (j * size) + rest;
                ne = ((j + 1) * size) + rest;
              }
              for (i = ns; i < ne; i++) {
                if (((cf_marker[i]) == relax_points) && ((l1_norms[i]) != zero)) {
                  res0 = 0.0;
                  res2 = 0.0;
                  res = f_data[i];
                  for (jj = (A_diag_i[i]) + 1; jj < (A_diag_i[i + 1]); jj++) {
                    ii = A_diag_j[jj];
                    if ((ii >= ns) && (ii < ne)) {
                      res2 += (A_diag_data[jj]) * (Vtemp_data[ii]);
                      res0 -= ((A_diag_data[jj]) * (u_data[ii]));
                    }
                    else
                      res -= ((A_diag_data[jj]) * (tmp_data[ii]));
                  }
                  for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
                    ii = A_offd_j[jj];
                    res -= ((A_offd_data[jj]) * (Vext_data[ii]));
                  }
                  (u_data[i]) -= prod;
                  u_data[i] += (relax_weight * (((omega * res) + res0) + (one_minus_omega * res2))) / (l1_norms[i]);
                }
              }
              for (i = ne - 1; i > (ns - 1); i--) {
                if (((cf_marker[i]) == relax_points) && ((l1_norms[i]) != zero)) {
                  res0 = 0.0;
                  res2 = 0.0;
                  res = f_data[i];
                  for (jj = (A_diag_i[i]) + 1; jj < (A_diag_i[i + 1]); jj++) {
                    ii = A_diag_j[jj];
                    if ((ii >= ns) && (ii < ne)) {
                      res2 += (A_diag_data[jj]) * (Vtemp_data[ii]);
                      res0 -= ((A_diag_data[jj]) * (u_data[ii]));
                    }
                    else
                      res -= ((A_diag_data[jj]) * (tmp_data[ii]));
                  }
                  for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
                    ii = A_offd_j[jj];
                    res -= ((A_offd_data[jj]) * (Vext_data[ii]));
                  }
                  (u_data[i]) -= prod;
                  u_data[i] += (relax_weight * (((omega * res) + res0) + (one_minus_omega * res2))) / (l1_norms[i]);
                }
              }
            }
          }
          else {
            for (i = 0; i < n; i++) {
              if (((cf_marker[i]) == relax_points) && ((l1_norms[i]) != zero)) {
                res = f_data[i];
                res0 = 0.0;
                res2 = 0.0;
                for (jj = (A_diag_i[i]) + 1; jj < (A_diag_i[i + 1]); jj++) {
                  ii = A_diag_j[jj];
                  res0 -= ((A_diag_data[jj]) * (u_data[ii]));
                  res2 += (A_diag_data[jj]) * (Vtemp_data[ii]);
                }
                for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
                  ii = A_offd_j[jj];
                  res -= ((A_offd_data[jj]) * (Vext_data[ii]));
                }
                (u_data[i]) -= prod;
                u_data[i] += (relax_weight * (((omega * res) + res0) + (one_minus_omega * res2))) / (l1_norms[i]);
              }
            }
            for (i = n - 1; i > (-1); i--) {
              if (((cf_marker[i]) == relax_points) && ((l1_norms[i]) != zero)) {
                res = f_data[i];
                res0 = 0.0;
                res2 = 0.0;
                for (jj = (A_diag_i[i]) + 1; jj < (A_diag_i[i + 1]); jj++) {
                  ii = A_diag_j[jj];
                  res0 -= ((A_diag_data[jj]) * (u_data[ii]));
                  res2 += (A_diag_data[jj]) * (Vtemp_data[ii]);
                }
                for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
                  ii = A_offd_j[jj];
                  res -= ((A_offd_data[jj]) * (Vext_data[ii]));
                }
                (u_data[i]) -= prod;
                u_data[i] += (relax_weight * (((omega * res) + res0) + (one_minus_omega * res2))) / (l1_norms[i]);
              }
            }
          }
        }
      }
      if (num_procs > 1) {
        hypre_Free((char*)Vext_data), Vext_data = (void*)0;
        hypre_Free((char*)v_buf_data), v_buf_data = (void*)0;
      }
    }
      break;
    case 5:
{
      if (num_procs > 1) {
        num_sends = (comm_pkg)->num_sends;
        v_buf_data = (double*)(hypre_CAlloc((unsigned)((comm_pkg)->send_map_starts[num_sends]), (unsigned)(sizeof(double))));
        Vext_data = (double*)(hypre_CAlloc((unsigned)num_cols_offd, (unsigned)(sizeof(double))));
        if (num_cols_offd) {
          A_offd_j = (A_offd)->j;
          A_offd_data = (A_offd)->data;
        }
        index = 0;
        for (i = 0; i < num_sends; i++) {
          start = (comm_pkg)->send_map_starts[i];
          for (j = start; j < ((comm_pkg)->send_map_starts[i + 1]); j++)
            v_buf_data[index++] = u_data[(comm_pkg)->send_map_elmts[j]];
        }
        comm_handle = hypre_ParCSRCommHandleCreate(1, comm_pkg, v_buf_data, Vext_data);
        hypre_ParCSRCommHandleDestroy(comm_handle);
        comm_handle = (void*)0;
      }
      if (relax_points == 0) {
        for (i = 0; i < n; i++) {
          if ((A_diag_data[A_diag_i[i]]) != zero) {
            res = f_data[i];
            for (jj = (A_diag_i[i]) + 1; jj < (A_diag_i[i + 1]); jj++) {
              ii = A_diag_j[jj];
              res -= ((A_diag_data[jj]) * (u_data[ii]));
            }
            for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
              ii = A_offd_j[jj];
              res -= ((A_offd_data[jj]) * (Vext_data[ii]));
            }
            u_data[i] = res / (A_diag_data[A_diag_i[i]]);
          }
        }
      }
      else
        if (relax_points > 1) {
          n_coarse = relax_points;
          for (i1 = 0; i1 < n_coarse; i1++) {
            i = cf_marker[i1];
            if ((A_diag_data[A_diag_i[i]]) != zero) {
              res = f_data[i];
              for (jj = (A_diag_i[i]) + 1; jj < (A_diag_i[i + 1]); jj++) {
                ii = A_diag_j[jj];
                res -= ((A_diag_data[jj]) * (Vtemp_data[ii]));
              }
              for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
                ii = A_offd_j[jj];
                res -= ((A_offd_data[jj]) * (Vext_data[ii]));
              }
              (u_data[i]) -= one_minus_weight;
              u_data[i] += (relax_weight * res) / (A_diag_data[A_diag_i[i]]);
            }
          }
        }
        else {
          for (i = 0; i < n; i++) {
            if (((cf_marker[i]) == relax_points) && ((A_diag_data[A_diag_i[i]]) != zero)) {
              res = f_data[i];
              for (jj = (A_diag_i[i]) + 1; jj < (A_diag_i[i + 1]); jj++) {
                ii = A_diag_j[jj];
                res -= ((A_diag_data[jj]) * (u_data[ii]));
              }
              for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
                ii = A_offd_j[jj];
                res -= ((A_offd_data[jj]) * (Vext_data[ii]));
              }
              u_data[i] = res / (A_diag_data[A_diag_i[i]]);
            }
          }
        }
      if (num_procs > 1) {
        hypre_Free((char*)Vext_data), Vext_data = (void*)0;
        hypre_Free((char*)v_buf_data), v_buf_data = (void*)0;
      }
    }
      break;
    case 3:
{
      Ztemp_local = (Ztemp)->local_vector;
      Ztemp_data = (Ztemp_local)->data;
      if (num_procs > 1) {
        num_sends = (comm_pkg)->num_sends;
        v_buf_data = (double*)(hypre_CAlloc((unsigned)((comm_pkg)->send_map_starts[num_sends]), (unsigned)(sizeof(double))));
        Vext_data = (double*)(hypre_CAlloc((unsigned)num_cols_offd, (unsigned)(sizeof(double))));
        if (num_cols_offd) {
          A_offd_j = (A_offd)->j;
          A_offd_data = (A_offd)->data;
        }
        index = 0;
        for (i = 0; i < num_sends; i++) {
          start = (comm_pkg)->send_map_starts[i];
          for (j = start; j < ((comm_pkg)->send_map_starts[i + 1]); j++)
            v_buf_data[index++] = u_data[(comm_pkg)->send_map_elmts[j]];
        }
        comm_handle = hypre_ParCSRCommHandleCreate(1, comm_pkg, v_buf_data, Vext_data);
        hypre_ParCSRCommHandleDestroy(comm_handle);
        comm_handle = (void*)0;
      }
      if ((relax_weight == 1) && (omega == 1)) {
        if (relax_points == 0) {
          if (num_threads > 1) {
            tmp_data = Ztemp_data;
            for (i = 0; i < n; i++)
              tmp_data[i] = u_data[i];
            for (j = 0; j < num_threads; j++) {
              size = n / num_threads;
              rest = n - (size * num_threads);
              if (j < rest) {
                ns = (j * size) + j;
                ne = (((j + 1) * size) + j) + 1;
              }
              else {
                ns = (j * size) + rest;
                ne = ((j + 1) * size) + rest;
              }
              for (i = ns; i < ne; i++) {
                if ((A_diag_data[A_diag_i[i]]) != zero) {
                  res = f_data[i];
                  for (jj = (A_diag_i[i]) + 1; jj < (A_diag_i[i + 1]); jj++) {
                    ii = A_diag_j[jj];
                    if ((ii >= ns) && (ii < ne))
                      res -= ((A_diag_data[jj]) * (u_data[ii]));
                    else
                      res -= ((A_diag_data[jj]) * (tmp_data[ii]));
                  }
                  for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
                    ii = A_offd_j[jj];
                    res -= ((A_offd_data[jj]) * (Vext_data[ii]));
                  }
                  u_data[i] = res / (A_diag_data[A_diag_i[i]]);
                }
              }
            }
          }
          else {
            for (i = 0; i < n; i++) {
              if ((A_diag_data[A_diag_i[i]]) != zero) {
                res = f_data[i];
                for (jj = (A_diag_i[i]) + 1; jj < (A_diag_i[i + 1]); jj++) {
                  ii = A_diag_j[jj];
                  res -= ((A_diag_data[jj]) * (u_data[ii]));
                }
                for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
                  ii = A_offd_j[jj];
                  res -= ((A_offd_data[jj]) * (Vext_data[ii]));
                }
                u_data[i] = res / (A_diag_data[A_diag_i[i]]);
              }
            }
          }
        }
        else {
          if (num_threads > 1) {
            tmp_data = Ztemp_data;
            for (i = 0; i < n; i++)
              tmp_data[i] = u_data[i];
            for (j = 0; j < num_threads; j++) {
              size = n / num_threads;
              rest = n - (size * num_threads);
              if (j < rest) {
                ns = (j * size) + j;
                ne = (((j + 1) * size) + j) + 1;
              }
              else {
                ns = (j * size) + rest;
                ne = ((j + 1) * size) + rest;
              }
              for (i = ns; i < ne; i++) {
                if (((cf_marker[i]) == relax_points) && ((A_diag_data[A_diag_i[i]]) != zero)) {
                  res = f_data[i];
                  for (jj = (A_diag_i[i]) + 1; jj < (A_diag_i[i + 1]); jj++) {
                    ii = A_diag_j[jj];
                    if ((ii >= ns) && (ii < ne))
                      res -= ((A_diag_data[jj]) * (u_data[ii]));
                    else
                      res -= ((A_diag_data[jj]) * (tmp_data[ii]));
                  }
                  for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
                    ii = A_offd_j[jj];
                    res -= ((A_offd_data[jj]) * (Vext_data[ii]));
                  }
                  u_data[i] = res / (A_diag_data[A_diag_i[i]]);
                }
              }
            }
          }
          else {
            for (i = 0; i < n; i++) {
              if (((cf_marker[i]) == relax_points) && ((A_diag_data[A_diag_i[i]]) != zero)) {
                res = f_data[i];
                for (jj = (A_diag_i[i]) + 1; jj < (A_diag_i[i + 1]); jj++) {
                  ii = A_diag_j[jj];
                  res -= ((A_diag_data[jj]) * (u_data[ii]));
                }
                for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
                  ii = A_offd_j[jj];
                  res -= ((A_offd_data[jj]) * (Vext_data[ii]));
                }
                u_data[i] = res / (A_diag_data[A_diag_i[i]]);
              }
            }
          }
        }
      }
      else {
        for (i = 0; i < n; i++) {
          Vtemp_data[i] = u_data[i];
        }
        prod = 1.0 - (relax_weight * omega);
        if (relax_points == 0) {
          if (num_threads > 1) {
            tmp_data = Ztemp_data;
            for (i = 0; i < n; i++)
              tmp_data[i] = u_data[i];
            for (j = 0; j < num_threads; j++) {
              size = n / num_threads;
              rest = n - (size * num_threads);
              if (j < rest) {
                ns = (j * size) + j;
                ne = (((j + 1) * size) + j) + 1;
              }
              else {
                ns = (j * size) + rest;
                ne = ((j + 1) * size) + rest;
              }
              for (i = ns; i < ne; i++) {
                if ((A_diag_data[A_diag_i[i]]) != zero) {
                  res = f_data[i];
                  res0 = 0.0;
                  res2 = 0.0;
                  for (jj = (A_diag_i[i]) + 1; jj < (A_diag_i[i + 1]); jj++) {
                    ii = A_diag_j[jj];
                    if ((ii >= ns) && (ii < ne)) {
                      res0 -= ((A_diag_data[jj]) * (u_data[ii]));
                      res2 += (A_diag_data[jj]) * (Vtemp_data[ii]);
                    }
                    else
                      res -= ((A_diag_data[jj]) * (tmp_data[ii]));
                  }
                  for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
                    ii = A_offd_j[jj];
                    res -= ((A_offd_data[jj]) * (Vext_data[ii]));
                  }
                  (u_data[i]) -= prod;
                  u_data[i] += (relax_weight * (((omega * res) + res0) + (one_minus_omega * res2))) / (A_diag_data[A_diag_i[i]]);
                }
              }
            }
          }
          else {
            for (i = 0; i < n; i++) {
              if ((A_diag_data[A_diag_i[i]]) != zero) {
                res0 = 0.0;
                res2 = 0.0;
                res = f_data[i];
                for (jj = (A_diag_i[i]) + 1; jj < (A_diag_i[i + 1]); jj++) {
                  ii = A_diag_j[jj];
                  res0 -= ((A_diag_data[jj]) * (u_data[ii]));
                  res2 += (A_diag_data[jj]) * (Vtemp_data[ii]);
                }
                for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
                  ii = A_offd_j[jj];
                  res -= ((A_offd_data[jj]) * (Vext_data[ii]));
                }
                (u_data[i]) -= prod;
                u_data[i] += (relax_weight * (((omega * res) + res0) + (one_minus_omega * res2))) / (A_diag_data[A_diag_i[i]]);
              }
            }
          }
        }
        else {
          if (num_threads > 1) {
            tmp_data = Ztemp_data;
            for (i = 0; i < n; i++)
              tmp_data[i] = u_data[i];
            for (j = 0; j < num_threads; j++) {
              size = n / num_threads;
              rest = n - (size * num_threads);
              if (j < rest) {
                ns = (j * size) + j;
                ne = (((j + 1) * size) + j) + 1;
              }
              else {
                ns = (j * size) + rest;
                ne = ((j + 1) * size) + rest;
              }
              for (i = ns; i < ne; i++) {
                if (((cf_marker[i]) == relax_points) && ((A_diag_data[A_diag_i[i]]) != zero)) {
                  res0 = 0.0;
                  res2 = 0.0;
                  res = f_data[i];
                  for (jj = (A_diag_i[i]) + 1; jj < (A_diag_i[i + 1]); jj++) {
                    ii = A_diag_j[jj];
                    if ((ii >= ns) && (ii < ne)) {
                      res0 -= ((A_diag_data[jj]) * (u_data[ii]));
                      res2 += (A_diag_data[jj]) * (Vtemp_data[ii]);
                    }
                    else
                      res -= ((A_diag_data[jj]) * (tmp_data[ii]));
                  }
                  for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
                    ii = A_offd_j[jj];
                    res -= ((A_offd_data[jj]) * (Vext_data[ii]));
                  }
                  (u_data[i]) -= prod;
                  u_data[i] += (relax_weight * (((omega * res) + res0) + (one_minus_omega * res2))) / (A_diag_data[A_diag_i[i]]);
                }
              }
            }
          }
          else {
            for (i = 0; i < n; i++) {
              if (((cf_marker[i]) == relax_points) && ((A_diag_data[A_diag_i[i]]) != zero)) {
                res = f_data[i];
                res0 = 0.0;
                res2 = 0.0;
                for (jj = (A_diag_i[i]) + 1; jj < (A_diag_i[i + 1]); jj++) {
                  ii = A_diag_j[jj];
                  res0 -= ((A_diag_data[jj]) * (u_data[ii]));
                  res2 += (A_diag_data[jj]) * (Vtemp_data[ii]);
                }
                for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
                  ii = A_offd_j[jj];
                  res -= ((A_offd_data[jj]) * (Vext_data[ii]));
                }
                (u_data[i]) -= prod;
                u_data[i] += (relax_weight * (((omega * res) + res0) + (one_minus_omega * res2))) / (A_diag_data[A_diag_i[i]]);
              }
            }
          }
        }
      }
      if (num_procs > 1) {
        hypre_Free((char*)Vext_data), Vext_data = (void*)0;
        hypre_Free((char*)v_buf_data), v_buf_data = (void*)0;
      }
    }
      break;
    case 1:
{
      if (num_procs > 1) {
        num_sends = (comm_pkg)->num_sends;
        num_recvs = (comm_pkg)->num_recvs;
        v_buf_data = (double*)(hypre_CAlloc((unsigned)((comm_pkg)->send_map_starts[num_sends]), (unsigned)(sizeof(double))));
        Vext_data = (double*)(hypre_CAlloc((unsigned)num_cols_offd, (unsigned)(sizeof(double))));
        status = (MPI_Status*)(hypre_CAlloc((unsigned)(num_recvs + num_sends), (unsigned)(sizeof(MPI_Status))));
        requests = (MPI_Request*)(hypre_CAlloc((unsigned)(num_recvs + num_sends), (unsigned)(sizeof(MPI_Request))));
        if (num_cols_offd) {
          A_offd_j = (A_offd)->j;
          A_offd_data = (A_offd)->data;
        }
      }
      for (p = 0; p < num_procs; p++) {
        jr = 0;
        if (p != my_id) {
          for (i = 0; i < num_sends; i++) {
            ip = (comm_pkg)->send_procs[i];
            if (ip == p) {
              vec_start = (comm_pkg)->send_map_starts[i];
              vec_len = ((comm_pkg)->send_map_starts[i + 1]) - vec_start;
              for (j = vec_start; j < (vec_start + vec_len); j++)
                v_buf_data[j] = u_data[(comm_pkg)->send_map_elmts[j]];
              MPI_Isend(&(v_buf_data[vec_start]), vec_len, MPI_DOUBLE, ip, 0, comm, &(requests[jr++]));
            }
          }
          MPI_Waitall(jr, requests, status);
          MPI_Barrier(comm);
        }
        else {
          if (num_procs > 1) {
            for (i = 0; i < num_recvs; i++) {
              ip = (comm_pkg)->recv_procs[i];
              vec_start = (comm_pkg)->recv_vec_starts[i];
              vec_len = ((comm_pkg)->recv_vec_starts[i + 1]) - vec_start;
              MPI_Irecv(&(Vext_data[vec_start]), vec_len, MPI_DOUBLE, ip, 0, comm, &(requests[jr++]));
            }
            MPI_Waitall(jr, requests, status);
          }
          if (relax_points == 0) {
            for (i = 0; i < n; i++) {
              if ((A_diag_data[A_diag_i[i]]) != zero) {
                res = f_data[i];
                for (jj = (A_diag_i[i]) + 1; jj < (A_diag_i[i + 1]); jj++) {
                  ii = A_diag_j[jj];
                  res -= ((A_diag_data[jj]) * (u_data[ii]));
                }
                for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
                  ii = A_offd_j[jj];
                  res -= ((A_offd_data[jj]) * (Vext_data[ii]));
                }
                u_data[i] = res / (A_diag_data[A_diag_i[i]]);
              }
            }
          }
          else {
            for (i = 0; i < n; i++) {
              if (((cf_marker[i]) == relax_points) && ((A_diag_data[A_diag_i[i]]) != zero)) {
                res = f_data[i];
                for (jj = (A_diag_i[i]) + 1; jj < (A_diag_i[i + 1]); jj++) {
                  ii = A_diag_j[jj];
                  res -= ((A_diag_data[jj]) * (u_data[ii]));
                }
                for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
                  ii = A_offd_j[jj];
                  res -= ((A_offd_data[jj]) * (Vext_data[ii]));
                }
                u_data[i] = res / (A_diag_data[A_diag_i[i]]);
              }
            }
          }
          if (num_procs > 1)
            MPI_Barrier(comm);
        }
      }
      if (num_procs > 1) {
        hypre_Free((char*)Vext_data), Vext_data = (void*)0;
        hypre_Free((char*)v_buf_data), v_buf_data = (void*)0;
        hypre_Free((char*)status), status = (void*)0;
        hypre_Free((char*)requests), requests = (void*)0;
      }
    }
      break;
    case 2:
{
      if (num_procs > 1) {
        num_sends = (comm_pkg)->num_sends;
        num_recvs = (comm_pkg)->num_recvs;
        v_buf_data = (double*)(hypre_CAlloc((unsigned)((comm_pkg)->send_map_starts[num_sends]), (unsigned)(sizeof(double))));
        Vext_data = (double*)(hypre_CAlloc((unsigned)num_cols_offd, (unsigned)(sizeof(double))));
        status = (MPI_Status*)(hypre_CAlloc((unsigned)(num_recvs + num_sends), (unsigned)(sizeof(MPI_Status))));
        requests = (MPI_Request*)(hypre_CAlloc((unsigned)(num_recvs + num_sends), (unsigned)(sizeof(MPI_Request))));
        if (num_cols_offd) {
          A_offd_j = (A_offd)->j;
          A_offd_data = (A_offd)->data;
        }
      }
      if (relax_points == 0) {
        for (i = 0; i < n; i++) {
          if ((((A_offd_i[i + 1]) - (A_offd_i[i])) == zero) && ((A_diag_data[A_diag_i[i]]) != zero)) {
            res = f_data[i];
            for (jj = (A_diag_i[i]) + 1; jj < (A_diag_i[i + 1]); jj++) {
              ii = A_diag_j[jj];
              res -= ((A_diag_data[jj]) * (u_data[ii]));
            }
            u_data[i] = res / (A_diag_data[A_diag_i[i]]);
          }
        }
      }
      else {
        for (i = 0; i < n; i++) {
          if ((((cf_marker[i]) == relax_points) && (((A_offd_i[i + 1]) - (A_offd_i[i])) == zero)) && ((A_diag_data[A_diag_i[i]]) != zero)) {
            res = f_data[i];
            for (jj = (A_diag_i[i]) + 1; jj < (A_diag_i[i + 1]); jj++) {
              ii = A_diag_j[jj];
              res -= ((A_diag_data[jj]) * (u_data[ii]));
            }
            u_data[i] = res / (A_diag_data[A_diag_i[i]]);
          }
        }
      }
      for (p = 0; p < num_procs; p++) {
        jr = 0;
        if (p != my_id) {
          for (i = 0; i < num_sends; i++) {
            ip = (comm_pkg)->send_procs[i];
            if (ip == p) {
              vec_start = (comm_pkg)->send_map_starts[i];
              vec_len = ((comm_pkg)->send_map_starts[i + 1]) - vec_start;
              for (j = vec_start; j < (vec_start + vec_len); j++)
                v_buf_data[j] = u_data[(comm_pkg)->send_map_elmts[j]];
              MPI_Isend(&(v_buf_data[vec_start]), vec_len, MPI_DOUBLE, ip, 0, comm, &(requests[jr++]));
            }
          }
          MPI_Waitall(jr, requests, status);
          MPI_Barrier(comm);
        }
        else {
          if (num_procs > 1) {
            for (i = 0; i < num_recvs; i++) {
              ip = (comm_pkg)->recv_procs[i];
              vec_start = (comm_pkg)->recv_vec_starts[i];
              vec_len = ((comm_pkg)->recv_vec_starts[i + 1]) - vec_start;
              MPI_Irecv(&(Vext_data[vec_start]), vec_len, MPI_DOUBLE, ip, 0, comm, &(requests[jr++]));
            }
            MPI_Waitall(jr, requests, status);
          }
          if (relax_points == 0) {
            for (i = 0; i < n; i++) {
              if ((((A_offd_i[i + 1]) - (A_offd_i[i])) != zero) && ((A_diag_data[A_diag_i[i]]) != zero)) {
                res = f_data[i];
                for (jj = (A_diag_i[i]) + 1; jj < (A_diag_i[i + 1]); jj++) {
                  ii = A_diag_j[jj];
                  res -= ((A_diag_data[jj]) * (u_data[ii]));
                }
                for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
                  ii = A_offd_j[jj];
                  res -= ((A_offd_data[jj]) * (Vext_data[ii]));
                }
                u_data[i] = res / (A_diag_data[A_diag_i[i]]);
              }
            }
          }
          else {
            for (i = 0; i < n; i++) {
              if ((((cf_marker[i]) == relax_points) && (((A_offd_i[i + 1]) - (A_offd_i[i])) != zero)) && ((A_diag_data[A_diag_i[i]]) != zero)) {
                res = f_data[i];
                for (jj = (A_diag_i[i]) + 1; jj < (A_diag_i[i + 1]); jj++) {
                  ii = A_diag_j[jj];
                  res -= ((A_diag_data[jj]) * (u_data[ii]));
                }
                for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
                  ii = A_offd_j[jj];
                  res -= ((A_offd_data[jj]) * (Vext_data[ii]));
                }
                u_data[i] = res / (A_diag_data[A_diag_i[i]]);
              }
            }
          }
          if (num_procs > 1)
            MPI_Barrier(comm);
        }
      }
      if (num_procs > 1) {
        hypre_Free((char*)Vext_data), Vext_data = (void*)0;
        hypre_Free((char*)v_buf_data), v_buf_data = (void*)0;
        hypre_Free((char*)status), status = (void*)0;
        hypre_Free((char*)requests), requests = (void*)0;
      }
    }
      break;
    case 4:
{
      if (num_procs > 1) {
        num_sends = (comm_pkg)->num_sends;
        v_buf_data = (double*)(hypre_CAlloc((unsigned)((comm_pkg)->send_map_starts[num_sends]), (unsigned)(sizeof(double))));
        Vext_data = (double*)(hypre_CAlloc((unsigned)num_cols_offd, (unsigned)(sizeof(double))));
        if (num_cols_offd) {
          A_offd_j = (A_offd)->j;
          A_offd_data = (A_offd)->data;
        }
        index = 0;
        for (i = 0; i < num_sends; i++) {
          start = (comm_pkg)->send_map_starts[i];
          for (j = start; j < ((comm_pkg)->send_map_starts[i + 1]); j++)
            v_buf_data[index++] = u_data[(comm_pkg)->send_map_elmts[j]];
        }
        comm_handle = hypre_ParCSRCommHandleCreate(1, comm_pkg, v_buf_data, Vext_data);
        hypre_ParCSRCommHandleDestroy(comm_handle);
        comm_handle = (void*)0;
      }
      if ((relax_weight == 1) && (omega == 1)) {
        if (relax_points == 0) {
          if (num_threads > 1) {
            tmp_data = (double*)(hypre_CAlloc((unsigned)n, (unsigned)(sizeof(double))));
            for (i = 0; i < n; i++)
              tmp_data[i] = u_data[i];
            for (j = 0; j < num_threads; j++) {
              size = n / num_threads;
              rest = n - (size * num_threads);
              if (j < rest) {
                ns = (j * size) + j;
                ne = (((j + 1) * size) + j) + 1;
              }
              else {
                ns = (j * size) + rest;
                ne = ((j + 1) * size) + rest;
              }
              for (i = ne - 1; i > (ns - 1); i--) {
                if ((A_diag_data[A_diag_i[i]]) != zero) {
                  res = f_data[i];
                  for (jj = (A_diag_i[i]) + 1; jj < (A_diag_i[i + 1]); jj++) {
                    ii = A_diag_j[jj];
                    if ((ii >= ns) && (ii < ne))
                      res -= ((A_diag_data[jj]) * (u_data[ii]));
                    else
                      res -= ((A_diag_data[jj]) * (tmp_data[ii]));
                  }
                  for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
                    ii = A_offd_j[jj];
                    res -= ((A_offd_data[jj]) * (Vext_data[ii]));
                  }
                  u_data[i] = res / (A_diag_data[A_diag_i[i]]);
                }
              }
            }
            hypre_Free((char*)tmp_data), tmp_data = (void*)0;
          }
          else {
            for (i = n - 1; i > (-1); i--) {
              if ((A_diag_data[A_diag_i[i]]) != zero) {
                res = f_data[i];
                for (jj = (A_diag_i[i]) + 1; jj < (A_diag_i[i + 1]); jj++) {
                  ii = A_diag_j[jj];
                  res -= ((A_diag_data[jj]) * (u_data[ii]));
                }
                for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
                  ii = A_offd_j[jj];
                  res -= ((A_offd_data[jj]) * (Vext_data[ii]));
                }
                u_data[i] = res / (A_diag_data[A_diag_i[i]]);
              }
            }
          }
        }
        else {
          if (num_threads > 1) {
            tmp_data = (double*)(hypre_CAlloc((unsigned)n, (unsigned)(sizeof(double))));
            for (i = 0; i < n; i++)
              tmp_data[i] = u_data[i];
            for (j = 0; j < num_threads; j++) {
              size = n / num_threads;
              rest = n - (size * num_threads);
              if (j < rest) {
                ns = (j * size) + j;
                ne = (((j + 1) * size) + j) + 1;
              }
              else {
                ns = (j * size) + rest;
                ne = ((j + 1) * size) + rest;
              }
              for (i = ne - 1; i > (ns - 1); i--) {
                if (((cf_marker[i]) == relax_points) && ((A_diag_data[A_diag_i[i]]) != zero)) {
                  res = f_data[i];
                  for (jj = (A_diag_i[i]) + 1; jj < (A_diag_i[i + 1]); jj++) {
                    ii = A_diag_j[jj];
                    if ((ii >= ns) && (ii < ne))
                      res -= ((A_diag_data[jj]) * (u_data[ii]));
                    else
                      res -= ((A_diag_data[jj]) * (tmp_data[ii]));
                  }
                  for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
                    ii = A_offd_j[jj];
                    res -= ((A_offd_data[jj]) * (Vext_data[ii]));
                  }
                  u_data[i] = res / (A_diag_data[A_diag_i[i]]);
                }
              }
            }
            hypre_Free((char*)tmp_data), tmp_data = (void*)0;
          }
          else {
            for (i = n - 1; i > (-1); i--) {
              if (((cf_marker[i]) == relax_points) && ((A_diag_data[A_diag_i[i]]) != zero)) {
                res = f_data[i];
                for (jj = (A_diag_i[i]) + 1; jj < (A_diag_i[i + 1]); jj++) {
                  ii = A_diag_j[jj];
                  res -= ((A_diag_data[jj]) * (u_data[ii]));
                }
                for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
                  ii = A_offd_j[jj];
                  res -= ((A_offd_data[jj]) * (Vext_data[ii]));
                }
                u_data[i] = res / (A_diag_data[A_diag_i[i]]);
              }
            }
          }
        }
      }
      else {
        for (i = 0; i < n; i++) {
          Vtemp_data[i] = u_data[i];
        }
        prod = 1.0 - (relax_weight * omega);
        if (relax_points == 0) {
          if (num_threads > 1) {
            tmp_data = (double*)(hypre_CAlloc((unsigned)n, (unsigned)(sizeof(double))));
            for (i = 0; i < n; i++)
              tmp_data[i] = u_data[i];
            for (j = 0; j < num_threads; j++) {
              size = n / num_threads;
              rest = n - (size * num_threads);
              if (j < rest) {
                ns = (j * size) + j;
                ne = (((j + 1) * size) + j) + 1;
              }
              else {
                ns = (j * size) + rest;
                ne = ((j + 1) * size) + rest;
              }
              for (i = ne - 1; i > (ns - 1); i--) {
                if ((A_diag_data[A_diag_i[i]]) != zero) {
                  res = f_data[i];
                  res0 = 0.0;
                  res2 = 0.0;
                  for (jj = (A_diag_i[i]) + 1; jj < (A_diag_i[i + 1]); jj++) {
                    ii = A_diag_j[jj];
                    if ((ii >= ns) && (ii < ne)) {
                      res0 -= ((A_diag_data[jj]) * (u_data[ii]));
                      res2 += (A_diag_data[jj]) * (Vtemp_data[ii]);
                    }
                    else
                      res -= ((A_diag_data[jj]) * (tmp_data[ii]));
                  }
                  for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
                    ii = A_offd_j[jj];
                    res -= ((A_offd_data[jj]) * (Vext_data[ii]));
                  }
                  (u_data[i]) -= prod;
                  u_data[i] += (relax_weight * (((omega * res) + res0) + (one_minus_omega * res2))) / (A_diag_data[A_diag_i[i]]);
                }
              }
            }
            hypre_Free((char*)tmp_data), tmp_data = (void*)0;
          }
          else {
            for (i = n - 1; i > (-1); i--) {
              if ((A_diag_data[A_diag_i[i]]) != zero) {
                res0 = 0.0;
                res2 = 0.0;
                res = f_data[i];
                for (jj = (A_diag_i[i]) + 1; jj < (A_diag_i[i + 1]); jj++) {
                  ii = A_diag_j[jj];
                  res0 -= ((A_diag_data[jj]) * (u_data[ii]));
                  res2 += (A_diag_data[jj]) * (Vtemp_data[ii]);
                }
                for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
                  ii = A_offd_j[jj];
                  res -= ((A_offd_data[jj]) * (Vext_data[ii]));
                }
                (u_data[i]) -= prod;
                u_data[i] += (relax_weight * (((omega * res) + res0) + (one_minus_omega * res2))) / (A_diag_data[A_diag_i[i]]);
              }
            }
          }
        }
        else {
          if (num_threads > 1) {
            tmp_data = (double*)(hypre_CAlloc((unsigned)n, (unsigned)(sizeof(double))));
            for (i = 0; i < n; i++)
              tmp_data[i] = u_data[i];
            for (j = 0; j < num_threads; j++) {
              size = n / num_threads;
              rest = n - (size * num_threads);
              if (j < rest) {
                ns = (j * size) + j;
                ne = (((j + 1) * size) + j) + 1;
              }
              else {
                ns = (j * size) + rest;
                ne = ((j + 1) * size) + rest;
              }
              for (i = ne - 1; i > (ns - 1); i--) {
                if (((cf_marker[i]) == relax_points) && ((A_diag_data[A_diag_i[i]]) != zero)) {
                  res0 = 0.0;
                  res2 = 0.0;
                  res = f_data[i];
                  for (jj = (A_diag_i[i]) + 1; jj < (A_diag_i[i + 1]); jj++) {
                    ii = A_diag_j[jj];
                    if ((ii >= ns) && (ii < ne)) {
                      res0 -= ((A_diag_data[jj]) * (u_data[ii]));
                      res2 += (A_diag_data[jj]) * (Vtemp_data[ii]);
                    }
                    else
                      res -= ((A_diag_data[jj]) * (tmp_data[ii]));
                  }
                  for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
                    ii = A_offd_j[jj];
                    res -= ((A_offd_data[jj]) * (Vext_data[ii]));
                  }
                  (u_data[i]) -= prod;
                  u_data[i] += (relax_weight * (((omega * res) + res0) + (one_minus_omega * res2))) / (A_diag_data[A_diag_i[i]]);
                }
              }
            }
            hypre_Free((char*)tmp_data), tmp_data = (void*)0;
          }
          else {
            for (i = n - 1; i > (-1); i--) {
              if (((cf_marker[i]) == relax_points) && ((A_diag_data[A_diag_i[i]]) != zero)) {
                res = f_data[i];
                res0 = 0.0;
                res2 = 0.0;
                for (jj = (A_diag_i[i]) + 1; jj < (A_diag_i[i + 1]); jj++) {
                  ii = A_diag_j[jj];
                  res0 -= ((A_diag_data[jj]) * (u_data[ii]));
                  res2 += (A_diag_data[jj]) * (Vtemp_data[ii]);
                }
                for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
                  ii = A_offd_j[jj];
                  res -= ((A_offd_data[jj]) * (Vext_data[ii]));
                }
                (u_data[i]) -= prod;
                u_data[i] += (relax_weight * (((omega * res) + res0) + (one_minus_omega * res2))) / (A_diag_data[A_diag_i[i]]);
              }
            }
          }
        }
      }
      if (num_procs > 1) {
        hypre_Free((char*)Vext_data), Vext_data = (void*)0;
        hypre_Free((char*)v_buf_data), v_buf_data = (void*)0;
      }
    }
      break;
    case 6:
{
      Ztemp_local = (Ztemp)->local_vector;
      Ztemp_data = (Ztemp_local)->data;
      if (num_procs > 1) {
        num_sends = (comm_pkg)->num_sends;
        v_buf_data = (double*)(hypre_CAlloc((unsigned)((comm_pkg)->send_map_starts[num_sends]), (unsigned)(sizeof(double))));
        Vext_data = (double*)(hypre_CAlloc((unsigned)num_cols_offd, (unsigned)(sizeof(double))));
        if (num_cols_offd) {
          A_offd_j = (A_offd)->j;
          A_offd_data = (A_offd)->data;
        }
        index = 0;
        for (i = 0; i < num_sends; i++) {
          start = (comm_pkg)->send_map_starts[i];
          for (j = start; j < ((comm_pkg)->send_map_starts[i + 1]); j++)
            v_buf_data[index++] = u_data[(comm_pkg)->send_map_elmts[j]];
        }
        comm_handle = hypre_ParCSRCommHandleCreate(1, comm_pkg, v_buf_data, Vext_data);
        hypre_ParCSRCommHandleDestroy(comm_handle);
        comm_handle = (void*)0;
      }
      if ((relax_weight == 1) && (omega == 1)) {
        if (relax_points == 0) {
          if (num_threads > 1) {
            tmp_data = Ztemp_data;
            for (i = 0; i < n; i++)
              tmp_data[i] = u_data[i];
            for (j = 0; j < num_threads; j++) {
              size = n / num_threads;
              rest = n - (size * num_threads);
              if (j < rest) {
                ns = (j * size) + j;
                ne = (((j + 1) * size) + j) + 1;
              }
              else {
                ns = (j * size) + rest;
                ne = ((j + 1) * size) + rest;
              }
              for (i = ns; i < ne; i++) {
                if ((A_diag_data[A_diag_i[i]]) != zero) {
                  res = f_data[i];
                  for (jj = (A_diag_i[i]) + 1; jj < (A_diag_i[i + 1]); jj++) {
                    ii = A_diag_j[jj];
                    if ((ii >= ns) && (ii < ne)) {
                      res -= ((A_diag_data[jj]) * (u_data[ii]));
                    }
                    else
                      res -= ((A_diag_data[jj]) * (tmp_data[ii]));
                  }
                  for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
                    ii = A_offd_j[jj];
                    res -= ((A_offd_data[jj]) * (Vext_data[ii]));
                  }
                  u_data[i] = res / (A_diag_data[A_diag_i[i]]);
                }
              }
              for (i = ne - 1; i > (ns - 1); i--) {
                if ((A_diag_data[A_diag_i[i]]) != zero) {
                  res = f_data[i];
                  for (jj = (A_diag_i[i]) + 1; jj < (A_diag_i[i + 1]); jj++) {
                    ii = A_diag_j[jj];
                    if ((ii >= ns) && (ii < ne)) {
                      res -= ((A_diag_data[jj]) * (u_data[ii]));
                    }
                    else
                      res -= ((A_diag_data[jj]) * (tmp_data[ii]));
                  }
                  for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
                    ii = A_offd_j[jj];
                    res -= ((A_offd_data[jj]) * (Vext_data[ii]));
                  }
                  u_data[i] = res / (A_diag_data[A_diag_i[i]]);
                }
              }
            }
          }
          else {
            for (i = 0; i < n; i++) {
              if ((A_diag_data[A_diag_i[i]]) != zero) {
                res = f_data[i];
                for (jj = (A_diag_i[i]) + 1; jj < (A_diag_i[i + 1]); jj++) {
                  ii = A_diag_j[jj];
                  res -= ((A_diag_data[jj]) * (u_data[ii]));
                }
                for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
                  ii = A_offd_j[jj];
                  res -= ((A_offd_data[jj]) * (Vext_data[ii]));
                }
                u_data[i] = res / (A_diag_data[A_diag_i[i]]);
              }
            }
            for (i = n - 1; i > (-1); i--) {
              if ((A_diag_data[A_diag_i[i]]) != zero) {
                res = f_data[i];
                for (jj = (A_diag_i[i]) + 1; jj < (A_diag_i[i + 1]); jj++) {
                  ii = A_diag_j[jj];
                  res -= ((A_diag_data[jj]) * (u_data[ii]));
                }
                for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
                  ii = A_offd_j[jj];
                  res -= ((A_offd_data[jj]) * (Vext_data[ii]));
                }
                u_data[i] = res / (A_diag_data[A_diag_i[i]]);
              }
            }
          }
        }
        else {
          if (num_threads > 1) {
            tmp_data = Ztemp_data;
            for (i = 0; i < n; i++)
              tmp_data[i] = u_data[i];
            for (j = 0; j < num_threads; j++) {
              size = n / num_threads;
              rest = n - (size * num_threads);
              if (j < rest) {
                ns = (j * size) + j;
                ne = (((j + 1) * size) + j) + 1;
              }
              else {
                ns = (j * size) + rest;
                ne = ((j + 1) * size) + rest;
              }
              for (i = ns; i < ne; i++) {
                if (((cf_marker[i]) == relax_points) && ((A_diag_data[A_diag_i[i]]) != zero)) {
                  res = f_data[i];
                  for (jj = (A_diag_i[i]) + 1; jj < (A_diag_i[i + 1]); jj++) {
                    ii = A_diag_j[jj];
                    if ((ii >= ns) && (ii < ne)) {
                      res -= ((A_diag_data[jj]) * (u_data[ii]));
                    }
                    else
                      res -= ((A_diag_data[jj]) * (tmp_data[ii]));
                  }
                  for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
                    ii = A_offd_j[jj];
                    res -= ((A_offd_data[jj]) * (Vext_data[ii]));
                  }
                  u_data[i] = res / (A_diag_data[A_diag_i[i]]);
                }
              }
              for (i = ne - 1; i > (ns - 1); i--) {
                if (((cf_marker[i]) == relax_points) && ((A_diag_data[A_diag_i[i]]) != zero)) {
                  res = f_data[i];
                  for (jj = (A_diag_i[i]) + 1; jj < (A_diag_i[i + 1]); jj++) {
                    ii = A_diag_j[jj];
                    if ((ii >= ns) && (ii < ne)) {
                      res -= ((A_diag_data[jj]) * (u_data[ii]));
                    }
                    else
                      res -= ((A_diag_data[jj]) * (tmp_data[ii]));
                  }
                  for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
                    ii = A_offd_j[jj];
                    res -= ((A_offd_data[jj]) * (Vext_data[ii]));
                  }
                  u_data[i] = res / (A_diag_data[A_diag_i[i]]);
                }
              }
            }
          }
          else {
            for (i = 0; i < n; i++) {
              if (((cf_marker[i]) == relax_points) && ((A_diag_data[A_diag_i[i]]) != zero)) {
                res = f_data[i];
                for (jj = (A_diag_i[i]) + 1; jj < (A_diag_i[i + 1]); jj++) {
                  ii = A_diag_j[jj];
                  res -= ((A_diag_data[jj]) * (u_data[ii]));
                }
                for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
                  ii = A_offd_j[jj];
                  res -= ((A_offd_data[jj]) * (Vext_data[ii]));
                }
                u_data[i] = res / (A_diag_data[A_diag_i[i]]);
              }
            }
            for (i = n - 1; i > (-1); i--) {
              if (((cf_marker[i]) == relax_points) && ((A_diag_data[A_diag_i[i]]) != zero)) {
                res = f_data[i];
                for (jj = (A_diag_i[i]) + 1; jj < (A_diag_i[i + 1]); jj++) {
                  ii = A_diag_j[jj];
                  res -= ((A_diag_data[jj]) * (u_data[ii]));
                }
                for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
                  ii = A_offd_j[jj];
                  res -= ((A_offd_data[jj]) * (Vext_data[ii]));
                }
                u_data[i] = res / (A_diag_data[A_diag_i[i]]);
              }
            }
          }
        }
      }
      else {
        for (i = 0; i < n; i++) {
          Vtemp_data[i] = u_data[i];
        }
        prod = 1.0 - (relax_weight * omega);
        if (relax_points == 0) {
          if (num_threads > 1) {
            tmp_data = Ztemp_data;
            for (i = 0; i < n; i++)
              tmp_data[i] = u_data[i];
            for (j = 0; j < num_threads; j++) {
              size = n / num_threads;
              rest = n - (size * num_threads);
              if (j < rest) {
                ns = (j * size) + j;
                ne = (((j + 1) * size) + j) + 1;
              }
              else {
                ns = (j * size) + rest;
                ne = ((j + 1) * size) + rest;
              }
              for (i = ns; i < ne; i++) {
                if ((A_diag_data[A_diag_i[i]]) != zero) {
                  res0 = 0.0;
                  res2 = 0.0;
                  res = f_data[i];
                  for (jj = (A_diag_i[i]) + 1; jj < (A_diag_i[i + 1]); jj++) {
                    ii = A_diag_j[jj];
                    if ((ii >= ns) && (ii < ne)) {
                      res0 -= ((A_diag_data[jj]) * (u_data[ii]));
                      res2 += (A_diag_data[jj]) * (Vtemp_data[ii]);
                    }
                    else
                      res -= ((A_diag_data[jj]) * (tmp_data[ii]));
                  }
                  for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
                    ii = A_offd_j[jj];
                    res -= ((A_offd_data[jj]) * (Vext_data[ii]));
                  }
                  (u_data[i]) -= prod;
                  u_data[i] += (relax_weight * (((omega * res) + res0) + (one_minus_omega * res2))) / (A_diag_data[A_diag_i[i]]);
                }
              }
              for (i = ne - 1; i > (ns - 1); i--) {
                if ((A_diag_data[A_diag_i[i]]) != zero) {
                  res0 = 0.0;
                  res2 = 0.0;
                  res = f_data[i];
                  for (jj = (A_diag_i[i]) + 1; jj < (A_diag_i[i + 1]); jj++) {
                    ii = A_diag_j[jj];
                    if ((ii >= ns) && (ii < ne)) {
                      res0 -= ((A_diag_data[jj]) * (u_data[ii]));
                      res2 += (A_diag_data[jj]) * (Vtemp_data[ii]);
                    }
                    else
                      res -= ((A_diag_data[jj]) * (tmp_data[ii]));
                  }
                  for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
                    ii = A_offd_j[jj];
                    res -= ((A_offd_data[jj]) * (Vext_data[ii]));
                  }
                  (u_data[i]) -= prod;
                  u_data[i] += (relax_weight * (((omega * res) + res0) + (one_minus_omega * res2))) / (A_diag_data[A_diag_i[i]]);
                }
              }
            }
          }
          else {
            for (i = 0; i < n; i++) {
              if ((A_diag_data[A_diag_i[i]]) != zero) {
                res0 = 0.0;
                res = f_data[i];
                res2 = 0.0;
                for (jj = (A_diag_i[i]) + 1; jj < (A_diag_i[i + 1]); jj++) {
                  ii = A_diag_j[jj];
                  res0 -= ((A_diag_data[jj]) * (u_data[ii]));
                  res2 += (A_diag_data[jj]) * (Vtemp_data[ii]);
                }
                for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
                  ii = A_offd_j[jj];
                  res -= ((A_offd_data[jj]) * (Vext_data[ii]));
                }
                (u_data[i]) -= prod;
                u_data[i] += (relax_weight * (((omega * res) + res0) + (one_minus_omega * res2))) / (A_diag_data[A_diag_i[i]]);
              }
            }
            for (i = n - 1; i > (-1); i--) {
              if ((A_diag_data[A_diag_i[i]]) != zero) {
                res0 = 0.0;
                res = f_data[i];
                res2 = 0.0;
                for (jj = (A_diag_i[i]) + 1; jj < (A_diag_i[i + 1]); jj++) {
                  ii = A_diag_j[jj];
                  res0 -= ((A_diag_data[jj]) * (u_data[ii]));
                  res2 += (A_diag_data[jj]) * (Vtemp_data[ii]);
                }
                for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
                  ii = A_offd_j[jj];
                  res -= ((A_offd_data[jj]) * (Vext_data[ii]));
                }
                (u_data[i]) -= prod;
                u_data[i] += (relax_weight * (((omega * res) + res0) + (one_minus_omega * res2))) / (A_diag_data[A_diag_i[i]]);
              }
            }
          }
        }
        else {
          if (num_threads > 1) {
            tmp_data = Ztemp_data;
            for (i = 0; i < n; i++)
              tmp_data[i] = u_data[i];
            for (j = 0; j < num_threads; j++) {
              size = n / num_threads;
              rest = n - (size * num_threads);
              if (j < rest) {
                ns = (j * size) + j;
                ne = (((j + 1) * size) + j) + 1;
              }
              else {
                ns = (j * size) + rest;
                ne = ((j + 1) * size) + rest;
              }
              for (i = ns; i < ne; i++) {
                if (((cf_marker[i]) == relax_points) && ((A_diag_data[A_diag_i[i]]) != zero)) {
                  res0 = 0.0;
                  res2 = 0.0;
                  res = f_data[i];
                  for (jj = (A_diag_i[i]) + 1; jj < (A_diag_i[i + 1]); jj++) {
                    ii = A_diag_j[jj];
                    if ((ii >= ns) && (ii < ne)) {
                      res2 += (A_diag_data[jj]) * (Vtemp_data[ii]);
                      res0 -= ((A_diag_data[jj]) * (u_data[ii]));
                    }
                    else
                      res -= ((A_diag_data[jj]) * (tmp_data[ii]));
                  }
                  for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
                    ii = A_offd_j[jj];
                    res -= ((A_offd_data[jj]) * (Vext_data[ii]));
                  }
                  (u_data[i]) -= prod;
                  u_data[i] += (relax_weight * (((omega * res) + res0) + (one_minus_omega * res2))) / (A_diag_data[A_diag_i[i]]);
                }
              }
              for (i = ne - 1; i > (ns - 1); i--) {
                if (((cf_marker[i]) == relax_points) && ((A_diag_data[A_diag_i[i]]) != zero)) {
                  res0 = 0.0;
                  res2 = 0.0;
                  res = f_data[i];
                  for (jj = (A_diag_i[i]) + 1; jj < (A_diag_i[i + 1]); jj++) {
                    ii = A_diag_j[jj];
                    if ((ii >= ns) && (ii < ne)) {
                      res2 += (A_diag_data[jj]) * (Vtemp_data[ii]);
                      res0 -= ((A_diag_data[jj]) * (u_data[ii]));
                    }
                    else
                      res -= ((A_diag_data[jj]) * (tmp_data[ii]));
                  }
                  for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
                    ii = A_offd_j[jj];
                    res -= ((A_offd_data[jj]) * (Vext_data[ii]));
                  }
                  (u_data[i]) -= prod;
                  u_data[i] += (relax_weight * (((omega * res) + res0) + (one_minus_omega * res2))) / (A_diag_data[A_diag_i[i]]);
                }
              }
            }
          }
          else {
            for (i = 0; i < n; i++) {
              if (((cf_marker[i]) == relax_points) && ((A_diag_data[A_diag_i[i]]) != zero)) {
                res = f_data[i];
                res0 = 0.0;
                res2 = 0.0;
                for (jj = (A_diag_i[i]) + 1; jj < (A_diag_i[i + 1]); jj++) {
                  ii = A_diag_j[jj];
                  res0 -= ((A_diag_data[jj]) * (u_data[ii]));
                  res2 += (A_diag_data[jj]) * (Vtemp_data[ii]);
                }
                for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
                  ii = A_offd_j[jj];
                  res -= ((A_offd_data[jj]) * (Vext_data[ii]));
                }
                (u_data[i]) -= prod;
                u_data[i] += (relax_weight * (((omega * res) + res0) + (one_minus_omega * res2))) / (A_diag_data[A_diag_i[i]]);
              }
            }
            for (i = n - 1; i > (-1); i--) {
              if (((cf_marker[i]) == relax_points) && ((A_diag_data[A_diag_i[i]]) != zero)) {
                res = f_data[i];
                res0 = 0.0;
                res2 = 0.0;
                for (jj = (A_diag_i[i]) + 1; jj < (A_diag_i[i + 1]); jj++) {
                  ii = A_diag_j[jj];
                  res0 -= ((A_diag_data[jj]) * (u_data[ii]));
                  res2 += (A_diag_data[jj]) * (Vtemp_data[ii]);
                }
                for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
                  ii = A_offd_j[jj];
                  res -= ((A_offd_data[jj]) * (Vext_data[ii]));
                }
                (u_data[i]) -= prod;
                u_data[i] += (relax_weight * (((omega * res) + res0) + (one_minus_omega * res2))) / (A_diag_data[A_diag_i[i]]);
              }
            }
          }
        }
      }
      if (num_procs > 1) {
        hypre_Free((char*)Vext_data), Vext_data = (void*)0;
        hypre_Free((char*)v_buf_data), v_buf_data = (void*)0;
      }
    }
      break;
    case 7:
{
      hypre_ParVectorCopy(f, Vtemp);
      hypre_ParCSRMatrixMatvec(-1.0, A, u, 1.0, Vtemp);
      for (i = 0; i < n; i++) {
        if ((A_diag_data[A_diag_i[i]]) != zero) {
          u_data[i] += (relax_weight * (Vtemp_data[i])) / (A_diag_data[A_diag_i[i]]);
        }
      }
    }
      break;
    case 9:
{
      int n_global = (int)global_num_rows;
      if (n) {
        A_CSR = hypre_ParCSRMatrixToCSRMatrixAll(A);
        f_vector = hypre_ParVectorToVectorAll(f);
        A_CSR_i = (A_CSR)->i;
        A_CSR_j = (A_CSR)->j;
        A_CSR_data = (A_CSR)->data;
        f_vector_data = (f_vector)->data;
        A_mat = (double*)(hypre_CAlloc((unsigned)(n_global * n_global), (unsigned)(sizeof(double))));
        b_vec = (double*)(hypre_CAlloc((unsigned)n_global, (unsigned)(sizeof(double))));
        for (i = 0; i < n_global; i++) {
          for (jj = A_CSR_i[i]; jj < (A_CSR_i[i + 1]); jj++) {
            column = A_CSR_j[jj];
            A_mat[(i * n_global) + column] = A_CSR_data[jj];
          }
          b_vec[i] = f_vector_data[i];
        }
        relax_error = gselim(A_mat, b_vec, n_global);
        for (i = 0; i < n; i++) {
          u_data[i] = b_vec[first_index + i];
        }
        hypre_Free((char*)A_mat), A_mat = (void*)0;
        hypre_Free((char*)b_vec), b_vec = (void*)0;
        hypre_CSRMatrixDestroy(A_CSR);
        A_CSR = (void*)0;
        hypre_SeqVectorDestroy(f_vector);
        f_vector = (void*)0;
      }
    }
      break;
  }
  return relax_error;
}
int gselim(double* A, double* x, int n) {
  int err_flag = 0;
  int j;
  int k;
  int m;
  double factor;
  if (n == 1) {
    if ((A[0]) != 0.0) {
      x[0] = (x[0]) / (A[0]);
      return err_flag;
    }
    else {
      err_flag = 1;
      return err_flag;
    }
  }
  else {
    for (k = 0; k < (n - 1); k++) {
      if ((A[(k * n) + k]) != 0.0) {
        for (j = k + 1; j < n; j++) {
          if ((A[(j * n) + k]) != 0.0) {
            factor = (A[(j * n) + k]) / (A[(k * n) + k]);
            for (m = k + 1; m < n; m++) {
              (A[(j * n) + m]) -= (factor * (A[(k * n) + m]));
            }
            (x[j]) -= (factor * (x[k]));
          }
        }
      }
    }
    for (k = n - 1; k > 0; --k) {
      (x[k]) /= (A[(k * n) + k]);
      for (j = 0; j < k; j++) {
        if ((A[(j * n) + k]) != 0.0) {
          (x[j]) -= ((x[k]) * (A[(j * n) + k]));
        }
      }
    }
    (x[0]) /= (A[0]);
    return err_flag;
  }
}
//================== par_relax_interface.c =================
int hypre_BoomerAMGRelaxIF(hypre_ParCSRMatrix* A, hypre_ParVector* f, int* cf_marker, int relax_type, int relax_order, int cycle_type, double relax_weight, double omega, double* l1_norms, hypre_ParVector* u, hypre_ParVector* Vtemp, hypre_ParVector* Ztemp) {
  int i;
  int Solve_err_flag = 0;
  int  relax_points[2];
  if ((relax_order == 1) && (cycle_type < 3)) {
    if (cycle_type < 2) {
      relax_points[0] = 1;
      relax_points[1] = -1;
    }
    else {
      relax_points[0] = -1;
      relax_points[1] = 1;
    }
    {
      for (i = 0; i < 2; i++)
        Solve_err_flag = hypre_BoomerAMGRelax(A, f, cf_marker, relax_type, relax_points[i], relax_weight, omega, l1_norms, u, Vtemp, Ztemp);
    }
  }
  else {
    Solve_err_flag = hypre_BoomerAMGRelax(A, f, cf_marker, relax_type, 0, relax_weight, omega, l1_norms, u, Vtemp, Ztemp);
  }
  return Solve_err_flag;
}
//==================== par_relax_more.c ====================
int hypre_LINPACKcgtql1(int*, double*, double*, int*);
int hypre_ParCSRMaxEigEstimateCG(hypre_ParCSRMatrix* A, int scale, int max_iter, double* max_eig, double* min_eig) {
  int i;
  int j;
  int err;
  hypre_ParVector* p;
  hypre_ParVector* s;
  hypre_ParVector* r;
  hypre_ParVector* ds;
  hypre_ParVector* u;
  double* tridiag;
  double* trioffd;
  double lambda_max;
  double max_row_sum;
  double beta;
  double gamma = 0.0;
  double alpha;
  double sdotp;
  double gamma_old;
  double alphainv;
  double diag;
  double lambda_min;
  double* s_data;
  double* p_data;
  double* ds_data;
  double* u_data;
  int local_size = ((A)->diag)->num_rows;
  hypre_CSRMatrix* A_diag = (A)->diag;
  double* A_diag_data = (A_diag)->data;
  int* A_diag_i = (A_diag)->i;
  int size = (A)->global_num_rows;
  if (size < (int)max_iter)
    max_iter = (int)size;
  r = hypre_ParVectorCreate((A)->comm, (A)->global_num_rows, (A)->row_starts);
  hypre_ParVectorInitialize(r);
  hypre_ParVectorSetPartitioningOwner(r, 0);
  p = hypre_ParVectorCreate((A)->comm, (A)->global_num_rows, (A)->row_starts);
  hypre_ParVectorInitialize(p);
  hypre_ParVectorSetPartitioningOwner(p, 0);
  s = hypre_ParVectorCreate((A)->comm, (A)->global_num_rows, (A)->row_starts);
  hypre_ParVectorInitialize(s);
  hypre_ParVectorSetPartitioningOwner(s, 0);
  ds = hypre_ParVectorCreate((A)->comm, (A)->global_num_rows, (A)->row_starts);
  hypre_ParVectorInitialize(ds);
  hypre_ParVectorSetPartitioningOwner(ds, 0);
  u = hypre_ParVectorCreate((A)->comm, (A)->global_num_rows, (A)->row_starts);
  hypre_ParVectorInitialize(u);
  hypre_ParVectorSetPartitioningOwner(u, 0);
  s_data = ((s)->local_vector)->data;
  p_data = ((p)->local_vector)->data;
  ds_data = ((ds)->local_vector)->data;
  u_data = ((u)->local_vector)->data;
  tridiag = (double*)(hypre_CAlloc((unsigned)(max_iter + 1), (unsigned)(sizeof(double))));
  trioffd = (double*)(hypre_CAlloc((unsigned)(max_iter + 1), (unsigned)(sizeof(double))));
  for (i = 0; i < (max_iter + 1); i++) {
    tridiag[i] = 0;
    trioffd[i] = 0;
  }
  hypre_ParVectorSetRandomValues(r, 1);
  if (scale) {
    for (i = 0; i < local_size; i++) {
      diag = A_diag_data[A_diag_i[i]];
      ds_data[i] = 1 / sqrt(diag);
    }
  }
  else {
    hypre_ParVectorSetConstantValues(ds, 1.0);
  }
  gamma = hypre_ParVectorInnerProd(r, p);
  beta = 1.0;
  max_row_sum = 0.0;
  i = 0;
  while (i < max_iter) {
    hypre_ParVectorCopy(r, s);
    gamma_old = gamma;
    gamma = hypre_ParVectorInnerProd(r, s);
    if (i == 0) {
      beta = 1.0;
      hypre_ParVectorCopy(s, p);
    }
    else {
      beta = gamma / gamma_old;
      for (j = 0; j < local_size; j++) {
        p_data[j] = (s_data[j]) + (beta * (p_data[j]));
      }
    }
    if (scale) {
      for (j = 0; j < local_size; j++) {
        u_data[j] = (ds_data[j]) * (p_data[j]);
      }
      hypre_ParCSRMatrixMatvec(1.0, A, u, 0.0, s);
      for (j = 0; j < local_size; j++) {
        s_data[j] = (ds_data[j]) * (s_data[j]);
      }
    }
    else {
      hypre_ParCSRMatrixMatvec(1.0, A, p, 0.0, s);
    }
    sdotp = hypre_ParVectorInnerProd(s, p);
    alpha = gamma / sdotp;
    alphainv = 1.0 / alpha;
    tridiag[i + 1] = alphainv;
    (tridiag[i]) -= beta;
    tridiag[i] += alphainv;
    trioffd[i + 1] = alphainv;
    (trioffd[i]) -= sqrt(beta);
    hypre_ParVectorAxpy(-alpha, s, r);
    i++;
  }
  hypre_LINPACKcgtql1(&(i), tridiag, trioffd, &(err));
  lambda_max = tridiag[i - 1];
  lambda_min = tridiag[0];
  hypre_ParVectorDestroy(r);
  hypre_ParVectorDestroy(s);
  hypre_ParVectorDestroy(p);
  hypre_ParVectorDestroy(ds);
  hypre_ParVectorDestroy(u);
  *max_eig = lambda_max;
  *min_eig = lambda_min;
  return hypre__global_error;
}
int hypre_ParCSRRelax_Cheby(hypre_ParCSRMatrix* A, hypre_ParVector* f, double max_eig, double min_eig, double eig_ratio, int order, int scale, int variant, hypre_ParVector* u, hypre_ParVector* v, hypre_ParVector* r) {
  hypre_CSRMatrix* A_diag = (A)->diag;
  double* A_diag_data = (A_diag)->data;
  int* A_diag_i = (A_diag)->i;
  double* u_data = ((u)->local_vector)->data;
  double* f_data = ((f)->local_vector)->data;
  double* v_data = ((v)->local_vector)->data;
  double* r_data = ((r)->local_vector)->data;
  double theta;
  double delta;
  double den;
  double upper_bound;
  double lower_bound;
  int i;
  int j;
  int num_rows = (A_diag)->num_rows;
  double  coefs[5];
  double mult;
  double* orig_u;
  double tmp_d;
  int cheby_order;
  double* ds_data;
  double* tmp_data;
  double diag;
  hypre_ParVector* ds;
  hypre_ParVector* tmp_vec;
  if (order > 4)
    order = 4;
  if (order < 1)
    order = 1;
  cheby_order = order - 1;
  upper_bound = max_eig * 1.1;
  lower_bound = ((upper_bound - min_eig) * eig_ratio) + min_eig;
  theta = (upper_bound + lower_bound) / 2;
  delta = (upper_bound - lower_bound) / 2;
  if (variant == 1) {
    switch (cheby_order) {
      case 0:
        coefs[0] = 1.0 / theta;
        break;
      case 1:
        den = (theta * theta) + (delta * theta);
        coefs[0] = (delta + (2 * theta)) / den;
        coefs[1] = (-1.0) / den;
        break;
      case 2:
        den = (((((2 * delta) * theta) * theta) - ((delta * delta) * theta)) - pow(delta, 3)) + (2 * pow(theta, 3));
        coefs[0] = ((((4 * delta) * theta) - pow(delta, 2)) + (6 * pow(theta, 2))) / den;
        coefs[1] = (-((2 * delta) + (6 * theta))) / den;
        coefs[2] = 2 / den;
        break;
      case 3:
        den = -(((((4 * delta) * pow(theta, 3)) - ((3 * pow(delta, 2)) * pow(theta, 2))) - ((3 * pow(delta, 3)) * theta)) + (4 * pow(theta, 4)));
        coefs[0] = (((((6 * pow(delta, 2)) * theta) - ((12 * delta) * pow(theta, 2))) + (3 * pow(delta, 3))) - (16 * pow(theta, 3))) / den;
        coefs[1] = ((((12 * delta) * theta) - (3 * pow(delta, 2))) + (24 * pow(theta, 2))) / den;
        coefs[2] = (-((4 * delta) + (16 * theta))) / den;
        coefs[3] = 4 / den;
        break;
    }
  }
  else {
    switch (cheby_order) {
      case 0:
        coefs[0] = 1.0 / theta;
        break;
      case 1:
        den = (delta * delta) - ((2 * theta) * theta);
        coefs[0] = ((-4) * theta) / den;
        coefs[1] = 2 / den;
        break;
      case 2:
        den = ((3 * (delta * delta)) * theta) - (4 * ((theta * theta) * theta));
        coefs[0] = (((3 * delta) * delta) - ((12 * theta) * theta)) / den;
        coefs[1] = (12 * theta) / den;
        coefs[2] = (-4) / den;
        break;
      case 3:
        den = (pow(delta, 4) - ((((8 * delta) * delta) * theta) * theta)) + (8 * pow(theta, 4));
        coefs[0] = ((32 * pow(theta, 3)) - (((16 * delta) * delta) * theta)) / den;
        coefs[1] = (((8 * delta) * delta) - ((48 * theta) * theta)) / den;
        coefs[2] = (32 * theta) / den;
        coefs[3] = (-8) / den;
        break;
    }
  }
  orig_u = (double*)(hypre_CAlloc((unsigned)num_rows, (unsigned)(sizeof(double))));
  if (!scale) {
    hypre_ParVectorCopy(f, r);
    hypre_ParCSRMatrixMatvec(-1.0, A, u, 1.0, r);
    for (i = 0; i < num_rows; i++) {
      orig_u[i] = u_data[i];
      u_data[i] = (r_data[i]) * (coefs[cheby_order]);
    }
    for (i = cheby_order - 1; i >= 0; i--) {
      hypre_ParCSRMatrixMatvec(1.0, A, u, 0.0, v);
      mult = coefs[i];
      for (j = 0; j < num_rows; j++) {
        u_data[j] = (mult * (r_data[j])) + (v_data[j]);
      }
    }
    for (i = 0; i < num_rows; i++) {
      u_data[i] = (orig_u[i]) + (u_data[i]);
    }
  }
  else {
    ds = hypre_ParVectorCreate((A)->comm, (A)->global_num_rows, (A)->row_starts);
    hypre_ParVectorInitialize(ds);
    hypre_ParVectorSetPartitioningOwner(ds, 0);
    ds_data = ((ds)->local_vector)->data;
    tmp_vec = hypre_ParVectorCreate((A)->comm, (A)->global_num_rows, (A)->row_starts);
    hypre_ParVectorInitialize(tmp_vec);
    hypre_ParVectorSetPartitioningOwner(tmp_vec, 0);
    tmp_data = ((tmp_vec)->local_vector)->data;
    for (j = 0; j < num_rows; j++) {
      diag = A_diag_data[A_diag_i[j]];
      ds_data[j] = 1 / sqrt(diag);
      r_data[j] = (ds_data[j]) * (f_data[j]);
    }
    hypre_ParCSRMatrixMatvec(-1.0, A, u, 0.0, tmp_vec);
    for (j = 0; j < num_rows; j++) {
      r_data[j] += (ds_data[j]) * (tmp_data[j]);
    }
    for (j = 0; j < num_rows; j++) {
      orig_u[j] = u_data[j];
      u_data[j] = (r_data[j]) * (coefs[cheby_order]);
    }
    for (i = cheby_order - 1; i >= 0; i--) {
      for (j = 0; j < num_rows; j++) {
        tmp_data[j] = (ds_data[j]) * (u_data[j]);
      }
      hypre_ParCSRMatrixMatvec(1.0, A, tmp_vec, 0.0, v);
      mult = coefs[i];
      for (j = 0; j < num_rows; j++) {
        tmp_d = (ds_data[j]) * (v_data[j]);
        u_data[j] = (mult * (r_data[j])) + tmp_d;
      }
    }
    for (j = 0; j < num_rows; j++) {
      u_data[j] = (orig_u[j]) + ((ds_data[j]) * (u_data[j]));
    }
    hypre_ParVectorDestroy(ds);
    hypre_ParVectorDestroy(tmp_vec);
  }
  hypre_Free((char*)orig_u), orig_u = (void*)0;
  return hypre__global_error;
}
int hypre_BoomerAMGRelax_FCFJacobi(hypre_ParCSRMatrix* A, hypre_ParVector* f, int* cf_marker, double relax_weight, hypre_ParVector* u, hypre_ParVector* Vtemp) {
  int i;
  int  relax_points[3];
  int relax_type = 0;
  hypre_ParVector* Ztemp = (void*)0;
  relax_points[0] = -1;
  relax_points[1] = 1;
  relax_points[2] = -1;
  if (cf_marker == (void*)0) {
    hypre_BoomerAMGRelax(A, f, cf_marker, relax_type, 0, relax_weight, 0.0, (void*)0, u, Vtemp, Ztemp);
  }
  else {
    for (i = 0; i < 3; i++)
      hypre_BoomerAMGRelax(A, f, cf_marker, relax_type, relax_points[i], relax_weight, 0.0, (void*)0, u, Vtemp, Ztemp);
  }
  return hypre__global_error;
}
int hypre_ParCSRRelax_CG(HYPRE_Solver solver, hypre_ParCSRMatrix* A, hypre_ParVector* f, hypre_ParVector* u, int num_its) {
  int num_iterations;
  double final_res_norm;
  HYPRE_PCGSetMaxIter(solver, num_its);
  HYPRE_ParCSRPCGSolve(solver, (HYPRE_ParCSRMatrix)A, (HYPRE_ParVector)f, (HYPRE_ParVector)u);
  HYPRE_PCGGetNumIterations(solver, &(num_iterations));
  HYPRE_PCGGetFinalRelativeResidualNorm(solver, &(final_res_norm));
  return hypre__global_error;
}
double hypre_LINPACKcgpthy(double*, double*);
int hypre_LINPACKcgtql1(int* n, double* d, double* e, int* ierr) {
  int i__1;
  int i__2;
  double d__1;
  double d__2;
  double c_b10 = 1.0;
  double c;
  double f;
  double g;
  double h;
  int i;
  int j;
  int l;
  int m;
  double p;
  double r;
  double s;
  double c2;
  double c3 = 0.0;
  int l1;
  int l2;
  double s2 = 0.0;
  int ii;
  double dl1;
  double el1;
  int mml;
  double tst1;
  double tst2;
  double ds;
  --e;
  --d;
  *ierr = 0;
  if ((*n) == 1) {
    goto L1001;
  }
  i__1 = *n;
  for (i = 2; i <= i__1; ++i) {
    e[i - 1] = e[i];
  }
  f = 0.;
  tst1 = 0.;
  e[*n] = 0.;
  i__1 = *n;
  for (l = 1; l <= i__1; ++l) {
    j = 0;
    h = (d__1 = d[l], fabs(d__1)) + (d__2 = e[l], fabs(d__2));
    if (tst1 < h) {
      tst1 = h;
    }
    i__2 = *n;
    for (m = l; m <= i__2; ++m) {
      tst2 = tst1 + (d__1 = e[m], fabs(d__1));
      if (tst2 == tst1) {
        goto L120;
      }
    }
    L120:
      if (m == l) {
        goto L210;
      }
    L130:
      if (j == 30) {
        goto L1000;
      }
    ++j;
    l1 = l + 1;
    l2 = l1 + 1;
    g = d[l];
    p = ((d[l1]) - g) / ((e[l]) * 2.);
    r = hypre_LINPACKcgpthy(&(p), &(c_b10));
    ds = 1.0;
    if (p < 0.0)
      ds = -1.0;
    d[l] = (e[l]) / (p + (ds * r));
    d[l1] = (e[l]) * (p + (ds * r));
    dl1 = d[l1];
    h = g - (d[l]);
    if (l2 > (*n)) {
      goto L145;
    }
    i__2 = *n;
    for (i = l2; i <= i__2; ++i) {
      (d[i]) -= h;
    }
    L145:
      f += h;
    p = d[m];
    c = 1.;
    c2 = c;
    el1 = e[l1];
    s = 0.;
    mml = m - l;
    i__2 = mml;
    for (ii = 1; ii <= i__2; ++ii) {
      c3 = c2;
      c2 = c;
      s2 = s;
      i = m - ii;
      g = c * (e[i]);
      h = c * p;
      r = hypre_LINPACKcgpthy(&(p), &(e[i]));
      e[i + 1] = s * r;
      s = (e[i]) / r;
      c = p / r;
      p = (c * (d[i])) - (s * g);
      d[i + 1] = h + (s * ((c * g) + (s * (d[i]))));
    }
    p = (((((-s) * s2) * c3) * el1) * (e[l])) / dl1;
    e[l] = s * p;
    d[l] = c * p;
    tst2 = tst1 + (d__1 = e[l], fabs(d__1));
    if (tst2 > tst1) {
      goto L130;
    }
    L210:
      p = (d[l]) + f;
    if (l == 1) {
      goto L250;
    }
    i__2 = l;
    for (ii = 2; ii <= i__2; ++ii) {
      i = (l + 2) - ii;
      if (p >= (d[i - 1])) {
        goto L270;
      }
      d[i] = d[i - 1];
    }
    L250:
      i = 1;
    L270:
      d[i] = p;
  }
  goto L1001;
  L1000:
    *ierr = l;
  L1001:
    return 0;
}
double hypre_LINPACKcgpthy(double* a, double* b) {
  double ret_val;
  double d__1;
  double d__2;
  double d__3;
  double p;
  double r;
  double s;
  double t;
  double u;
  d__1 = fabs(*a), d__2 = fabs(*b);
  p = d__1 < d__2 ? d__2 : d__1;
  if (!p) {
    goto L20;
  }
  d__2 = fabs(*a), d__3 = fabs(*b);
  d__1 = (d__2 < d__3 ? d__2 : d__3) / p;
  r = d__1 * d__1;
  L10:
    t = r + 4.;
  if (t == 4.) {
    goto L20;
  }
  s = r / t;
  u = (s * 2.) + 1.;
  p = u * p;
  d__1 = s / u;
  r = (d__1 * d__1) * r;
  goto L10;
  L20:
    ret_val = p;
  return ret_val;
}
int hypre_ParCSRComputeL1Norms(hypre_ParCSRMatrix* A, int option, int* cf_marker, double** l1_norm_ptr) {
  int i;
  int j;
  int num_rows = ((A)->diag)->num_rows;
  hypre_CSRMatrix* A_diag = (A)->diag;
  int* A_diag_I = (A_diag)->i;
  int* A_diag_J = (A_diag)->j;
  double* A_diag_data = (A_diag)->data;
  hypre_CSRMatrix* A_offd = (A)->offd;
  int* A_offd_I = (A_offd)->i;
  int* A_offd_J = (A_offd)->j;
  double* A_offd_data = (A_offd)->data;
  int num_cols_offd = (A_offd)->num_cols;
  double* l1_norm = (double*)(hypre_CAlloc((unsigned)num_rows, (unsigned)(sizeof(double))));
  int* cf_marker_offd = (void*)0;
  int cf_diag;
  double diag;
  if (cf_marker != (void*)0) {
    int index;
    int num_sends;
    int start;
    int* int_buf_data = (void*)0;
    hypre_ParCSRCommPkg* comm_pkg = (A)->comm_pkg;
    hypre_ParCSRCommHandle* comm_handle;
    if (num_cols_offd)
      cf_marker_offd = (int*)(hypre_CAlloc((unsigned)num_cols_offd, (unsigned)(sizeof(int))));
    num_sends = (comm_pkg)->num_sends;
    if ((comm_pkg)->send_map_starts[num_sends])
      int_buf_data = (int*)(hypre_CAlloc((unsigned)((comm_pkg)->send_map_starts[num_sends]), (unsigned)(sizeof(int))));
    index = 0;
    for (i = 0; i < num_sends; i++) {
      start = (comm_pkg)->send_map_starts[i];
      for (j = start; j < ((comm_pkg)->send_map_starts[i + 1]); j++) {
        int_buf_data[index++] = cf_marker[(comm_pkg)->send_map_elmts[j]];
      }
    }
    comm_handle = hypre_ParCSRCommHandleCreate(11, comm_pkg, int_buf_data, cf_marker_offd);
    hypre_ParCSRCommHandleDestroy(comm_handle);
    hypre_Free((char*)int_buf_data), int_buf_data = (void*)0;
  }
  if (option == 1) {
    for (i = 0; i < num_rows; i++) {
      l1_norm[i] = 0.0;
      if (cf_marker == (void*)0) {
        for (j = A_diag_I[i]; j < (A_diag_I[i + 1]); j++)
          l1_norm[i] += fabs(A_diag_data[j]);
        if (num_cols_offd) {
          for (j = A_offd_I[i]; j < (A_offd_I[i + 1]); j++)
            l1_norm[i] += fabs(A_offd_data[j]);
        }
      }
      else {
        cf_diag = cf_marker[i];
        for (j = A_diag_I[i]; j < (A_diag_I[i + 1]); j++)
          if (cf_diag == (cf_marker[A_diag_J[j]]))
            l1_norm[i] += fabs(A_diag_data[j]);
        if (num_cols_offd) {
          for (j = A_offd_I[i]; j < (A_offd_I[i + 1]); j++)
            if (cf_diag == (cf_marker_offd[A_offd_J[j]]))
              l1_norm[i] += fabs(A_offd_data[j]);
        }
      }
    }
  }
  else
    if (option == 2) {
      for (i = 0; i < num_rows; i++) {
        l1_norm[i] = fabs(A_diag_data[A_diag_I[i]]);
        if (cf_marker == (void*)0) {
          if (num_cols_offd) {
            for (j = A_offd_I[i]; j < (A_offd_I[i + 1]); j++)
              l1_norm[i] += fabs(A_offd_data[j]);
          }
        }
        else {
          cf_diag = cf_marker[i];
          if (num_cols_offd) {
            for (j = A_offd_I[i]; j < (A_offd_I[i + 1]); j++)
              if (cf_diag == (cf_marker_offd[A_offd_J[j]]))
                l1_norm[i] += fabs(A_offd_data[j]);
          }
        }
      }
    }
    else
      if (option == 3) {
        for (i = 0; i < num_rows; i++) {
          l1_norm[i] = 0.0;
          for (j = A_diag_I[i]; j < (A_diag_I[i + 1]); j++)
            l1_norm[i] += (A_diag_data[j]) * (A_diag_data[j]);
          if (num_cols_offd)
            for (j = A_offd_I[i]; j < (A_offd_I[i + 1]); j++)
              l1_norm[i] += (A_offd_data[j]) * (A_offd_data[j]);
        }
      }
      else
        if (option == 4) {
          for (i = 0; i < num_rows; i++) {
            diag = l1_norm[i] = fabs(A_diag_data[A_diag_I[i]]);
            if (cf_marker == (void*)0) {
              if (num_cols_offd) {
                for (j = A_offd_I[i]; j < (A_offd_I[i + 1]); j++)
                  l1_norm[i] += 0.5 * fabs(A_offd_data[j]);
              }
            }
            else {
              cf_diag = cf_marker[i];
              if (num_cols_offd) {
                for (j = A_offd_I[i]; j < (A_offd_I[i + 1]); j++)
                  if (cf_diag == (cf_marker_offd[A_offd_J[j]]))
                    l1_norm[i] += 0.5 * fabs(A_offd_data[j]);
              }
            }
            if ((l1_norm[i]) <= ((4.0 / 3.0) * diag))
              l1_norm[i] = diag;
          }
        }
  for (i = 0; i < num_rows; i++)
    if ((A_diag_data[A_diag_I[i]]) < 0)
      l1_norm[i] = -(l1_norm[i]);
  for (i = 0; i < num_rows; i++)
    if (fabs(l1_norm[i]) < 1e-9) {
      hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_relax_more.c", 908, 4 | (1 << 3));
      break;
    }
  hypre_Free((char*)cf_marker_offd), cf_marker_offd = (void*)0;
  *l1_norm_ptr = l1_norm;
  return hypre__global_error;
}
int hypre_ParCSRComputeL1NormsThreads(hypre_ParCSRMatrix* A, int option, int num_threads, int* cf_marker, double** l1_norm_ptr) {
  int i;
  int j;
  int k;
  int num_rows = ((A)->diag)->num_rows;
  hypre_CSRMatrix* A_diag = (A)->diag;
  int* A_diag_I = (A_diag)->i;
  int* A_diag_J = (A_diag)->j;
  double* A_diag_data = (A_diag)->data;
  hypre_CSRMatrix* A_offd = (A)->offd;
  int* A_offd_I = (A_offd)->i;
  int* A_offd_J = (A_offd)->j;
  double* A_offd_data = (A_offd)->data;
  int num_cols_offd = (A_offd)->num_cols;
  double* l1_norm = (double*)(hypre_CAlloc((unsigned)num_rows, (unsigned)(sizeof(double))));
  int ii;
  int ns;
  int ne;
  int rest;
  int size;
  int* cf_marker_offd = (void*)0;
  int cf_diag;
  double diag;
  if (cf_marker != (void*)0) {
    int index;
    int num_sends;
    int start;
    int* int_buf_data = (void*)0;
    hypre_ParCSRCommPkg* comm_pkg = (A)->comm_pkg;
    hypre_ParCSRCommHandle* comm_handle;
    if (num_cols_offd)
      cf_marker_offd = (int*)(hypre_CAlloc((unsigned)num_cols_offd, (unsigned)(sizeof(int))));
    num_sends = (comm_pkg)->num_sends;
    if ((comm_pkg)->send_map_starts[num_sends])
      int_buf_data = (int*)(hypre_CAlloc((unsigned)((comm_pkg)->send_map_starts[num_sends]), (unsigned)(sizeof(int))));
    index = 0;
    for (i = 0; i < num_sends; i++) {
      start = (comm_pkg)->send_map_starts[i];
      for (j = start; j < ((comm_pkg)->send_map_starts[i + 1]); j++) {
        int_buf_data[index++] = cf_marker[(comm_pkg)->send_map_elmts[j]];
      }
    }
    comm_handle = hypre_ParCSRCommHandleCreate(11, comm_pkg, int_buf_data, cf_marker_offd);
    hypre_ParCSRCommHandleDestroy(comm_handle);
    hypre_Free((char*)int_buf_data), int_buf_data = (void*)0;
  }
  for (k = 0; k < num_threads; k++) {
    size = num_rows / num_threads;
    rest = num_rows - (size * num_threads);
    if (k < rest) {
      ns = (k * size) + k;
      ne = (((k + 1) * size) + k) + 1;
    }
    else {
      ns = (k * size) + rest;
      ne = ((k + 1) * size) + rest;
    }
    if (option == 1) {
      for (i = ns; i < ne; i++) {
        l1_norm[i] = 0.0;
        if (cf_marker == (void*)0) {
          for (j = A_diag_I[i]; j < (A_diag_I[i + 1]); j++)
            l1_norm[i] += fabs(A_diag_data[j]);
          if (num_cols_offd) {
            for (j = A_offd_I[i]; j < (A_offd_I[i + 1]); j++)
              l1_norm[i] += fabs(A_offd_data[j]);
          }
        }
        else {
          cf_diag = cf_marker[i];
          for (j = A_diag_I[i]; j < (A_diag_I[i + 1]); j++)
            if (cf_diag == (cf_marker[A_diag_J[j]]))
              l1_norm[i] += fabs(A_diag_data[j]);
          if (num_cols_offd) {
            for (j = A_offd_I[i]; j < (A_offd_I[i + 1]); j++)
              if (cf_diag == (cf_marker_offd[A_offd_J[j]]))
                l1_norm[i] += fabs(A_offd_data[j]);
          }
        }
      }
    }
    else
      if (option == 2) {
        for (i = ns; i < ne; i++) {
          l1_norm[i] = 0.0;
          if (cf_marker == (void*)0) {
            for (j = A_diag_I[i]; j < (A_diag_I[i + 1]); j++) {
              ii = A_diag_J[j];
              if (((ii == i) || (ii < ns)) || (ii >= ne))
                l1_norm[i] += fabs(A_diag_data[j]);
            }
            if (num_cols_offd) {
              for (j = A_offd_I[i]; j < (A_offd_I[i + 1]); j++)
                l1_norm[i] += fabs(A_offd_data[j]);
            }
          }
          else {
            cf_diag = cf_marker[i];
            for (j = A_diag_I[i]; j < (A_diag_I[i + 1]); j++) {
              ii = A_diag_J[j];
              if ((((ii == i) || (ii < ns)) || (ii >= ne)) && (cf_diag == (cf_marker[A_diag_J[j]])))
                l1_norm[i] += fabs(A_diag_data[j]);
            }
            if (num_cols_offd) {
              for (j = A_offd_I[i]; j < (A_offd_I[i + 1]); j++)
                if (cf_diag == (cf_marker_offd[A_offd_J[j]]))
                  l1_norm[i] += fabs(A_offd_data[j]);
            }
          }
        }
      }
      else
        if (option == 3) {
          for (i = ns; i < ne; i++) {
            l1_norm[i] = 0.0;
            for (j = A_diag_I[i]; j < (A_diag_I[i + 1]); j++)
              l1_norm[i] += (A_diag_data[j]) * (A_diag_data[j]);
            if (num_cols_offd)
              for (j = A_offd_I[i]; j < (A_offd_I[i + 1]); j++)
                l1_norm[i] += (A_offd_data[j]) * (A_offd_data[j]);
          }
        }
        else
          if (option == 4) {
            for (i = ns; i < ne; i++) {
              l1_norm[i] = 0.0;
              if (cf_marker == (void*)0) {
                for (j = A_diag_I[i]; j < (A_diag_I[i + 1]); j++) {
                  ii = A_diag_J[j];
                  if (((ii == i) || (ii < ns)) || (ii >= ne)) {
                    if (ii == i) {
                      diag = fabs(A_diag_data[j]);
                      l1_norm[i] += fabs(A_diag_data[j]);
                    }
                    else
                      l1_norm[i] += 0.5 * fabs(A_diag_data[j]);
                  }
                }
                if (num_cols_offd) {
                  for (j = A_offd_I[i]; j < (A_offd_I[i + 1]); j++)
                    l1_norm[i] += 0.5 * fabs(A_offd_data[j]);
                }
              }
              else {
                cf_diag = cf_marker[i];
                for (j = A_diag_I[i]; j < (A_diag_I[i + 1]); j++) {
                  ii = A_diag_J[j];
                  if ((((ii == i) || (ii < ns)) || (ii >= ne)) && (cf_diag == (cf_marker[A_diag_J[j]]))) {
                    if (ii == i) {
                      diag = fabs(A_diag_data[j]);
                      l1_norm[i] += fabs(A_diag_data[j]);
                    }
                    else
                      l1_norm[i] += 0.5 * fabs(A_diag_data[j]);
                  }
                }
                if (num_cols_offd) {
                  for (j = A_offd_I[i]; j < (A_offd_I[i + 1]); j++)
                    if (cf_diag == (cf_marker_offd[A_offd_J[j]]))
                      l1_norm[i] += 0.5 * fabs(A_offd_data[j]);
                }
              }
              if ((l1_norm[i]) <= ((4.0 / 3.0) * diag))
                l1_norm[i] = diag;
            }
          }
    for (i = ns; i < ne; i++)
      if ((A_diag_data[A_diag_I[i]]) < 0)
        l1_norm[i] = -(l1_norm[i]);
    for (i = ns; i < ne; i++)
      if (fabs(l1_norm[i]) < 1e-9) {
        hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_ls/par_relax_more.c", 908, 4 | (1 << 3));
        break;
      }
  }
  hypre_Free((char*)cf_marker_offd), cf_marker_offd = (void*)0;
  *l1_norm_ptr = l1_norm;
  return hypre__global_error;
}
int hypre_ParCSRRelax_L1(hypre_ParCSRMatrix* A, hypre_ParVector* f, double relax_weight, double omega, double* l1_norms, hypre_ParVector* u, hypre_ParVector* Vtemp, hypre_ParVector* Ztemp) {
  MPI_Comm comm = (A)->comm;
  hypre_CSRMatrix* A_diag = (A)->diag;
  double* A_diag_data = (A_diag)->data;
  int* A_diag_i = (A_diag)->i;
  int* A_diag_j = (A_diag)->j;
  hypre_CSRMatrix* A_offd = (A)->offd;
  int* A_offd_i = (A_offd)->i;
  double* A_offd_data = (A_offd)->data;
  int* A_offd_j = (A_offd)->j;
  hypre_ParCSRCommPkg* comm_pkg = (A)->comm_pkg;
  hypre_ParCSRCommHandle* comm_handle;
  int n = (A_diag)->num_rows;
  int num_cols_offd = (A_offd)->num_cols;
  hypre_Vector* u_local = (u)->local_vector;
  double* u_data = (u_local)->data;
  hypre_Vector* f_local = (f)->local_vector;
  double* f_data = (f_local)->data;
  hypre_Vector* Vtemp_local = (Vtemp)->local_vector;
  double* Vtemp_data = (Vtemp_local)->data;
  double* Vext_data;
  double* v_buf_data;
  double* tmp_data;
  int i;
  int j;
  int ii;
  int jj;
  int ns;
  int ne;
  int size;
  int rest;
  int relax_error = 0;
  int num_sends;
  int index;
  int start;
  int num_procs;
  int num_threads;
  int my_id;
  double zero = 0.0;
  double res;
  double res2;
  hypre_Vector* Ztemp_local;
  double* Ztemp_data;
  MPI_Comm_size(comm, &(num_procs));
  MPI_Comm_rank(comm, &(my_id));
  num_threads = 1;
  if (num_procs > 1) {
    num_sends = (comm_pkg)->num_sends;
    v_buf_data = (double*)(hypre_CAlloc((unsigned)((comm_pkg)->send_map_starts[num_sends]), (unsigned)(sizeof(double))));
    Vext_data = (double*)(hypre_CAlloc((unsigned)num_cols_offd, (unsigned)(sizeof(double))));
    if (num_cols_offd) {
      A_offd_j = (A_offd)->j;
      A_offd_data = (A_offd)->data;
    }
    index = 0;
    for (i = 0; i < num_sends; i++) {
      start = (comm_pkg)->send_map_starts[i];
      for (j = start; j < ((comm_pkg)->send_map_starts[i + 1]); j++)
        v_buf_data[index++] = u_data[(comm_pkg)->send_map_elmts[j]];
    }
    comm_handle = hypre_ParCSRCommHandleCreate(1, comm_pkg, v_buf_data, Vext_data);
    hypre_ParCSRCommHandleDestroy(comm_handle);
    comm_handle = (void*)0;
  }
  Ztemp_local = (Ztemp)->local_vector;
  Ztemp_data = (Ztemp_local)->data;
  if ((relax_weight == 1) && (omega == 1)) {
    tmp_data = Ztemp_data;
    for (i = 0; i < n; i++)
      tmp_data[i] = u_data[i];
    for (j = 0; j < num_threads; j++) {
      size = n / num_threads;
      rest = n - (size * num_threads);
      if (j < rest) {
        ns = (j * size) + j;
        ne = (((j + 1) * size) + j) + 1;
      }
      else {
        ns = (j * size) + rest;
        ne = ((j + 1) * size) + rest;
      }
      for (i = ns; i < ne; i++) {
        if ((A_diag_data[A_diag_i[i]]) != zero) {
          res = f_data[i];
          for (jj = A_diag_i[i]; jj < (A_diag_i[i + 1]); jj++) {
            ii = A_diag_j[jj];
            if ((ii >= ns) && (ii < ne)) {
              res -= ((A_diag_data[jj]) * (u_data[ii]));
            }
            else
              res -= ((A_diag_data[jj]) * (tmp_data[ii]));
          }
          for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
            ii = A_offd_j[jj];
            res -= ((A_offd_data[jj]) * (Vext_data[ii]));
          }
          u_data[i] += res / (l1_norms[i]);
        }
      }
      for (i = ne - 1; i > (ns - 1); i--) {
        if ((A_diag_data[A_diag_i[i]]) != zero) {
          res = f_data[i];
          for (jj = A_diag_i[i]; jj < (A_diag_i[i + 1]); jj++) {
            ii = A_diag_j[jj];
            if ((ii >= ns) && (ii < ne)) {
              res -= ((A_diag_data[jj]) * (u_data[ii]));
            }
            else
              res -= ((A_diag_data[jj]) * (tmp_data[ii]));
          }
          for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
            ii = A_offd_j[jj];
            res -= ((A_offd_data[jj]) * (Vext_data[ii]));
          }
          u_data[i] += res / (l1_norms[i]);
        }
      }
    }
  }
  else {
    double c1 = omega * relax_weight;
    double c2 = omega * (1.0 - relax_weight);
    tmp_data = Ztemp_data;
    for (i = 0; i < n; i++) {
      tmp_data[i] = u_data[i];
    }
    for (j = 0; j < num_threads; j++) {
      size = n / num_threads;
      rest = n - (size * num_threads);
      if (j < rest) {
        ns = (j * size) + j;
        ne = (((j + 1) * size) + j) + 1;
      }
      else {
        ns = (j * size) + rest;
        ne = ((j + 1) * size) + rest;
      }
      for (i = ns; i < ne; i++) {
        if ((A_diag_data[A_diag_i[i]]) != zero) {
          res2 = 0.0;
          res = f_data[i];
          Vtemp_data[i] = u_data[i];
          for (jj = A_diag_i[i]; jj < (A_diag_i[i + 1]); jj++) {
            ii = A_diag_j[jj];
            if ((ii >= ns) && (ii < ne)) {
              res -= ((A_diag_data[jj]) * (u_data[ii]));
              if (ii < i)
                res2 += (A_diag_data[jj]) * ((Vtemp_data[ii]) - (u_data[ii]));
            }
            else
              res -= ((A_diag_data[jj]) * (tmp_data[ii]));
          }
          for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
            ii = A_offd_j[jj];
            res -= ((A_offd_data[jj]) * (Vext_data[ii]));
          }
          u_data[i] += ((c1 * res) + (c2 * res2)) / (l1_norms[i]);
        }
      }
      for (i = ne - 1; i > (ns - 1); i--) {
        if ((A_diag_data[A_diag_i[i]]) != zero) {
          res2 = 0.0;
          res = f_data[i];
          for (jj = A_diag_i[i]; jj < (A_diag_i[i + 1]); jj++) {
            ii = A_diag_j[jj];
            if ((ii >= ns) && (ii < ne)) {
              res -= ((A_diag_data[jj]) * (u_data[ii]));
              if (ii > i)
                res2 += (A_diag_data[jj]) * ((Vtemp_data[ii]) - (u_data[ii]));
            }
            else
              res -= ((A_diag_data[jj]) * (tmp_data[ii]));
          }
          for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
            ii = A_offd_j[jj];
            res -= ((A_offd_data[jj]) * (Vext_data[ii]));
          }
          u_data[i] += ((c1 * res) + (c2 * res2)) / (l1_norms[i]);
        }
      }
    }
  }
  if (num_procs > 1) {
    hypre_Free((char*)Vext_data), Vext_data = (void*)0;
    hypre_Free((char*)v_buf_data), v_buf_data = (void*)0;
  }
  return relax_error;
}
int hypre_ParCSRRelax_L1_GS(hypre_ParCSRMatrix* A, hypre_ParVector* f, double relax_weight, double omega, double* l1_norms, hypre_ParVector* u, hypre_ParVector* Vtemp, hypre_ParVector* Ztemp) {
  MPI_Comm comm = (A)->comm;
  hypre_CSRMatrix* A_diag = (A)->diag;
  double* A_diag_data = (A_diag)->data;
  int* A_diag_i = (A_diag)->i;
  int* A_diag_j = (A_diag)->j;
  hypre_CSRMatrix* A_offd = (A)->offd;
  int* A_offd_i = (A_offd)->i;
  double* A_offd_data = (A_offd)->data;
  int* A_offd_j = (A_offd)->j;
  hypre_ParCSRCommPkg* comm_pkg = (A)->comm_pkg;
  hypre_ParCSRCommHandle* comm_handle;
  int n = (A_diag)->num_rows;
  int num_cols_offd = (A_offd)->num_cols;
  hypre_Vector* u_local = (u)->local_vector;
  double* u_data = (u_local)->data;
  hypre_Vector* f_local = (f)->local_vector;
  double* f_data = (f_local)->data;
  hypre_Vector* Vtemp_local = (Vtemp)->local_vector;
  double* Vtemp_data = (Vtemp_local)->data;
  double* Vext_data;
  double* v_buf_data;
  double* tmp_data;
  int i;
  int j;
  int ii;
  int jj;
  int ns;
  int ne;
  int size;
  int rest;
  int relax_error = 0;
  int num_sends;
  int index;
  int start;
  int num_procs;
  int num_threads;
  int my_id;
  double zero = 0.0;
  double res;
  double res2;
  hypre_Vector* Ztemp_local;
  double* Ztemp_data;
  MPI_Comm_size(comm, &(num_procs));
  MPI_Comm_rank(comm, &(my_id));
  num_threads = 1;
  if (num_procs > 1) {
    num_sends = (comm_pkg)->num_sends;
    v_buf_data = (double*)(hypre_CAlloc((unsigned)((comm_pkg)->send_map_starts[num_sends]), (unsigned)(sizeof(double))));
    Vext_data = (double*)(hypre_CAlloc((unsigned)num_cols_offd, (unsigned)(sizeof(double))));
    if (num_cols_offd) {
      A_offd_j = (A_offd)->j;
      A_offd_data = (A_offd)->data;
    }
    index = 0;
    for (i = 0; i < num_sends; i++) {
      start = (comm_pkg)->send_map_starts[i];
      for (j = start; j < ((comm_pkg)->send_map_starts[i + 1]); j++)
        v_buf_data[index++] = u_data[(comm_pkg)->send_map_elmts[j]];
    }
    comm_handle = hypre_ParCSRCommHandleCreate(1, comm_pkg, v_buf_data, Vext_data);
    hypre_ParCSRCommHandleDestroy(comm_handle);
    comm_handle = (void*)0;
  }
  Ztemp_local = (Ztemp)->local_vector;
  Ztemp_data = (Ztemp_local)->data;
  if ((relax_weight == 1) && (omega == 1)) {
    tmp_data = Ztemp_data;
    for (i = 0; i < n; i++)
      tmp_data[i] = u_data[i];
    for (j = 0; j < num_threads; j++) {
      size = n / num_threads;
      rest = n - (size * num_threads);
      if (j < rest) {
        ns = (j * size) + j;
        ne = (((j + 1) * size) + j) + 1;
      }
      else {
        ns = (j * size) + rest;
        ne = ((j + 1) * size) + rest;
      }
      for (i = ns; i < ne; i++) {
        if ((A_diag_data[A_diag_i[i]]) != zero) {
          res = f_data[i];
          for (jj = A_diag_i[i]; jj < (A_diag_i[i + 1]); jj++) {
            ii = A_diag_j[jj];
            if ((ii >= ns) && (ii < ne)) {
              res -= ((A_diag_data[jj]) * (u_data[ii]));
            }
            else
              res -= ((A_diag_data[jj]) * (tmp_data[ii]));
          }
          for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
            ii = A_offd_j[jj];
            res -= ((A_offd_data[jj]) * (Vext_data[ii]));
          }
          u_data[i] += res / (l1_norms[i]);
        }
      }
    }
  }
  else {
    double c1 = omega * relax_weight;
    double c2 = omega * (1.0 - relax_weight);
    tmp_data = Ztemp_data;
    for (i = 0; i < n; i++) {
      tmp_data[i] = u_data[i];
    }
    for (j = 0; j < num_threads; j++) {
      size = n / num_threads;
      rest = n - (size * num_threads);
      if (j < rest) {
        ns = (j * size) + j;
        ne = (((j + 1) * size) + j) + 1;
      }
      else {
        ns = (j * size) + rest;
        ne = ((j + 1) * size) + rest;
      }
      for (i = ns; i < ne; i++) {
        if ((A_diag_data[A_diag_i[i]]) != zero) {
          res2 = 0.0;
          res = f_data[i];
          Vtemp_data[i] = u_data[i];
          for (jj = A_diag_i[i]; jj < (A_diag_i[i + 1]); jj++) {
            ii = A_diag_j[jj];
            if ((ii >= ns) && (ii < ne)) {
              res -= ((A_diag_data[jj]) * (u_data[ii]));
              if (ii < i)
                res2 += (A_diag_data[jj]) * ((Vtemp_data[ii]) - (u_data[ii]));
            }
            else
              res -= ((A_diag_data[jj]) * (tmp_data[ii]));
          }
          for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
            ii = A_offd_j[jj];
            res -= ((A_offd_data[jj]) * (Vext_data[ii]));
          }
          u_data[i] += ((c1 * res) + (c2 * res2)) / (l1_norms[i]);
        }
      }
    }
  }
  if (num_procs > 1) {
    hypre_Free((char*)Vext_data), Vext_data = (void*)0;
    hypre_Free((char*)v_buf_data), v_buf_data = (void*)0;
  }
  return relax_error;
}
int hypre_ParCSRRelax_L1_Jacobi(hypre_ParCSRMatrix* A, hypre_ParVector* f, int* cf_marker, int relax_points, double relax_weight, double* l1_norms, hypre_ParVector* u, hypre_ParVector* Vtemp) {
  MPI_Comm comm = (A)->comm;
  hypre_CSRMatrix* A_diag = (A)->diag;
  double* A_diag_data = (A_diag)->data;
  int* A_diag_i = (A_diag)->i;
  int* A_diag_j = (A_diag)->j;
  hypre_CSRMatrix* A_offd = (A)->offd;
  int* A_offd_i = (A_offd)->i;
  double* A_offd_data = (A_offd)->data;
  int* A_offd_j = (A_offd)->j;
  hypre_ParCSRCommPkg* comm_pkg = (A)->comm_pkg;
  hypre_ParCSRCommHandle* comm_handle;
  int n = (A_diag)->num_rows;
  int num_cols_offd = (A_offd)->num_cols;
  hypre_Vector* u_local = (u)->local_vector;
  double* u_data = (u_local)->data;
  hypre_Vector* f_local = (f)->local_vector;
  double* f_data = (f_local)->data;
  hypre_Vector* Vtemp_local = (Vtemp)->local_vector;
  double* Vtemp_data = (Vtemp_local)->data;
  double* Vext_data;
  double* v_buf_data;
  int i;
  int j;
  int ii;
  int jj;
  int num_sends;
  int index;
  int start;
  int num_procs;
  int my_id;
  double zero = 0.0;
  double res;
  MPI_Comm_size(comm, &(num_procs));
  MPI_Comm_rank(comm, &(my_id));
  if (num_procs > 1) {
    num_sends = (comm_pkg)->num_sends;
    v_buf_data = (double*)(hypre_CAlloc((unsigned)((comm_pkg)->send_map_starts[num_sends]), (unsigned)(sizeof(double))));
    Vext_data = (double*)(hypre_CAlloc((unsigned)num_cols_offd, (unsigned)(sizeof(double))));
    if (num_cols_offd) {
      A_offd_j = (A_offd)->j;
      A_offd_data = (A_offd)->data;
    }
    index = 0;
    for (i = 0; i < num_sends; i++) {
      start = (comm_pkg)->send_map_starts[i];
      for (j = start; j < ((comm_pkg)->send_map_starts[i + 1]); j++)
        v_buf_data[index++] = u_data[(comm_pkg)->send_map_elmts[j]];
    }
    comm_handle = hypre_ParCSRCommHandleCreate(1, comm_pkg, v_buf_data, Vext_data);
  }
  for (i = 0; i < n; i++) {
    Vtemp_data[i] = u_data[i];
  }
  if (num_procs > 1) {
    hypre_ParCSRCommHandleDestroy(comm_handle);
    comm_handle = (void*)0;
  }
  if ((relax_points == 0) || (cf_marker == (void*)0)) {
    for (i = 0; i < n; i++) {
      if ((A_diag_data[A_diag_i[i]]) != zero) {
        res = f_data[i];
        for (jj = A_diag_i[i]; jj < (A_diag_i[i + 1]); jj++) {
          ii = A_diag_j[jj];
          res -= ((A_diag_data[jj]) * (Vtemp_data[ii]));
        }
        for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
          ii = A_offd_j[jj];
          res -= ((A_offd_data[jj]) * (Vext_data[ii]));
        }
        u_data[i] += (relax_weight * res) / (l1_norms[i]);
      }
    }
  }
  else {
    for (i = 0; i < n; i++) {
      if (((cf_marker[i]) == relax_points) && ((A_diag_data[A_diag_i[i]]) != zero)) {
        res = f_data[i];
        for (jj = A_diag_i[i]; jj < (A_diag_i[i + 1]); jj++) {
          ii = A_diag_j[jj];
          res -= ((A_diag_data[jj]) * (Vtemp_data[ii]));
        }
        for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
          ii = A_offd_j[jj];
          res -= ((A_offd_data[jj]) * (Vext_data[ii]));
        }
        u_data[i] += (relax_weight * res) / (l1_norms[i]);
      }
    }
  }
  if (num_procs > 1) {
    hypre_Free((char*)Vext_data), Vext_data = (void*)0;
    hypre_Free((char*)v_buf_data), v_buf_data = (void*)0;
  }
  return 0;
}
//================== par_scaled_matnorm.c ==================
int hypre_ParCSRMatrixScaledNorm(hypre_ParCSRMatrix* A, double* scnorm) {
  hypre_ParCSRCommHandle* comm_handle;
  hypre_ParCSRCommPkg* comm_pkg = (A)->comm_pkg;
  MPI_Comm comm = (A)->comm;
  hypre_CSRMatrix* diag = (A)->diag;
  int* diag_i = (diag)->i;
  int* diag_j = (diag)->j;
  double* diag_data = (diag)->data;
  hypre_CSRMatrix* offd = (A)->offd;
  int* offd_i = (offd)->i;
  int* offd_j = (offd)->j;
  double* offd_data = (offd)->data;
  int global_num_rows = (A)->global_num_rows;
  int* row_starts = (A)->row_starts;
  int num_rows = (diag)->num_rows;
  hypre_ParVector* dinvsqrt;
  double* dis_data;
  hypre_Vector* dis_ext;
  double* dis_ext_data;
  hypre_Vector* sum;
  double* sum_data;
  int num_cols_offd = (offd)->num_cols;
  int num_sends;
  int i;
  int j;
  int index;
  int start;
  double* d_buf_data;
  double mat_norm;
  double max_row_sum;
  dinvsqrt = hypre_ParVectorCreate(comm, global_num_rows, row_starts);
  hypre_ParVectorInitialize(dinvsqrt);
  dis_data = ((dinvsqrt)->local_vector)->data;
  hypre_ParVectorSetPartitioningOwner(dinvsqrt, 0);
  dis_ext = hypre_SeqVectorCreate(num_cols_offd);
  hypre_SeqVectorInitialize(dis_ext);
  dis_ext_data = (dis_ext)->data;
  sum = hypre_SeqVectorCreate(num_rows);
  hypre_SeqVectorInitialize(sum);
  sum_data = (sum)->data;
  for (i = 0; i < num_rows; i++) {
    dis_data[i] = 1.0 / sqrt(fabs(diag_data[diag_i[i]]));
  }
  if (!comm_pkg) {
    hypre_MatvecCommPkgCreate(A);
    comm_pkg = (A)->comm_pkg;
  }
  num_sends = (comm_pkg)->num_sends;
  d_buf_data = (double*)(hypre_CAlloc((unsigned)((comm_pkg)->send_map_starts[num_sends]), (unsigned)(sizeof(double))));
  index = 0;
  for (i = 0; i < num_sends; i++) {
    start = (comm_pkg)->send_map_starts[i];
    for (j = start; j < ((comm_pkg)->send_map_starts[i + 1]); j++)
      d_buf_data[index++] = dis_data[(comm_pkg)->send_map_elmts[j]];
  }
  comm_handle = hypre_ParCSRCommHandleCreate(1, comm_pkg, d_buf_data, dis_ext_data);
  for (i = 0; i < num_rows; i++) {
    for (j = diag_i[i]; j < (diag_i[i + 1]); j++) {
      sum_data[i] += (fabs(diag_data[j]) * (dis_data[i])) * (dis_data[diag_j[j]]);
    }
  }
  hypre_ParCSRCommHandleDestroy(comm_handle);
  for (i = 0; i < num_rows; i++) {
    for (j = offd_i[i]; j < (offd_i[i + 1]); j++) {
      sum_data[i] += (fabs(offd_data[j]) * (dis_data[i])) * (dis_ext_data[offd_j[j]]);
    }
  }
  max_row_sum = 0;
  for (i = 0; i < num_rows; i++) {
    if (max_row_sum < (sum_data[i]))
      max_row_sum = sum_data[i];
  }
  MPI_Allreduce(&(max_row_sum), &(mat_norm), 1, MPI_DOUBLE, _MAX, comm);
  hypre_ParVectorDestroy(dinvsqrt);
  hypre_SeqVectorDestroy(sum);
  hypre_SeqVectorDestroy(dis_ext);
  hypre_Free((char*)d_buf_data), d_buf_data = (void*)0;
  *scnorm = mat_norm;
  return 0;
}
//======================= par_stats.c ======================
int hypre_BoomerAMGSetupStats(void* amg_vdata, hypre_ParCSRMatrix* A) {
  MPI_Comm comm = (A)->comm;
  hypre_ParAMGData* amg_data = amg_vdata;
  hypre_ParCSRMatrix** A_array;
  hypre_ParCSRMatrix** P_array;
  hypre_CSRMatrix* A_diag;
  double* A_diag_data;
  int* A_diag_i;
  hypre_CSRMatrix* A_offd;
  double* A_offd_data;
  int* A_offd_i;
  hypre_CSRMatrix* P_diag;
  double* P_diag_data;
  int* P_diag_i;
  hypre_CSRMatrix* P_offd;
  double* P_offd_data;
  int* P_offd_i;
  int numrows;
  int* row_starts;
  int num_levels;
  int coarsen_type;
  int interp_type;
  int measure_type;
  double global_nonzeros;
  double* send_buff;
  double* gather_buff;
  int level;
  int j;
  int fine_size;
  int min_entries;
  int max_entries;
  int num_procs;
  int my_id;
  int num_threads;
  double min_rowsum;
  double max_rowsum;
  double sparse;
  int i;
  int coarse_size;
  int entries;
  double avg_entries;
  double rowsum;
  double min_weight;
  double max_weight;
  int global_min_e;
  int global_max_e;
  double global_min_rsum;
  double global_max_rsum;
  double global_min_wt;
  double global_max_wt;
  double* num_coeffs;
  double* num_variables;
  double total_variables;
  double operat_cmplxty;
  double grid_cmplxty;
  int max_iter;
  int cycle_type;
  int* num_grid_sweeps;
  int* grid_relax_type;
  int relax_order;
  int** grid_relax_points;
  double* relax_weight;
  double* omega;
  double tol;
  int one = 1;
  int minus_one = -1;
  int zero = 0;
  int smooth_type;
  int smooth_num_levels;
  int agg_num_levels;
  MPI_Comm_size(comm, &(num_procs));
  MPI_Comm_rank(comm, &(my_id));
  num_threads = 1;
  if (my_id == 0)
    printf("\nNumber of MPI processes: %d , Number of OpenMP threads: %d\n", num_procs, num_threads);
  A_array = (amg_data)->A_array;
  P_array = (amg_data)->P_array;
  num_levels = (amg_data)->num_levels;
  coarsen_type = (amg_data)->coarsen_type;
  interp_type = (amg_data)->interp_type;
  measure_type = (amg_data)->measure_type;
  smooth_type = (amg_data)->smooth_type;
  smooth_num_levels = (amg_data)->smooth_num_levels;
  agg_num_levels = (amg_data)->agg_num_levels;
  num_levels = (amg_data)->num_levels;
  max_iter = (amg_data)->max_iter;
  cycle_type = (amg_data)->cycle_type;
  num_grid_sweeps = (amg_data)->num_grid_sweeps;
  grid_relax_type = (amg_data)->grid_relax_type;
  grid_relax_points = (amg_data)->grid_relax_points;
  relax_weight = (amg_data)->relax_weight;
  relax_order = (amg_data)->relax_order;
  omega = (amg_data)->omega;
  tol = (amg_data)->tol;
  send_buff = (double*)(hypre_CAlloc((unsigned)6, (unsigned)(sizeof(double))));
  gather_buff = (double*)(hypre_CAlloc((unsigned)(6 * num_procs), (unsigned)(sizeof(double))));
  if (my_id == 0) {
    printf("\nBoomerAMG SETUP PARAMETERS:\n\n");
    printf(" Max levels = %d\n", (amg_data)->max_levels);
    printf(" Num levels = %d\n\n", num_levels);
    printf(" Strength Threshold = %f\n", (amg_data)->strong_threshold);
    printf(" Interpolation Truncation Factor = %f\n", (amg_data)->trunc_factor);
    printf(" Maximum Row Sum Threshold for Dependency Weakening = %f\n\n", (amg_data)->max_row_sum);
    if (coarsen_type == 0) {
      printf(" Coarsening Type = Cleary-Luby-Jones-Plassman\n");
    }
    else
      if (abs(coarsen_type) == 1) {
        printf(" Coarsening Type = Ruge\n");
      }
      else
        if (abs(coarsen_type) == 2) {
          printf(" Coarsening Type = Ruge2B\n");
        }
        else
          if (abs(coarsen_type) == 3) {
            printf(" Coarsening Type = Ruge3\n");
          }
          else
            if (abs(coarsen_type) == 4) {
              printf(" Coarsening Type = Ruge 3c \n");
            }
            else
              if (abs(coarsen_type) == 5) {
                printf(" Coarsening Type = Ruge relax special points \n");
              }
              else
                if (abs(coarsen_type) == 6) {
                  printf(" Coarsening Type = Falgout-CLJP \n");
                }
                else
                  if (abs(coarsen_type) == 8) {
                    printf(" Coarsening Type = PMIS \n");
                  }
                  else
                    if (abs(coarsen_type) == 10) {
                      printf(" Coarsening Type = HMIS \n");
                    }
                    else
                      if (abs(coarsen_type) == 11) {
                        printf(" Coarsening Type = Ruge 1st pass only \n");
                      }
                      else
                        if (abs(coarsen_type) == 9) {
                          printf(" Coarsening Type = PMIS fixed random \n");
                        }
                        else
                          if (abs(coarsen_type) == 7) {
                            printf(" Coarsening Type = CLJP, fixed random \n");
                          }
    if (coarsen_type > 0) {
      printf(" Hybrid Coarsening (switch to CLJP when coarsening slows)\n");
    }
    if (coarsen_type)
      printf(" measures are determined %s\n\n", measure_type ? "globally" : "locally");
    if (agg_num_levels)
      printf(" no. of levels of aggressive coarsening: %d\n\n", agg_num_levels);
    if (interp_type == 0) {
      printf(" Interpolation = modified classical interpolation\n");
    }
    else
      if (interp_type == 1) {
        printf(" Interpolation = LS interpolation \n");
      }
      else
        if (interp_type == 2) {
          printf(" Interpolation = modified classical interpolation for hyperbolic PDEs\n");
        }
        else
          if (interp_type == 3) {
            printf(" Interpolation = direct interpolation with separation of weights\n");
          }
          else
            if (interp_type == 4) {
              printf(" Interpolation = multipass interpolation\n");
            }
            else
              if (interp_type == 5) {
                printf(" Interpolation = multipass interpolation with separation of weights\n");
              }
              else
                if (interp_type == 6) {
                  printf(" Interpolation = extended+i interpolation\n");
                }
                else
                  if (interp_type == 7) {
                    printf(" Interpolation = extended+i interpolation (only when needed)\n");
                  }
                  else
                    if (interp_type == 8) {
                      printf(" Interpolation = standard interpolation\n");
                    }
                    else
                      if (interp_type == 9) {
                        printf(" Interpolation = standard interpolation with separation of weights\n");
                      }
                      else
                        if (interp_type == 12) {
                          printf(" FF interpolation \n");
                        }
                        else
                          if (interp_type == 13) {
                            printf(" FF1 interpolation \n");
                          }
    {
      printf("\nOperator Matrix Information:\n\n");
    }
    printf("            nonzero         entries p");
    printf("er row        row sums\n");
    printf("lev   rows  entries  sparse  min  max   ");
    printf("avg       min         max\n");
    printf("=======================================");
    printf("============================\n");
  }
  num_coeffs = (double*)(hypre_CAlloc((unsigned)num_levels, (unsigned)(sizeof(double))));
  num_variables = (double*)(hypre_CAlloc((unsigned)num_levels, (unsigned)(sizeof(double))));
  for (level = 0; level < num_levels; level++) {
    {
      A_diag = (A_array[level])->diag;
      A_diag_data = (A_diag)->data;
      A_diag_i = (A_diag)->i;
      A_offd = (A_array[level])->offd;
      A_offd_data = (A_offd)->data;
      A_offd_i = (A_offd)->i;
      row_starts = (A_array[level])->row_starts;
      fine_size = (A_array[level])->global_num_rows;
      global_nonzeros = (A_array[level])->d_num_nonzeros;
      num_coeffs[level] = global_nonzeros;
      num_variables[level] = (double)fine_size;
      sparse = global_nonzeros / ((double)fine_size * (double)fine_size);
      min_entries = 0;
      max_entries = 0;
      min_rowsum = 0.0;
      max_rowsum = 0.0;
      if ((A_diag)->num_rows) {
        min_entries = ((A_diag_i[1]) - (A_diag_i[0])) + ((A_offd_i[1]) - (A_offd_i[0]));
        for (j = A_diag_i[0]; j < (A_diag_i[1]); j++)
          min_rowsum += A_diag_data[j];
        for (j = A_offd_i[0]; j < (A_offd_i[1]); j++)
          min_rowsum += A_offd_data[j];
        max_rowsum = min_rowsum;
        for (j = 0; j < (A_diag)->num_rows; j++) {
          entries = ((A_diag_i[j + 1]) - (A_diag_i[j])) + ((A_offd_i[j + 1]) - (A_offd_i[j]));
          min_entries = entries < min_entries ? entries : min_entries;
          max_entries = entries < max_entries ? max_entries : entries;
          rowsum = 0.0;
          for (i = A_diag_i[j]; i < (A_diag_i[j + 1]); i++)
            rowsum += A_diag_data[i];
          for (i = A_offd_i[j]; i < (A_offd_i[j + 1]); i++)
            rowsum += A_offd_data[i];
          min_rowsum = rowsum < min_rowsum ? rowsum : min_rowsum;
          max_rowsum = rowsum < max_rowsum ? max_rowsum : rowsum;
        }
      }
      avg_entries = global_nonzeros / (double)fine_size;
    }
    send_buff[0] = (double)min_entries;
    send_buff[1] = (double)max_entries;
    send_buff[2] = min_rowsum;
    send_buff[3] = max_rowsum;
    MPI_Gather(send_buff, 4, MPI_DOUBLE, gather_buff, 4, MPI_DOUBLE, 0, comm);
    if (my_id == 0) {
      global_min_e = 1000000;
      global_max_e = 0;
      global_min_rsum = 1.0e7;
      global_max_rsum = 0.0;
      for (j = 0; j < num_procs; j++) {
        numrows = (row_starts[j + 1]) - (row_starts[j]);
        if (numrows) {
          global_min_e = global_min_e < (int)(gather_buff[j * 4]) ? global_min_e : (int)(gather_buff[j * 4]);
          global_min_rsum = global_min_rsum < (gather_buff[(j * 4) + 2]) ? global_min_rsum : gather_buff[(j * 4) + 2];
        }
        global_max_e = global_max_e < (int)(gather_buff[(j * 4) + 1]) ? (int)(gather_buff[(j * 4) + 1]) : global_max_e;
        global_max_rsum = global_max_rsum < (gather_buff[(j * 4) + 3]) ? gather_buff[(j * 4) + 3] : global_max_rsum;
      }
      printf("%2d %7d %8.0f  %0.3f  %4d %4d", level, fine_size, global_nonzeros, sparse, global_min_e, global_max_e);
      printf("  %4.1f  %10.3e  %10.3e\n", avg_entries, global_min_rsum, global_max_rsum);
    }
  }
  if (my_id == 0) {
    {
      printf("\n\nInterpolation Matrix Information:\n\n");
    }
    printf("                 entries/row    min     max");
    printf("         row sums\n");
    printf("lev  rows cols    min max  ");
    printf("   weight   weight     min       max \n");
    printf("=======================================");
    printf("==========================\n");
  }
  for (level = 0; level < (num_levels - 1); level++) {
    {
      P_diag = (P_array[level])->diag;
      P_diag_data = (P_diag)->data;
      P_diag_i = (P_diag)->i;
      P_offd = (P_array[level])->offd;
      P_offd_data = (P_offd)->data;
      P_offd_i = (P_offd)->i;
      row_starts = (P_array[level])->row_starts;
      fine_size = (P_array[level])->global_num_rows;
      coarse_size = (P_array[level])->global_num_cols;
      global_nonzeros = (P_array[level])->num_nonzeros;
      min_weight = 1.0;
      max_weight = 0.0;
      max_rowsum = 0.0;
      min_rowsum = 0.0;
      min_entries = 0;
      max_entries = 0;
      if ((P_diag)->num_rows) {
        if ((P_diag)->num_cols)
          min_weight = P_diag_data[0];
        for (j = P_diag_i[0]; j < (P_diag_i[1]); j++) {
          min_weight = min_weight < (P_diag_data[j]) ? min_weight : P_diag_data[j];
          if ((P_diag_data[j]) != 1.0)
            max_weight = max_weight < (P_diag_data[j]) ? P_diag_data[j] : max_weight;
          min_rowsum += P_diag_data[j];
        }
        for (j = P_offd_i[0]; j < (P_offd_i[1]); j++) {
          min_weight = min_weight < (P_offd_data[j]) ? min_weight : P_offd_data[j];
          if ((P_offd_data[j]) != 1.0)
            max_weight = max_weight < (P_offd_data[j]) ? P_offd_data[j] : max_weight;
          min_rowsum += P_offd_data[j];
        }
        max_rowsum = min_rowsum;
        min_entries = ((P_diag_i[1]) - (P_diag_i[0])) + ((P_offd_i[1]) - (P_offd_i[0]));
        max_entries = 0;
        for (j = 0; j < (P_diag)->num_rows; j++) {
          entries = ((P_diag_i[j + 1]) - (P_diag_i[j])) + ((P_offd_i[j + 1]) - (P_offd_i[j]));
          min_entries = entries < min_entries ? entries : min_entries;
          max_entries = entries < max_entries ? max_entries : entries;
          rowsum = 0.0;
          for (i = P_diag_i[j]; i < (P_diag_i[j + 1]); i++) {
            min_weight = min_weight < (P_diag_data[i]) ? min_weight : P_diag_data[i];
            if ((P_diag_data[i]) != 1.0)
              max_weight = max_weight < (P_diag_data[i]) ? P_diag_data[i] : max_weight;
            rowsum += P_diag_data[i];
          }
          for (i = P_offd_i[j]; i < (P_offd_i[j + 1]); i++) {
            min_weight = min_weight < (P_offd_data[i]) ? min_weight : P_offd_data[i];
            if ((P_offd_data[i]) != 1.0)
              max_weight = max_weight < (P_offd_data[i]) ? P_offd_data[i] : max_weight;
            rowsum += P_offd_data[i];
          }
          min_rowsum = rowsum < min_rowsum ? rowsum : min_rowsum;
          max_rowsum = rowsum < max_rowsum ? max_rowsum : rowsum;
        }
      }
      avg_entries = (double)global_nonzeros / (double)fine_size;
    }
    send_buff[0] = (double)min_entries;
    send_buff[1] = (double)max_entries;
    send_buff[2] = min_rowsum;
    send_buff[3] = max_rowsum;
    send_buff[4] = min_weight;
    send_buff[5] = max_weight;
    MPI_Gather(send_buff, 6, MPI_DOUBLE, gather_buff, 6, MPI_DOUBLE, 0, comm);
    if (my_id == 0) {
      global_min_e = 1000000;
      global_max_e = 0;
      global_min_rsum = 1.0e7;
      global_max_rsum = 0.0;
      global_min_wt = 1.0e7;
      global_max_wt = 0.0;
      for (j = 0; j < num_procs; j++) {
        numrows = (row_starts[j + 1]) - (row_starts[j]);
        if (numrows) {
          global_min_e = global_min_e < (int)(gather_buff[j * 6]) ? global_min_e : (int)(gather_buff[j * 6]);
          global_min_rsum = global_min_rsum < (gather_buff[(j * 6) + 2]) ? global_min_rsum : gather_buff[(j * 6) + 2];
          global_min_wt = global_min_wt < (gather_buff[(j * 6) + 4]) ? global_min_wt : gather_buff[(j * 6) + 4];
        }
        global_max_e = global_max_e < (int)(gather_buff[(j * 6) + 1]) ? (int)(gather_buff[(j * 6) + 1]) : global_max_e;
        global_max_rsum = global_max_rsum < (gather_buff[(j * 6) + 3]) ? gather_buff[(j * 6) + 3] : global_max_rsum;
        global_max_wt = global_max_wt < (gather_buff[(j * 6) + 5]) ? gather_buff[(j * 6) + 5] : global_max_wt;
      }
      printf("%2d %5d x %-5d %3d %3d", level, fine_size, coarse_size, global_min_e, global_max_e);
      printf("  %10.3e %9.3e %9.3e %9.3e\n", global_min_wt, global_max_wt, global_min_rsum, global_max_rsum);
    }
  }
  total_variables = 0;
  operat_cmplxty = 0;
  for (j = 0; j < (amg_data)->num_levels; j++) {
    operat_cmplxty += (num_coeffs[j]) / (num_coeffs[0]);
    total_variables += num_variables[j];
  }
  if ((num_variables[0]) != 0)
    grid_cmplxty = total_variables / (num_variables[0]);
  if (my_id == 0) {
    printf("\n\n     Complexity:    grid = %f\n", grid_cmplxty);
    printf("                operator = %f\n", operat_cmplxty);
  }
  if (my_id == 0)
    printf("\n\n");
  if (my_id == 0) {
    printf("\n\nBoomerAMG SOLVER PARAMETERS:\n\n");
    printf("  Maximum number of cycles:         %d \n", max_iter);
    printf("  Stopping Tolerance:               %e \n", tol);
    printf("  Cycle type (1 = V, 2 = W, etc.):  %d\n\n", cycle_type);
    printf("  Relaxation Parameters:\n");
    printf("   Visiting Grid:                     down   up  coarse\n");
    printf("            Number of partial sweeps: %4d   %2d  %4d \n", num_grid_sweeps[1], num_grid_sweeps[2], num_grid_sweeps[3]);
    printf("   Type 0=Jac, 3=hGS, 6=hSGS, 9=GE:   %4d   %2d  %4d \n", grid_relax_type[1], grid_relax_type[2], grid_relax_type[3]);
    printf("   Point types, partial sweeps (1=C, -1=F):\n");
    if (grid_relax_points) {
      printf("                  Pre-CG relaxation (down):");
      for (j = 0; j < (num_grid_sweeps[1]); j++)
        printf("  %2d", grid_relax_points[1][j]);
      printf("\n");
      printf("                   Post-CG relaxation (up):");
      for (j = 0; j < (num_grid_sweeps[2]); j++)
        printf("  %2d", grid_relax_points[2][j]);
      printf("\n");
      printf("                             Coarsest grid:");
      for (j = 0; j < (num_grid_sweeps[3]); j++)
        printf("  %2d", grid_relax_points[3][j]);
      printf("\n\n");
    }
    else
      if (relax_order == 1) {
        printf("                  Pre-CG relaxation (down):");
        for (j = 0; j < (num_grid_sweeps[1]); j++)
          printf("  %2d  %2d", one, minus_one);
        printf("\n");
        printf("                   Post-CG relaxation (up):");
        for (j = 0; j < (num_grid_sweeps[2]); j++)
          printf("  %2d  %2d", minus_one, one);
        printf("\n");
        printf("                             Coarsest grid:");
        for (j = 0; j < (num_grid_sweeps[3]); j++)
          printf("  %2d", zero);
        printf("\n\n");
      }
      else {
        printf("                  Pre-CG relaxation (down):");
        for (j = 0; j < (num_grid_sweeps[1]); j++)
          printf("  %2d", zero);
        printf("\n");
        printf("                   Post-CG relaxation (up):");
        for (j = 0; j < (num_grid_sweeps[2]); j++)
          printf("  %2d", zero);
        printf("\n");
        printf("                             Coarsest grid:");
        for (j = 0; j < (num_grid_sweeps[3]); j++)
          printf("  %2d", zero);
        printf("\n\n");
      }
    if (smooth_type == 6)
      for (j = 0; j < smooth_num_levels; j++)
        printf(" Schwarz Relaxation Weight %f level %d\n", (amg_data)->schwarz_rlx_weight, j);
    for (j = 0; j < num_levels; j++)
      if ((relax_weight[j]) != 1)
        printf(" Relaxation Weight %f level %d\n", relax_weight[j], j);
    for (j = 0; j < num_levels; j++)
      if ((omega[j]) != 1)
        printf(" Outer relaxation weight %f level %d\n", omega[j], j);
  }
  hypre_Free((char*)num_coeffs), num_coeffs = (void*)0;
  hypre_Free((char*)num_variables), num_variables = (void*)0;
  hypre_Free((char*)send_buff), send_buff = (void*)0;
  hypre_Free((char*)gather_buff), gather_buff = (void*)0;
  return 0;
}
int hypre_BoomerAMGWriteSolverParams(void* data) {
  hypre_ParAMGData* amg_data = data;
  int num_levels;
  int max_iter;
  int cycle_type;
  int* num_grid_sweeps;
  int* grid_relax_type;
  int** grid_relax_points;
  int relax_order;
  double* relax_weight;
  double* omega;
  double tol;
  int smooth_type;
  int smooth_num_levels;
  int amg_print_level;
  int j;
  int one = 1;
  int minus_one = -1;
  int zero = 0;
  num_levels = (amg_data)->num_levels;
  max_iter = (amg_data)->max_iter;
  cycle_type = (amg_data)->cycle_type;
  num_grid_sweeps = (amg_data)->num_grid_sweeps;
  grid_relax_type = (amg_data)->grid_relax_type;
  grid_relax_points = (amg_data)->grid_relax_points;
  relax_order = (amg_data)->relax_order;
  relax_weight = (amg_data)->relax_weight;
  omega = (amg_data)->omega;
  smooth_type = (amg_data)->smooth_type;
  smooth_num_levels = (amg_data)->smooth_num_levels;
  tol = (amg_data)->tol;
  amg_print_level = (amg_data)->print_level;
  if ((amg_print_level == 1) || (amg_print_level == 3)) {
    printf("\n\nBoomerAMG SOLVER PARAMETERS:\n\n");
    printf("  Maximum number of cycles:         %d \n", max_iter);
    printf("  Stopping Tolerance:               %e \n", tol);
    printf("  Cycle type (1 = V, 2 = W, etc.):  %d\n\n", cycle_type);
    printf("  Relaxation Parameters:\n");
    printf("   Visiting Grid:                     down   up  coarse\n");
    printf("   Visiting Grid:                     down   up  coarse\n");
    printf("            Number of partial sweeps: %4d   %2d  %4d \n", num_grid_sweeps[1], num_grid_sweeps[2], num_grid_sweeps[3]);
    printf("   Type 0=Jac, 3=hGS, 6=hSGS, 9=GE:   %4d   %2d  %4d \n", grid_relax_type[1], grid_relax_type[2], grid_relax_type[3]);
    printf("   Point types, partial sweeps (1=C, -1=F):\n");
    if (grid_relax_points) {
      printf("                  Pre-CG relaxation (down):");
      for (j = 0; j < (num_grid_sweeps[1]); j++)
        printf("  %2d", grid_relax_points[1][j]);
      printf("\n");
      printf("                   Post-CG relaxation (up):");
      for (j = 0; j < (num_grid_sweeps[2]); j++)
        printf("  %2d", grid_relax_points[2][j]);
      printf("\n");
      printf("                             Coarsest grid:");
      for (j = 0; j < (num_grid_sweeps[3]); j++)
        printf("  %2d", grid_relax_points[3][j]);
      printf("\n\n");
    }
    else
      if (relax_order == 1) {
        printf("                  Pre-CG relaxation (down):");
        for (j = 0; j < (num_grid_sweeps[1]); j++)
          printf("  %2d  %2d", one, minus_one);
        printf("\n");
        printf("                   Post-CG relaxation (up):");
        for (j = 0; j < (num_grid_sweeps[2]); j++)
          printf("  %2d  %2d", minus_one, one);
        printf("\n");
        printf("                             Coarsest grid:");
        for (j = 0; j < (num_grid_sweeps[3]); j++)
          printf("  %2d", zero);
        printf("\n\n");
      }
      else {
        printf("                  Pre-CG relaxation (down):");
        for (j = 0; j < (num_grid_sweeps[1]); j++)
          printf("  %2d", zero);
        printf("\n");
        printf("                   Post-CG relaxation (up):");
        for (j = 0; j < (num_grid_sweeps[2]); j++)
          printf("  %2d", zero);
        printf("\n");
        printf("                             Coarsest grid:");
        for (j = 0; j < (num_grid_sweeps[3]); j++)
          printf("  %2d", zero);
        printf("\n\n");
      }
    if (smooth_type == 6)
      for (j = 0; j < smooth_num_levels; j++)
        printf(" Schwarz Relaxation Weight %f level %d\n", (amg_data)->schwarz_rlx_weight, j);
    for (j = 0; j < num_levels; j++)
      if ((relax_weight[j]) != 1)
        printf(" Relaxation Weight %f level %d\n", relax_weight[j], j);
    for (j = 0; j < num_levels; j++)
      if ((omega[j]) != 1)
        printf(" Outer relaxation weight %f level %d\n", omega[j], j);
    printf(" Output flag (print_level): %d \n", amg_print_level);
  }
  return 0;
}
//===================== par_strength.c =====================
int hypre_BoomerAMGCreateS(hypre_ParCSRMatrix* A, double strength_threshold, double max_row_sum, int num_functions, int* dof_func, hypre_ParCSRMatrix** S_ptr) {
  MPI_Comm comm = (A)->comm;
  hypre_ParCSRCommPkg* comm_pkg = (A)->comm_pkg;
  hypre_ParCSRCommHandle* comm_handle;
  hypre_CSRMatrix* A_diag = (A)->diag;
  int* A_diag_i = (A_diag)->i;
  double* A_diag_data = (A_diag)->data;
  hypre_CSRMatrix* A_offd = (A)->offd;
  int* A_offd_i = (A_offd)->i;
  double* A_offd_data;
  int* A_diag_j = (A_diag)->j;
  int* A_offd_j = (A_offd)->j;
  int* row_starts = (A)->row_starts;
  int num_variables = (A_diag)->num_rows;
  int global_num_vars = (A)->global_num_rows;
  int num_nonzeros_diag;
  int num_nonzeros_offd = 0;
  int num_cols_offd = 0;
  hypre_ParCSRMatrix* S;
  hypre_CSRMatrix* S_diag;
  int* S_diag_i;
  int* S_diag_j;
  hypre_CSRMatrix* S_offd;
  int* S_offd_i;
  int* S_offd_j;
  double diag;
  double row_scale;
  double row_sum;
  int i;
  int jA;
  int jS;
  int ierr = 0;
  int* dof_func_offd;
  int num_sends;
  int* int_buf_data;
  int index;
  int start;
  int j;
  num_nonzeros_diag = A_diag_i[num_variables];
  num_cols_offd = (A_offd)->num_cols;
  A_offd_i = (A_offd)->i;
  num_nonzeros_offd = A_offd_i[num_variables];
  S = hypre_ParCSRMatrixCreate(comm, global_num_vars, global_num_vars, row_starts, row_starts, num_cols_offd, num_nonzeros_diag, num_nonzeros_offd);
  hypre_ParCSRMatrixSetRowStartsOwner(S, 0);
  S_diag = (S)->diag;
  (S_diag)->i = (int*)(hypre_CAlloc((unsigned)(num_variables + 1), (unsigned)(sizeof(int))));
  (S_diag)->j = (int*)(hypre_CAlloc((unsigned)num_nonzeros_diag, (unsigned)(sizeof(int))));
  S_offd = (S)->offd;
  (S_offd)->i = (int*)(hypre_CAlloc((unsigned)(num_variables + 1), (unsigned)(sizeof(int))));
  S_diag_i = (S_diag)->i;
  S_diag_j = (S_diag)->j;
  S_offd_i = (S_offd)->i;
  dof_func_offd = (void*)0;
  if (num_cols_offd) {
    A_offd_data = (A_offd)->data;
    (S_offd)->j = (int*)(hypre_CAlloc((unsigned)num_nonzeros_offd, (unsigned)(sizeof(int))));
    S_offd_j = (S_offd)->j;
    (S)->col_map_offd = (int*)(hypre_CAlloc((unsigned)num_cols_offd, (unsigned)(sizeof(int))));
    if (num_functions > 1)
      dof_func_offd = (int*)(hypre_CAlloc((unsigned)num_cols_offd, (unsigned)(sizeof(int))));
  }
  if (!comm_pkg) {
    hypre_MatvecCommPkgCreate(A);
    comm_pkg = (A)->comm_pkg;
  }
  num_sends = (comm_pkg)->num_sends;
  if (num_functions > 1) {
    int_buf_data = (int*)(hypre_CAlloc((unsigned)((comm_pkg)->send_map_starts[num_sends]), (unsigned)(sizeof(int))));
    index = 0;
    for (i = 0; i < num_sends; i++) {
      start = (comm_pkg)->send_map_starts[i];
      for (j = start; j < ((comm_pkg)->send_map_starts[i + 1]); j++)
        int_buf_data[index++] = dof_func[(comm_pkg)->send_map_elmts[j]];
    }
    comm_handle = hypre_ParCSRCommHandleCreate(11, comm_pkg, int_buf_data, dof_func_offd);
    hypre_ParCSRCommHandleDestroy(comm_handle);
    hypre_Free((char*)int_buf_data), int_buf_data = (void*)0;
  }
  hypre_ParCSRMatrixCopy(A, S, 0);
  for (i = 0; i < num_variables; i++) {
    diag = A_diag_data[A_diag_i[i]];
    row_scale = 0.0;
    row_sum = diag;
    if (num_functions > 1) {
      if (diag < 0) {
        for (jA = (A_diag_i[i]) + 1; jA < (A_diag_i[i + 1]); jA++) {
          if ((dof_func[i]) == (dof_func[A_diag_j[jA]])) {
            row_scale = row_scale < (A_diag_data[jA]) ? A_diag_data[jA] : row_scale;
            row_sum += A_diag_data[jA];
          }
        }
        for (jA = A_offd_i[i]; jA < (A_offd_i[i + 1]); jA++) {
          if ((dof_func[i]) == (dof_func_offd[A_offd_j[jA]])) {
            row_scale = row_scale < (A_offd_data[jA]) ? A_offd_data[jA] : row_scale;
            row_sum += A_offd_data[jA];
          }
        }
      }
      else {
        for (jA = (A_diag_i[i]) + 1; jA < (A_diag_i[i + 1]); jA++) {
          if ((dof_func[i]) == (dof_func[A_diag_j[jA]])) {
            row_scale = row_scale < (A_diag_data[jA]) ? row_scale : A_diag_data[jA];
            row_sum += A_diag_data[jA];
          }
        }
        for (jA = A_offd_i[i]; jA < (A_offd_i[i + 1]); jA++) {
          if ((dof_func[i]) == (dof_func_offd[A_offd_j[jA]])) {
            row_scale = row_scale < (A_offd_data[jA]) ? row_scale : A_offd_data[jA];
            row_sum += A_offd_data[jA];
          }
        }
      }
    }
    else {
      if (diag < 0) {
        for (jA = (A_diag_i[i]) + 1; jA < (A_diag_i[i + 1]); jA++) {
          row_scale = row_scale < (A_diag_data[jA]) ? A_diag_data[jA] : row_scale;
          row_sum += A_diag_data[jA];
        }
        for (jA = A_offd_i[i]; jA < (A_offd_i[i + 1]); jA++) {
          row_scale = row_scale < (A_offd_data[jA]) ? A_offd_data[jA] : row_scale;
          row_sum += A_offd_data[jA];
        }
      }
      else {
        for (jA = (A_diag_i[i]) + 1; jA < (A_diag_i[i + 1]); jA++) {
          row_scale = row_scale < (A_diag_data[jA]) ? row_scale : A_diag_data[jA];
          row_sum += A_diag_data[jA];
        }
        for (jA = A_offd_i[i]; jA < (A_offd_i[i + 1]); jA++) {
          row_scale = row_scale < (A_offd_data[jA]) ? row_scale : A_offd_data[jA];
          row_sum += A_offd_data[jA];
        }
      }
    }
    row_sum = fabs(row_sum / diag);
    S_diag_j[A_diag_i[i]] = -1;
    if ((row_sum > max_row_sum) && (max_row_sum < 1.0)) {
      for (jA = (A_diag_i[i]) + 1; jA < (A_diag_i[i + 1]); jA++) {
        S_diag_j[jA] = -1;
      }
      for (jA = A_offd_i[i]; jA < (A_offd_i[i + 1]); jA++) {
        S_offd_j[jA] = -1;
      }
    }
    else {
      if (num_functions > 1) {
        if (diag < 0) {
          for (jA = (A_diag_i[i]) + 1; jA < (A_diag_i[i + 1]); jA++) {
            if (((A_diag_data[jA]) <= (strength_threshold * row_scale)) || ((dof_func[i]) != (dof_func[A_diag_j[jA]]))) {
              S_diag_j[jA] = -1;
            }
          }
          for (jA = A_offd_i[i]; jA < (A_offd_i[i + 1]); jA++) {
            if (((A_offd_data[jA]) <= (strength_threshold * row_scale)) || ((dof_func[i]) != (dof_func_offd[A_offd_j[jA]]))) {
              S_offd_j[jA] = -1;
            }
          }
        }
        else {
          for (jA = (A_diag_i[i]) + 1; jA < (A_diag_i[i + 1]); jA++) {
            if (((A_diag_data[jA]) >= (strength_threshold * row_scale)) || ((dof_func[i]) != (dof_func[A_diag_j[jA]]))) {
              S_diag_j[jA] = -1;
            }
          }
          for (jA = A_offd_i[i]; jA < (A_offd_i[i + 1]); jA++) {
            if (((A_offd_data[jA]) >= (strength_threshold * row_scale)) || ((dof_func[i]) != (dof_func_offd[A_offd_j[jA]]))) {
              S_offd_j[jA] = -1;
            }
          }
        }
      }
      else {
        if (diag < 0) {
          for (jA = (A_diag_i[i]) + 1; jA < (A_diag_i[i + 1]); jA++) {
            if ((A_diag_data[jA]) <= (strength_threshold * row_scale)) {
              S_diag_j[jA] = -1;
            }
          }
          for (jA = A_offd_i[i]; jA < (A_offd_i[i + 1]); jA++) {
            if ((A_offd_data[jA]) <= (strength_threshold * row_scale)) {
              S_offd_j[jA] = -1;
            }
          }
        }
        else {
          for (jA = (A_diag_i[i]) + 1; jA < (A_diag_i[i + 1]); jA++) {
            if ((A_diag_data[jA]) >= (strength_threshold * row_scale)) {
              S_diag_j[jA] = -1;
            }
          }
          for (jA = A_offd_i[i]; jA < (A_offd_i[i + 1]); jA++) {
            if ((A_offd_data[jA]) >= (strength_threshold * row_scale)) {
              S_offd_j[jA] = -1;
            }
          }
        }
      }
    }
  }
  jS = 0;
  for (i = 0; i < num_variables; i++) {
    S_diag_i[i] = jS;
    for (jA = A_diag_i[i]; jA < (A_diag_i[i + 1]); jA++) {
      if ((S_diag_j[jA]) > (-1)) {
        S_diag_j[jS] = S_diag_j[jA];
        jS++;
      }
    }
  }
  S_diag_i[num_variables] = jS;
  (S_diag)->num_nonzeros = jS;
  jS = 0;
  for (i = 0; i < num_variables; i++) {
    S_offd_i[i] = jS;
    for (jA = A_offd_i[i]; jA < (A_offd_i[i + 1]); jA++) {
      if ((S_offd_j[jA]) > (-1)) {
        S_offd_j[jS] = S_offd_j[jA];
        jS++;
      }
    }
  }
  S_offd_i[num_variables] = jS;
  (S_offd)->num_nonzeros = jS;
  (S)->comm_pkg = (void*)0;
  *S_ptr = S;
  hypre_Free((char*)dof_func_offd), dof_func_offd = (void*)0;
  return ierr;
}
int hypre_BoomerAMGCreateSabs(hypre_ParCSRMatrix* A, double strength_threshold, double max_row_sum, int num_functions, int* dof_func, hypre_ParCSRMatrix** S_ptr) {
  MPI_Comm comm = (A)->comm;
  hypre_ParCSRCommPkg* comm_pkg = (A)->comm_pkg;
  hypre_ParCSRCommHandle* comm_handle;
  hypre_CSRMatrix* A_diag = (A)->diag;
  int* A_diag_i = (A_diag)->i;
  double* A_diag_data = (A_diag)->data;
  hypre_CSRMatrix* A_offd = (A)->offd;
  int* A_offd_i = (A_offd)->i;
  double* A_offd_data;
  int* A_diag_j = (A_diag)->j;
  int* A_offd_j = (A_offd)->j;
  int* row_starts = (A)->row_starts;
  int num_variables = (A_diag)->num_rows;
  int global_num_vars = (A)->global_num_rows;
  int num_nonzeros_diag;
  int num_nonzeros_offd = 0;
  int num_cols_offd = 0;
  hypre_ParCSRMatrix* S;
  hypre_CSRMatrix* S_diag;
  int* S_diag_i;
  int* S_diag_j;
  hypre_CSRMatrix* S_offd;
  int* S_offd_i;
  int* S_offd_j;
  double diag;
  double row_scale;
  double row_sum;
  int i;
  int jA;
  int jS;
  int ierr = 0;
  int* dof_func_offd;
  int num_sends;
  int* int_buf_data;
  int index;
  int start;
  int j;
  num_nonzeros_diag = A_diag_i[num_variables];
  num_cols_offd = (A_offd)->num_cols;
  A_offd_i = (A_offd)->i;
  num_nonzeros_offd = A_offd_i[num_variables];
  S = hypre_ParCSRMatrixCreate(comm, global_num_vars, global_num_vars, row_starts, row_starts, num_cols_offd, num_nonzeros_diag, num_nonzeros_offd);
  hypre_ParCSRMatrixSetRowStartsOwner(S, 0);
  S_diag = (S)->diag;
  (S_diag)->i = (int*)(hypre_CAlloc((unsigned)(num_variables + 1), (unsigned)(sizeof(int))));
  (S_diag)->j = (int*)(hypre_CAlloc((unsigned)num_nonzeros_diag, (unsigned)(sizeof(int))));
  S_offd = (S)->offd;
  (S_offd)->i = (int*)(hypre_CAlloc((unsigned)(num_variables + 1), (unsigned)(sizeof(int))));
  S_diag_i = (S_diag)->i;
  S_diag_j = (S_diag)->j;
  S_offd_i = (S_offd)->i;
  dof_func_offd = (void*)0;
  if (num_cols_offd) {
    A_offd_data = (A_offd)->data;
    (S_offd)->j = (int*)(hypre_CAlloc((unsigned)num_nonzeros_offd, (unsigned)(sizeof(int))));
    S_offd_j = (S_offd)->j;
    (S)->col_map_offd = (int*)(hypre_CAlloc((unsigned)num_cols_offd, (unsigned)(sizeof(int))));
    if (num_functions > 1)
      dof_func_offd = (int*)(hypre_CAlloc((unsigned)num_cols_offd, (unsigned)(sizeof(int))));
  }
  if (!comm_pkg) {
    hypre_MatvecCommPkgCreate(A);
    comm_pkg = (A)->comm_pkg;
  }
  num_sends = (comm_pkg)->num_sends;
  if (num_functions > 1) {
    int_buf_data = (int*)(hypre_CAlloc((unsigned)((comm_pkg)->send_map_starts[num_sends]), (unsigned)(sizeof(int))));
    index = 0;
    for (i = 0; i < num_sends; i++) {
      start = (comm_pkg)->send_map_starts[i];
      for (j = start; j < ((comm_pkg)->send_map_starts[i + 1]); j++)
        int_buf_data[index++] = dof_func[(comm_pkg)->send_map_elmts[j]];
    }
    comm_handle = hypre_ParCSRCommHandleCreate(11, comm_pkg, int_buf_data, dof_func_offd);
    hypre_ParCSRCommHandleDestroy(comm_handle);
    hypre_Free((char*)int_buf_data), int_buf_data = (void*)0;
  }
  hypre_ParCSRMatrixCopy(A, S, 0);
  for (i = 0; i < num_variables; i++) {
    diag = A_diag_data[A_diag_i[i]];
    row_scale = 0.0;
    row_sum = diag;
    if (num_functions > 1) {
      for (jA = (A_diag_i[i]) + 1; jA < (A_diag_i[i + 1]); jA++) {
        if ((dof_func[i]) == (dof_func[A_diag_j[jA]])) {
          row_scale = row_scale < fabs(A_diag_data[jA]) ? fabs(A_diag_data[jA]) : row_scale;
          row_sum += fabs(A_diag_data[jA]);
        }
      }
      for (jA = A_offd_i[i]; jA < (A_offd_i[i + 1]); jA++) {
        if ((dof_func[i]) == (dof_func_offd[A_offd_j[jA]])) {
          row_scale = row_scale < fabs(A_offd_data[jA]) ? fabs(A_offd_data[jA]) : row_scale;
          row_sum += fabs(A_offd_data[jA]);
        }
      }
    }
    else {
      for (jA = (A_diag_i[i]) + 1; jA < (A_diag_i[i + 1]); jA++) {
        row_scale = row_scale < fabs(A_diag_data[jA]) ? fabs(A_diag_data[jA]) : row_scale;
        row_sum += fabs(A_diag_data[jA]);
      }
      for (jA = A_offd_i[i]; jA < (A_offd_i[i + 1]); jA++) {
        row_scale = row_scale < fabs(A_offd_data[jA]) ? fabs(A_offd_data[jA]) : row_scale;
        row_sum += fabs(A_offd_data[jA]);
      }
    }
    row_sum = fabs(row_sum / diag);
    S_diag_j[A_diag_i[i]] = -1;
    if ((row_sum > max_row_sum) && (max_row_sum < 1.0)) {
      for (jA = (A_diag_i[i]) + 1; jA < (A_diag_i[i + 1]); jA++) {
        S_diag_j[jA] = -1;
      }
      for (jA = A_offd_i[i]; jA < (A_offd_i[i + 1]); jA++) {
        S_offd_j[jA] = -1;
      }
    }
    else {
      if (num_functions > 1) {
        for (jA = (A_diag_i[i]) + 1; jA < (A_diag_i[i + 1]); jA++) {
          if ((fabs(A_diag_data[jA]) <= (strength_threshold * row_scale)) || ((dof_func[i]) != (dof_func[A_diag_j[jA]]))) {
            S_diag_j[jA] = -1;
          }
        }
        for (jA = A_offd_i[i]; jA < (A_offd_i[i + 1]); jA++) {
          if ((fabs(A_offd_data[jA]) <= (strength_threshold * row_scale)) || ((dof_func[i]) != (dof_func_offd[A_offd_j[jA]]))) {
            S_offd_j[jA] = -1;
          }
        }
      }
      else {
        for (jA = (A_diag_i[i]) + 1; jA < (A_diag_i[i + 1]); jA++) {
          if (fabs(A_diag_data[jA]) <= (strength_threshold * row_scale)) {
            S_diag_j[jA] = -1;
          }
        }
        for (jA = A_offd_i[i]; jA < (A_offd_i[i + 1]); jA++) {
          if (fabs(A_offd_data[jA]) <= (strength_threshold * row_scale)) {
            S_offd_j[jA] = -1;
          }
        }
      }
    }
  }
  jS = 0;
  for (i = 0; i < num_variables; i++) {
    S_diag_i[i] = jS;
    for (jA = A_diag_i[i]; jA < (A_diag_i[i + 1]); jA++) {
      if ((S_diag_j[jA]) > (-1)) {
        S_diag_j[jS] = S_diag_j[jA];
        jS++;
      }
    }
  }
  S_diag_i[num_variables] = jS;
  (S_diag)->num_nonzeros = jS;
  jS = 0;
  for (i = 0; i < num_variables; i++) {
    S_offd_i[i] = jS;
    for (jA = A_offd_i[i]; jA < (A_offd_i[i + 1]); jA++) {
      if ((S_offd_j[jA]) > (-1)) {
        S_offd_j[jS] = S_offd_j[jA];
        jS++;
      }
    }
  }
  S_offd_i[num_variables] = jS;
  (S_offd)->num_nonzeros = jS;
  (S)->comm_pkg = (void*)0;
  *S_ptr = S;
  hypre_Free((char*)dof_func_offd), dof_func_offd = (void*)0;
  return ierr;
}
int hypre_BoomerAMGCreateSCommPkg(hypre_ParCSRMatrix* A, hypre_ParCSRMatrix* S, int** col_offd_S_to_A_ptr) {
  MPI_Comm comm = (A)->comm;
  MPI_Status* status;
  MPI_Request* requests;
  hypre_ParCSRCommPkg* comm_pkg_A = (A)->comm_pkg;
  hypre_ParCSRCommPkg* comm_pkg_S;
  hypre_ParCSRCommHandle* comm_handle;
  hypre_CSRMatrix* A_offd = (A)->offd;
  int* col_map_offd_A = (A)->col_map_offd;
  hypre_CSRMatrix* S_diag = (S)->diag;
  hypre_CSRMatrix* S_offd = (S)->offd;
  int* S_offd_i = (S_offd)->i;
  int* S_offd_j = (S_offd)->j;
  int* col_map_offd_S = (S)->col_map_offd;
  int* recv_procs_A = (comm_pkg_A)->recv_procs;
  int* recv_vec_starts_A = (comm_pkg_A)->recv_vec_starts;
  int* send_procs_A = (comm_pkg_A)->send_procs;
  int* send_map_starts_A = (comm_pkg_A)->send_map_starts;
  int* recv_procs_S;
  int* recv_vec_starts_S;
  int* send_procs_S;
  int* send_map_starts_S;
  int* send_map_elmts_S = (void*)0;
  int* big_send_map_elmts_S = (void*)0;
  int* col_offd_S_to_A;
  int* S_marker;
  int* send_change;
  int* recv_change;
  int num_variables = (S_diag)->num_rows;
  int num_cols_offd_A = (A_offd)->num_cols;
  int num_cols_offd_S;
  int i;
  int j;
  int jcol;
  int proc;
  int cnt;
  int proc_cnt;
  int total_nz;
  int first_row;
  int ierr = 0;
  int num_sends_A = (comm_pkg_A)->num_sends;
  int num_recvs_A = (comm_pkg_A)->num_recvs;
  int num_sends_S;
  int num_recvs_S;
  int num_nonzeros;
  num_nonzeros = S_offd_i[num_variables];
  S_marker = (void*)0;
  if (num_cols_offd_A)
    S_marker = (int*)(hypre_CAlloc((unsigned)num_cols_offd_A, (unsigned)(sizeof(int))));
  for (i = 0; i < num_cols_offd_A; i++)
    S_marker[i] = -1;
  for (i = 0; i < num_nonzeros; i++) {
    jcol = S_offd_j[i];
    S_marker[jcol] = 0;
  }
  proc = 0;
  proc_cnt = 0;
  cnt = 0;
  num_recvs_S = 0;
  for (i = 0; i < num_recvs_A; i++) {
    for (j = recv_vec_starts_A[i]; j < (recv_vec_starts_A[i + 1]); j++) {
      if (!(S_marker[j])) {
        S_marker[j] = cnt;
        cnt++;
        proc = 1;
      }
    }
    if (proc) {
      num_recvs_S++;
      proc = 0;
    }
  }
  num_cols_offd_S = cnt;
  recv_change = (void*)0;
  recv_procs_S = (void*)0;
  send_change = (void*)0;
  if (col_map_offd_S)
    hypre_Free((char*)col_map_offd_S), col_map_offd_S = (void*)0;
  col_map_offd_S = (void*)0;
  col_offd_S_to_A = (void*)0;
  if (num_recvs_A)
    recv_change = (int*)(hypre_CAlloc((unsigned)num_recvs_A, (unsigned)(sizeof(int))));
  if (num_sends_A)
    send_change = (int*)(hypre_CAlloc((unsigned)num_sends_A, (unsigned)(sizeof(int))));
  if (num_recvs_S)
    recv_procs_S = (int*)(hypre_CAlloc((unsigned)num_recvs_S, (unsigned)(sizeof(int))));
  recv_vec_starts_S = (int*)(hypre_CAlloc((unsigned)(num_recvs_S + 1), (unsigned)(sizeof(int))));
  if (num_cols_offd_S) {
    col_map_offd_S = (int*)(hypre_CAlloc((unsigned)num_cols_offd_S, (unsigned)(sizeof(int))));
    col_offd_S_to_A = (int*)(hypre_CAlloc((unsigned)num_cols_offd_S, (unsigned)(sizeof(int))));
  }
  if (num_cols_offd_S < num_cols_offd_A) {
    for (i = 0; i < num_nonzeros; i++) {
      jcol = S_offd_j[i];
      S_offd_j[i] = S_marker[jcol];
    }
    proc = 0;
    proc_cnt = 0;
    cnt = 0;
    recv_vec_starts_S[0] = 0;
    for (i = 0; i < num_recvs_A; i++) {
      for (j = recv_vec_starts_A[i]; j < (recv_vec_starts_A[i + 1]); j++) {
        if ((S_marker[j]) != (-1)) {
          col_map_offd_S[cnt] = col_map_offd_A[j];
          col_offd_S_to_A[cnt++] = j;
          proc = 1;
        }
      }
      recv_change[i] = ((j - cnt) - (recv_vec_starts_A[i])) + (recv_vec_starts_S[proc_cnt]);
      if (proc) {
        recv_procs_S[proc_cnt++] = recv_procs_A[i];
        recv_vec_starts_S[proc_cnt] = cnt;
        proc = 0;
      }
    }
  }
  else {
    for (i = 0; i < num_recvs_A; i++) {
      for (j = recv_vec_starts_A[i]; j < (recv_vec_starts_A[i + 1]); j++) {
        col_map_offd_S[j] = col_map_offd_A[j];
        col_offd_S_to_A[j] = j;
      }
      recv_procs_S[i] = recv_procs_A[i];
      recv_vec_starts_S[i] = recv_vec_starts_A[i];
    }
    recv_vec_starts_S[num_recvs_A] = recv_vec_starts_A[num_recvs_A];
  }
  requests = (MPI_Request*)(hypre_CAlloc((unsigned)(num_sends_A + num_recvs_A), (unsigned)(sizeof(MPI_Request))));
  j = 0;
  for (i = 0; i < num_sends_A; i++)
    MPI_Irecv(&(send_change[i]), 1, MPI_INT, send_procs_A[i], 0, comm, &(requests[j++]));
  for (i = 0; i < num_recvs_A; i++)
    MPI_Isend(&(recv_change[i]), 1, MPI_INT, recv_procs_A[i], 0, comm, &(requests[j++]));
  status = (MPI_Status*)(hypre_CAlloc((unsigned)j, (unsigned)(sizeof(MPI_Status))));
  MPI_Waitall(j, requests, status);
  hypre_Free((char*)status), status = (void*)0;
  hypre_Free((char*)requests), requests = (void*)0;
  num_sends_S = 0;
  total_nz = send_map_starts_A[num_sends_A];
  for (i = 0; i < num_sends_A; i++) {
    if (send_change[i]) {
      if (((send_map_starts_A[i + 1]) - (send_map_starts_A[i])) > (send_change[i]))
        num_sends_S++;
    }
    else
      num_sends_S++;
    total_nz -= (send_change[i]);
  }
  send_procs_S = (void*)0;
  if (num_sends_S)
    send_procs_S = (int*)(hypre_CAlloc((unsigned)num_sends_S, (unsigned)(sizeof(int))));
  send_map_starts_S = (int*)(hypre_CAlloc((unsigned)(num_sends_S + 1), (unsigned)(sizeof(int))));
  send_map_elmts_S = (void*)0;
  if (total_nz) {
    send_map_elmts_S = (int*)(hypre_CAlloc((unsigned)total_nz, (unsigned)(sizeof(int))));
    big_send_map_elmts_S = (int*)(hypre_CAlloc((unsigned)total_nz, (unsigned)(sizeof(int))));
  }
  proc = 0;
  proc_cnt = 0;
  for (i = 0; i < num_sends_A; i++) {
    cnt = ((send_map_starts_A[i + 1]) - (send_map_starts_A[i])) - (send_change[i]);
    if (cnt) {
      send_procs_S[proc_cnt++] = send_procs_A[i];
      send_map_starts_S[proc_cnt] = (send_map_starts_S[proc_cnt - 1]) + cnt;
    }
  }
  comm_pkg_S = (hypre_ParCSRCommPkg*)(hypre_CAlloc((unsigned)1, (unsigned)(sizeof(hypre_ParCSRCommPkg))));
  (comm_pkg_S)->comm = comm;
  (comm_pkg_S)->num_recvs = num_recvs_S;
  (comm_pkg_S)->recv_procs = recv_procs_S;
  (comm_pkg_S)->recv_vec_starts = recv_vec_starts_S;
  (comm_pkg_S)->num_sends = num_sends_S;
  (comm_pkg_S)->send_procs = send_procs_S;
  (comm_pkg_S)->send_map_starts = send_map_starts_S;
  comm_handle = hypre_ParCSRCommHandleCreate(22, comm_pkg_S, col_map_offd_S, big_send_map_elmts_S);
  hypre_ParCSRCommHandleDestroy(comm_handle);
  first_row = (A)->first_row_index;
  if (first_row)
    for (i = 0; i < (send_map_starts_S[num_sends_S]); i++)
      send_map_elmts_S[i] = (int)((big_send_map_elmts_S[i]) - first_row);
  (comm_pkg_S)->send_map_elmts = send_map_elmts_S;
  (S)->comm_pkg = comm_pkg_S;
  (S)->col_map_offd = col_map_offd_S;
  (S_offd)->num_cols = num_cols_offd_S;
  hypre_Free((char*)S_marker), S_marker = (void*)0;
  hypre_Free((char*)send_change), send_change = (void*)0;
  hypre_Free((char*)recv_change), recv_change = (void*)0;
  hypre_Free((char*)big_send_map_elmts_S), big_send_map_elmts_S = (void*)0;
  *col_offd_S_to_A_ptr = col_offd_S_to_A;
  return ierr;
}
int hypre_BoomerAMGCreate2ndS(hypre_ParCSRMatrix* S, int* CF_marker, int num_paths, int* coarse_row_starts, hypre_ParCSRMatrix** C_ptr) {
  MPI_Comm comm = (S)->comm;
  hypre_ParCSRCommPkg* comm_pkg = (S)->comm_pkg;
  hypre_ParCSRCommPkg* tmp_comm_pkg;
  hypre_ParCSRCommHandle* comm_handle;
  hypre_CSRMatrix* S_diag = (S)->diag;
  int* S_diag_i = (S_diag)->i;
  int* S_diag_j = (S_diag)->j;
  hypre_CSRMatrix* S_offd = (S)->offd;
  int* S_offd_i = (S_offd)->i;
  int* S_offd_j = (S_offd)->j;
  int num_cols_diag_S = (S_diag)->num_cols;
  int num_cols_offd_S = (S_offd)->num_cols;
  hypre_ParCSRMatrix* S2;
  int* col_map_offd_C = (void*)0;
  hypre_CSRMatrix* C_diag;
  int* C_diag_data = (void*)0;
  int* C_diag_i;
  int* C_diag_j = (void*)0;
  hypre_CSRMatrix* C_offd;
  int* C_offd_data = (void*)0;
  int* C_offd_i;
  int* C_offd_j = (void*)0;
  int C_diag_size;
  int C_offd_size;
  int num_cols_offd_C = 0;
  int* S_ext_diag_i = (void*)0;
  int* S_ext_diag_j = (void*)0;
  int S_ext_diag_size = 0;
  int* S_ext_offd_i = (void*)0;
  int* S_ext_offd_j = (void*)0;
  int S_ext_offd_size = 0;
  int* CF_marker_offd = (void*)0;
  int* S_marker = (void*)0;
  int* S_marker_offd = (void*)0;
  int* fine_to_coarse = (void*)0;
  int* big_fine_to_coarse_offd = (void*)0;
  int* map_S_to_C = (void*)0;
  int num_sends = 0;
  int num_recvs = 0;
  int* send_map_starts;
  int* tmp_send_map_starts = (void*)0;
  int* send_map_elmts;
  int* recv_vec_starts;
  int* tmp_recv_vec_starts = (void*)0;
  int* int_buf_data = (void*)0;
  int* big_int_buf_data = (void*)0;
  int* temp = (void*)0;
  int i;
  int j;
  int k;
  int i1;
  int i2;
  int i3;
  int big_i1;
  int jj1;
  int jj2;
  int jcol;
  int jrow;
  int j_cnt;
  int jj_count_diag;
  int jj_count_offd;
  int jj_row_begin_diag;
  int jj_row_begin_offd;
  int cnt;
  int cnt_offd;
  int cnt_diag;
  int num_procs;
  int my_id;
  int index;
  int value;
  int num_coarse;
  int num_coarse_offd;
  int num_nonzeros;
  int num_nonzeros_diag;
  int num_nonzeros_offd;
  int num_nnz_diag;
  int num_nnz_offd;
  int num_threads;
  int ns;
  int ne;
  int rest;
  int size;
  int* ns_thr;
  int* ne_thr;
  int* nnz;
  int* nnz_offd;
  int* cnt_coarse;
  int global_num_coarse;
  int my_first_cpt;
  int my_last_cpt;
  int* S_int_i = (void*)0;
  int* S_int_j = (void*)0;
  int* S_ext_i = (void*)0;
  int* S_ext_j = (void*)0;
  MPI_Comm_size(comm, &(num_procs));
  MPI_Comm_rank(comm, &(my_id));
  num_threads = 1;
  my_first_cpt = coarse_row_starts[my_id];
  my_last_cpt = (coarse_row_starts[my_id + 1]) - 1;
  global_num_coarse = coarse_row_starts[num_procs];
  if (num_cols_offd_S) {
    CF_marker_offd = (int*)(hypre_CAlloc((unsigned)num_cols_offd_S, (unsigned)(sizeof(int))));
    big_fine_to_coarse_offd = (int*)(hypre_CAlloc((unsigned)num_cols_offd_S, (unsigned)(sizeof(int))));
  }
  if (num_cols_diag_S)
    fine_to_coarse = (int*)(hypre_CAlloc((unsigned)num_cols_diag_S, (unsigned)(sizeof(int))));
  num_coarse = 0;
  for (i = 0; i < num_cols_diag_S; i++) {
    if ((CF_marker[i]) > 0) {
      fine_to_coarse[i] = num_coarse;
      num_coarse++;
    }
    else {
      fine_to_coarse[i] = -1;
    }
  }
  if (num_procs > 1) {
    if (!comm_pkg) {
      hypre_MatvecCommPkgCreate(S);
      comm_pkg = (S)->comm_pkg;
    }
    num_sends = (comm_pkg)->num_sends;
    send_map_starts = (comm_pkg)->send_map_starts;
    send_map_elmts = (comm_pkg)->send_map_elmts;
    num_recvs = (comm_pkg)->num_recvs;
    recv_vec_starts = (comm_pkg)->recv_vec_starts;
    big_int_buf_data = (int*)(hypre_CAlloc((unsigned)(send_map_starts[num_sends]), (unsigned)(sizeof(int))));
    index = 0;
    for (i = 0; i < num_sends; i++) {
      for (j = send_map_starts[i]; j < (send_map_starts[i + 1]); j++)
        big_int_buf_data[index++] = my_first_cpt + (int)(fine_to_coarse[send_map_elmts[j]]);
    }
    comm_handle = hypre_ParCSRCommHandleCreate(21, comm_pkg, big_int_buf_data, big_fine_to_coarse_offd);
    hypre_ParCSRCommHandleDestroy(comm_handle);
    hypre_Free((char*)big_int_buf_data), big_int_buf_data = (void*)0;
    int_buf_data = (int*)(hypre_CAlloc((unsigned)(send_map_starts[num_sends]), (unsigned)(sizeof(int))));
    index = 0;
    for (i = 0; i < num_sends; i++) {
      for (j = send_map_starts[i]; j < (send_map_starts[i + 1]); j++) {
        int_buf_data[index++] = CF_marker[send_map_elmts[j]];
      }
    }
    comm_handle = hypre_ParCSRCommHandleCreate(11, comm_pkg, int_buf_data, CF_marker_offd);
    hypre_ParCSRCommHandleDestroy(comm_handle);
    hypre_Free((char*)int_buf_data), int_buf_data = (void*)0;
    S_int_i = (int*)(hypre_CAlloc((unsigned)((send_map_starts[num_sends]) + 1), (unsigned)(sizeof(int))));
    S_ext_i = (int*)(hypre_CAlloc((unsigned)((recv_vec_starts[num_recvs]) + 1), (unsigned)(sizeof(int))));
    S_int_i[0] = 0;
    j_cnt = 0;
    num_nonzeros = 0;
    for (i = 0; i < num_sends; i++) {
      for (j = send_map_starts[i]; j < (send_map_starts[i + 1]); j++) {
        jrow = send_map_elmts[j];
        index = 0;
        for (k = S_diag_i[jrow]; k < (S_diag_i[jrow + 1]); k++) {
          if ((CF_marker[S_diag_j[k]]) > 0)
            index++;
        }
        for (k = S_offd_i[jrow]; k < (S_offd_i[jrow + 1]); k++) {
          if ((CF_marker_offd[S_offd_j[k]]) > 0)
            index++;
        }
        S_int_i[++j_cnt] = index;
        num_nonzeros += S_int_i[j_cnt];
      }
    }
    if (num_procs > 1)
      comm_handle = hypre_ParCSRCommHandleCreate(11, comm_pkg, &(S_int_i[1]), &(S_ext_i[1]));
    if (num_nonzeros)
      S_int_j = (int*)(hypre_CAlloc((unsigned)num_nonzeros, (unsigned)(sizeof(int))));
    tmp_send_map_starts = (int*)(hypre_CAlloc((unsigned)(num_sends + 1), (unsigned)(sizeof(int))));
    tmp_recv_vec_starts = (int*)(hypre_CAlloc((unsigned)(num_recvs + 1), (unsigned)(sizeof(int))));
    tmp_send_map_starts[0] = 0;
    j_cnt = 0;
    for (i = 0; i < num_sends; i++) {
      for (j = send_map_starts[i]; j < (send_map_starts[i + 1]); j++) {
        jrow = send_map_elmts[j];
        for (k = S_diag_i[jrow]; k < (S_diag_i[jrow + 1]); k++) {
          if ((CF_marker[S_diag_j[k]]) > 0)
            S_int_j[j_cnt++] = (int)(fine_to_coarse[S_diag_j[k]]) + my_first_cpt;
        }
        for (k = S_offd_i[jrow]; k < (S_offd_i[jrow + 1]); k++) {
          if ((CF_marker_offd[S_offd_j[k]]) > 0)
            S_int_j[j_cnt++] = big_fine_to_coarse_offd[S_offd_j[k]];
        }
      }
      tmp_send_map_starts[i + 1] = j_cnt;
    }
    tmp_comm_pkg = (hypre_ParCSRCommPkg*)(hypre_CAlloc((unsigned)1, (unsigned)(sizeof(hypre_ParCSRCommPkg))));
    (tmp_comm_pkg)->comm = comm;
    (tmp_comm_pkg)->num_sends = num_sends;
    (tmp_comm_pkg)->num_recvs = num_recvs;
    (tmp_comm_pkg)->send_procs = (comm_pkg)->send_procs;
    (tmp_comm_pkg)->recv_procs = (comm_pkg)->recv_procs;
    (tmp_comm_pkg)->send_map_starts = tmp_send_map_starts;
    hypre_ParCSRCommHandleDestroy(comm_handle);
    comm_handle = (void*)0;
    for (i = 0; i < (recv_vec_starts[num_recvs]); i++)
      S_ext_i[i + 1] += S_ext_i[i];
    num_nonzeros = S_ext_i[recv_vec_starts[num_recvs]];
    if (num_nonzeros)
      S_ext_j = (int*)(hypre_CAlloc((unsigned)num_nonzeros, (unsigned)(sizeof(int))));
    tmp_recv_vec_starts[0] = 0;
    for (i = 0; i < num_recvs; i++)
      tmp_recv_vec_starts[i + 1] = S_ext_i[recv_vec_starts[i + 1]];
    (tmp_comm_pkg)->recv_vec_starts = tmp_recv_vec_starts;
    comm_handle = hypre_ParCSRCommHandleCreate(21, tmp_comm_pkg, S_int_j, S_ext_j);
    hypre_ParCSRCommHandleDestroy(comm_handle);
    comm_handle = (void*)0;
    hypre_Free((char*)tmp_send_map_starts), tmp_send_map_starts = (void*)0;
    hypre_Free((char*)tmp_recv_vec_starts), tmp_recv_vec_starts = (void*)0;
    hypre_Free((char*)tmp_comm_pkg), tmp_comm_pkg = (void*)0;
    hypre_Free((char*)S_int_i), S_int_i = (void*)0;
    hypre_Free((char*)S_int_j), S_int_j = (void*)0;
    S_ext_diag_size = 0;
    S_ext_offd_size = 0;
    for (i = 0; i < num_cols_offd_S; i++) {
      for (j = S_ext_i[i]; j < (S_ext_i[i + 1]); j++) {
        if (((S_ext_j[j]) < my_first_cpt) || ((S_ext_j[j]) > my_last_cpt))
          S_ext_offd_size++;
        else
          S_ext_diag_size++;
      }
    }
    S_ext_diag_i = (int*)(hypre_CAlloc((unsigned)(num_cols_offd_S + 1), (unsigned)(sizeof(int))));
    S_ext_offd_i = (int*)(hypre_CAlloc((unsigned)(num_cols_offd_S + 1), (unsigned)(sizeof(int))));
    if (S_ext_diag_size) {
      S_ext_diag_j = (int*)(hypre_CAlloc((unsigned)S_ext_diag_size, (unsigned)(sizeof(int))));
    }
    if (S_ext_offd_size) {
      S_ext_offd_j = (int*)(hypre_CAlloc((unsigned)S_ext_offd_size, (unsigned)(sizeof(int))));
    }
    cnt_offd = 0;
    cnt_diag = 0;
    cnt = 0;
    num_coarse_offd = 0;
    for (i = 0; i < num_cols_offd_S; i++) {
      if ((CF_marker_offd[i]) > 0)
        num_coarse_offd++;
      for (j = S_ext_i[i]; j < (S_ext_i[i + 1]); j++) {
        big_i1 = S_ext_j[j];
        if ((big_i1 < my_first_cpt) || (big_i1 > my_last_cpt))
          S_ext_j[cnt_offd++] = big_i1;
        else
          S_ext_diag_j[cnt_diag++] = (int)(big_i1 - my_first_cpt);
      }
      S_ext_diag_i[++cnt] = cnt_diag;
      S_ext_offd_i[cnt] = cnt_offd;
    }
    hypre_Free((char*)S_ext_i), S_ext_i = (void*)0;
    if (S_ext_offd_size || num_coarse_offd)
      temp = (int*)(hypre_CAlloc((unsigned)(S_ext_offd_size + num_coarse_offd), (unsigned)(sizeof(int))));
    for (i = 0; i < S_ext_offd_size; i++)
      temp[i] = S_ext_j[i];
    cnt = S_ext_offd_size;
    for (i = 0; i < num_cols_offd_S; i++)
      if ((CF_marker_offd[i]) > 0)
        temp[cnt++] = big_fine_to_coarse_offd[i];
    if (cnt) {
      hypre_BigQsort0(temp, 0, cnt - 1);
      num_cols_offd_C = 1;
      value = temp[0];
      for (i = 1; i < cnt; i++) {
        if ((temp[i]) > value) {
          value = temp[i];
          temp[num_cols_offd_C++] = value;
        }
      }
    }
    if (num_cols_offd_C)
      col_map_offd_C = (int*)(hypre_CAlloc((unsigned)num_cols_offd_C, (unsigned)(sizeof(int))));
    for (i = 0; i < num_cols_offd_C; i++)
      col_map_offd_C[i] = temp[i];
    hypre_Free((char*)temp), temp = (void*)0;
    for (i = 0; i < S_ext_offd_size; i++)
      S_ext_offd_j[i] = hypre_BigBinarySearch(col_map_offd_C, S_ext_j[i], num_cols_offd_C);
    hypre_Free((char*)S_ext_j), S_ext_j = (void*)0;
    if (num_cols_offd_S) {
      map_S_to_C = (int*)(hypre_CAlloc((unsigned)num_cols_offd_S, (unsigned)(sizeof(int))));
      cnt = 0;
      for (i = 0; i < num_cols_offd_S; i++) {
        if ((CF_marker_offd[i]) > 0) {
          while ((big_fine_to_coarse_offd[i]) > (col_map_offd_C[cnt])) {
            cnt++;
          }
          map_S_to_C[i] = cnt++;
        }
        else {
          map_S_to_C[i] = -1;
        }
      }
    }
  }
  C_diag_i = (int*)(hypre_CAlloc((unsigned)(num_coarse + 1), (unsigned)(sizeof(int))));
  C_offd_i = (int*)(hypre_CAlloc((unsigned)(num_coarse + 1), (unsigned)(sizeof(int))));
  cnt = 0;
  num_nonzeros_diag = 0;
  num_nonzeros_offd = 0;
  ns_thr = (int*)(hypre_CAlloc((unsigned)num_threads, (unsigned)(sizeof(int))));
  ne_thr = (int*)(hypre_CAlloc((unsigned)num_threads, (unsigned)(sizeof(int))));
  nnz = (int*)(hypre_CAlloc((unsigned)num_threads, (unsigned)(sizeof(int))));
  nnz_offd = (int*)(hypre_CAlloc((unsigned)num_threads, (unsigned)(sizeof(int))));
  cnt_coarse = (int*)(hypre_CAlloc((unsigned)num_threads, (unsigned)(sizeof(int))));
  size = num_cols_diag_S / num_threads;
  rest = num_cols_diag_S - (size * num_threads);
  for (k = 0; k < num_threads; k++) {
    if (k < rest) {
      ns_thr[k] = (k * size) + k;
      ne_thr[k] = (((k + 1) * size) + k) + 1;
    }
    else {
      ns_thr[k] = (k * size) + rest;
      ne_thr[k] = ((k + 1) * size) + rest;
    }
  }
  for (k = 0; k < num_threads; k++) {
    ns = ns_thr[k];
    ne = ne_thr[k];
    num_nnz_diag = 0;
    num_nnz_offd = 0;
    cnt_coarse[k] = 0;
    S_marker = (void*)0;
    if (num_coarse)
      S_marker = (int*)(hypre_CAlloc((unsigned)num_coarse, (unsigned)(sizeof(int))));
    for (i1 = 0; i1 < num_coarse; i1++)
      S_marker[i1] = -1;
    S_marker_offd = (void*)0;
    if (num_cols_offd_C)
      S_marker_offd = (int*)(hypre_CAlloc((unsigned)num_cols_offd_C, (unsigned)(sizeof(int))));
    for (i1 = 0; i1 < num_cols_offd_C; i1++)
      S_marker_offd[i1] = -1;
    for (i1 = ns; i1 < ne; i1++) {
      if ((CF_marker[i1]) > 0) {
        cnt_coarse[k]++;
        for (jj1 = S_diag_i[i1]; jj1 < (S_diag_i[i1 + 1]); jj1++) {
          jcol = S_diag_j[jj1];
          if ((CF_marker[jcol]) > 0) {
            S_marker[fine_to_coarse[jcol]] = i1;
            num_nnz_diag++;
          }
        }
        for (jj1 = S_offd_i[i1]; jj1 < (S_offd_i[i1 + 1]); jj1++) {
          jcol = S_offd_j[jj1];
          if ((CF_marker_offd[jcol]) > 0) {
            S_marker_offd[map_S_to_C[jcol]] = i1;
            num_nnz_offd++;
          }
        }
        for (jj1 = S_diag_i[i1]; jj1 < (S_diag_i[i1 + 1]); jj1++) {
          i2 = S_diag_j[jj1];
          for (jj2 = S_diag_i[i2]; jj2 < (S_diag_i[i2 + 1]); jj2++) {
            i3 = S_diag_j[jj2];
            if (((CF_marker[i3]) > 0) && ((S_marker[fine_to_coarse[i3]]) != i1)) {
              S_marker[fine_to_coarse[i3]] = i1;
              num_nnz_diag++;
            }
          }
          for (jj2 = S_offd_i[i2]; jj2 < (S_offd_i[i2 + 1]); jj2++) {
            i3 = S_offd_j[jj2];
            if (((CF_marker_offd[i3]) > 0) && ((S_marker_offd[map_S_to_C[i3]]) != i1)) {
              S_marker_offd[map_S_to_C[i3]] = i1;
              num_nnz_offd++;
            }
          }
        }
        for (jj1 = S_offd_i[i1]; jj1 < (S_offd_i[i1 + 1]); jj1++) {
          i2 = S_offd_j[jj1];
          for (jj2 = S_ext_diag_i[i2]; jj2 < (S_ext_diag_i[i2 + 1]); jj2++) {
            i3 = S_ext_diag_j[jj2];
            if ((S_marker[i3]) != i1) {
              S_marker[i3] = i1;
              num_nnz_diag++;
            }
          }
          for (jj2 = S_ext_offd_i[i2]; jj2 < (S_ext_offd_i[i2 + 1]); jj2++) {
            i3 = S_ext_offd_j[jj2];
            if ((S_marker_offd[i3]) != i1) {
              S_marker_offd[i3] = i1;
              num_nnz_offd++;
            }
          }
        }
      }
    }
    nnz[k] = num_nnz_diag;
    nnz_offd[k] = num_nnz_offd;
    if (num_coarse)
      hypre_Free((char*)S_marker), S_marker = (void*)0;
    if (num_cols_offd_C)
      hypre_Free((char*)S_marker_offd), S_marker_offd = (void*)0;
  }
  num_nonzeros_diag = 0;
  num_nonzeros_offd = 0;
  for (k = 0; k < num_threads; k++) {
    num_nonzeros_diag += nnz[k];
    num_nonzeros_offd += nnz_offd[k];
  }
  C_diag_i[num_coarse] = num_nonzeros_diag;
  C_offd_i[num_coarse] = num_nonzeros_offd;
  if (num_nonzeros_diag) {
    C_diag_j = (int*)(hypre_CAlloc((unsigned)num_nonzeros_diag, (unsigned)(sizeof(int))));
    C_diag_data = (int*)(hypre_CAlloc((unsigned)num_nonzeros_diag, (unsigned)(sizeof(int))));
  }
  if (num_nonzeros_offd) {
    C_offd_j = (int*)(hypre_CAlloc((unsigned)num_nonzeros_offd, (unsigned)(sizeof(int))));
    C_offd_data = (int*)(hypre_CAlloc((unsigned)num_nonzeros_offd, (unsigned)(sizeof(int))));
  }
  for (k = 0; k < num_threads; k++) {
    ns = ns_thr[k];
    ne = ne_thr[k];
    jj_count_diag = 0;
    jj_count_offd = 0;
    for (i1 = 0; i1 < k; i1++) {
      jj_count_diag += nnz[i1];
      jj_count_offd += nnz_offd[i1];
    }
    S_marker = (void*)0;
    if (num_coarse)
      S_marker = (int*)(hypre_CAlloc((unsigned)num_coarse, (unsigned)(sizeof(int))));
    for (i1 = 0; i1 < num_coarse; i1++)
      S_marker[i1] = -1;
    S_marker_offd = (void*)0;
    if (num_cols_offd_C)
      S_marker_offd = (int*)(hypre_CAlloc((unsigned)num_cols_offd_C, (unsigned)(sizeof(int))));
    for (i1 = 0; i1 < num_cols_offd_C; i1++)
      S_marker_offd[i1] = -1;
    cnt = 0;
    for (i1 = 0; i1 < k; i1++)
      cnt += cnt_coarse[i1];
    for (i1 = ns; i1 < ne; i1++) {
      jj_row_begin_diag = jj_count_diag;
      jj_row_begin_offd = jj_count_offd;
      if ((CF_marker[i1]) > 0) {
        C_diag_i[cnt] = jj_row_begin_diag;
        C_offd_i[cnt++] = jj_row_begin_offd;
        for (jj1 = S_diag_i[i1]; jj1 < (S_diag_i[i1 + 1]); jj1++) {
          jcol = S_diag_j[jj1];
          if ((CF_marker[jcol]) > 0) {
            S_marker[fine_to_coarse[jcol]] = jj_count_diag;
            C_diag_j[jj_count_diag] = fine_to_coarse[jcol];
            C_diag_data[jj_count_diag] = 2;
            jj_count_diag++;
          }
        }
        for (jj1 = S_offd_i[i1]; jj1 < (S_offd_i[i1 + 1]); jj1++) {
          jcol = S_offd_j[jj1];
          if ((CF_marker_offd[jcol]) > 0) {
            index = map_S_to_C[jcol];
            S_marker_offd[index] = jj_count_offd;
            C_offd_j[jj_count_offd] = index;
            C_offd_data[jj_count_offd] = 2;
            jj_count_offd++;
          }
        }
        for (jj1 = S_diag_i[i1]; jj1 < (S_diag_i[i1 + 1]); jj1++) {
          i2 = S_diag_j[jj1];
          for (jj2 = S_diag_i[i2]; jj2 < (S_diag_i[i2 + 1]); jj2++) {
            i3 = S_diag_j[jj2];
            if ((CF_marker[i3]) > 0) {
              if ((S_marker[fine_to_coarse[i3]]) < jj_row_begin_diag) {
                S_marker[fine_to_coarse[i3]] = jj_count_diag;
                C_diag_j[jj_count_diag] = fine_to_coarse[i3];
                C_diag_data[jj_count_diag]++;
                jj_count_diag++;
              }
              else {
                C_diag_data[S_marker[fine_to_coarse[i3]]]++;
              }
            }
          }
          for (jj2 = S_offd_i[i2]; jj2 < (S_offd_i[i2 + 1]); jj2++) {
            i3 = S_offd_j[jj2];
            if ((CF_marker_offd[i3]) > 0) {
              index = map_S_to_C[i3];
              if ((S_marker_offd[index]) < jj_row_begin_offd) {
                S_marker_offd[index] = jj_count_offd;
                C_offd_j[jj_count_offd] = index;
                C_offd_data[jj_count_offd]++;
                jj_count_offd++;
              }
              else {
                C_offd_data[S_marker_offd[index]]++;
              }
            }
          }
        }
        for (jj1 = S_offd_i[i1]; jj1 < (S_offd_i[i1 + 1]); jj1++) {
          i2 = S_offd_j[jj1];
          for (jj2 = S_ext_diag_i[i2]; jj2 < (S_ext_diag_i[i2 + 1]); jj2++) {
            i3 = S_ext_diag_j[jj2];
            if ((S_marker[i3]) < jj_row_begin_diag) {
              S_marker[i3] = jj_count_diag;
              C_diag_j[jj_count_diag] = i3;
              C_diag_data[jj_count_diag]++;
              jj_count_diag++;
            }
            else {
              C_diag_data[S_marker[i3]]++;
            }
          }
          for (jj2 = S_ext_offd_i[i2]; jj2 < (S_ext_offd_i[i2 + 1]); jj2++) {
            i3 = S_ext_offd_j[jj2];
            if ((S_marker_offd[i3]) < jj_row_begin_offd) {
              S_marker_offd[i3] = jj_count_offd;
              C_offd_j[jj_count_offd] = i3;
              C_offd_data[jj_count_offd]++;
              jj_count_offd++;
            }
            else {
              C_offd_data[S_marker_offd[i3]]++;
            }
          }
        }
      }
    }
    if (num_coarse)
      hypre_Free((char*)S_marker), S_marker = (void*)0;
    if (num_cols_offd_C)
      hypre_Free((char*)S_marker_offd), S_marker_offd = (void*)0;
  }
  cnt = 0;
  for (i = 0; i < num_coarse; i++) {
    for (j = C_diag_i[i]; j < (C_diag_i[i + 1]); j++) {
      jcol = C_diag_j[j];
      if (((C_diag_data[j]) >= num_paths) && (jcol != i))
        C_diag_j[cnt++] = jcol;
    }
    C_diag_i[i] = cnt;
  }
  if (num_nonzeros_diag)
    hypre_Free((char*)C_diag_data), C_diag_data = (void*)0;
  for (i = num_coarse; i > 0; i--)
    C_diag_i[i] = C_diag_i[i - 1];
  C_diag_i[0] = 0;
  cnt = 0;
  for (i = 0; i < num_coarse; i++) {
    for (j = C_offd_i[i]; j < (C_offd_i[i + 1]); j++) {
      jcol = C_offd_j[j];
      if ((C_offd_data[j]) >= num_paths)
        C_offd_j[cnt++] = jcol;
    }
    C_offd_i[i] = cnt;
  }
  if (num_nonzeros_offd)
    hypre_Free((char*)C_offd_data), C_offd_data = (void*)0;
  for (i = num_coarse; i > 0; i--)
    C_offd_i[i] = C_offd_i[i - 1];
  C_offd_i[0] = 0;
  cnt = 0;
  for (i = 0; i < num_cols_diag_S; i++) {
    if ((CF_marker[i]) > 0) {
      if ((!((C_diag_i[cnt + 1]) - (C_diag_i[cnt]))) && (!((C_offd_i[cnt + 1]) - (C_offd_i[cnt]))))
        CF_marker[i] = 2;
      cnt++;
    }
  }
  C_diag_size = C_diag_i[num_coarse];
  C_offd_size = C_offd_i[num_coarse];
  S2 = hypre_ParCSRMatrixCreate(comm, global_num_coarse, global_num_coarse, coarse_row_starts, coarse_row_starts, num_cols_offd_C, C_diag_size, C_offd_size);
  (S2)->owns_row_starts = 0;
  C_diag = (S2)->diag;
  (C_diag)->i = C_diag_i;
  if (num_nonzeros_diag)
    (C_diag)->j = C_diag_j;
  C_offd = (S2)->offd;
  (C_offd)->i = C_offd_i;
  (S2)->offd = C_offd;
  if (num_cols_offd_C) {
    if (num_nonzeros_offd)
      (C_offd)->j = C_offd_j;
    (S2)->col_map_offd = col_map_offd_C;
  }
  hypre_Free((char*)ns_thr), ns_thr = (void*)0;
  hypre_Free((char*)ne_thr), ne_thr = (void*)0;
  hypre_Free((char*)nnz), nnz = (void*)0;
  hypre_Free((char*)nnz_offd), nnz_offd = (void*)0;
  hypre_Free((char*)cnt_coarse), cnt_coarse = (void*)0;
  hypre_Free((char*)S_ext_diag_i), S_ext_diag_i = (void*)0;
  hypre_Free((char*)fine_to_coarse), fine_to_coarse = (void*)0;
  if (S_ext_diag_size) {
    hypre_Free((char*)S_ext_diag_j), S_ext_diag_j = (void*)0;
  }
  hypre_Free((char*)S_ext_offd_i), S_ext_offd_i = (void*)0;
  if (S_ext_offd_size) {
    hypre_Free((char*)S_ext_offd_j), S_ext_offd_j = (void*)0;
  }
  if (num_cols_offd_S) {
    hypre_Free((char*)map_S_to_C), map_S_to_C = (void*)0;
    hypre_Free((char*)CF_marker_offd), CF_marker_offd = (void*)0;
    hypre_Free((char*)big_fine_to_coarse_offd), big_fine_to_coarse_offd = (void*)0;
  }
  *C_ptr = S2;
  return 0;
}
int hypre_BoomerAMGCorrectCFMarker(int* CF_marker, int num_var, int* new_CF_marker) {
  int i;
  int cnt;
  cnt = 0;
  for (i = 0; i < num_var; i++) {
    if ((CF_marker[i]) > 0) {
      if ((CF_marker[i]) == 1)
        CF_marker[i] = new_CF_marker[cnt++];
      else {
        CF_marker[i] = 1;
        cnt++;
      }
    }
  }
  return 0;
}
int hypre_BoomerAMGCorrectCFMarker2(int* CF_marker, int num_var, int* new_CF_marker) {
  int i;
  int cnt;
  cnt = 0;
  for (i = 0; i < num_var; i++) {
    if ((CF_marker[i]) > 0) {
      if ((new_CF_marker[cnt]) == (-1))
        CF_marker[i] = -2;
      else
        CF_marker[i] = 1;
      cnt++;
    }
  }
  return 0;
}
//==================== par_vardifconv.c ====================
HYPRE_ParCSRMatrix GenerateVarDifConv(MPI_Comm comm, int nx, int ny, int nz, int P, int Q, int R, int p, int q, int r, double eps, HYPRE_ParVector* rhs_ptr, HYPRE_ParVector* x_ptr) {
  hypre_ParCSRMatrix* A;
  hypre_CSRMatrix* diag;
  hypre_CSRMatrix* offd;
  hypre_ParVector* par_rhs;
  hypre_Vector* rhs;
  hypre_ParVector* par_x;
  hypre_Vector* x;
  double* rhs_data;
  double* x_data;
  int* diag_i;
  int* diag_j;
  double* diag_data;
  int* offd_i;
  int* offd_j = (void*)0;
  double* offd_data = (void*)0;
  int* global_part;
  int* global_part_rhs;
  int* global_part_x;
  int* tmp_j = (void*)0;
  int ix;
  int iy;
  int iz;
  int cnt;
  int o_cnt;
  int local_num_rows;
  int* col_map_offd = (void*)0;
  int row_index;
  int i;
  int j;
  int ip;
  int iq;
  int ir;
  int nx_local;
  int ny_local;
  int nz_local;
  int num_cols_offd;
  int grid_size;
  int* nx_part;
  int* ny_part;
  int* nz_part;
  int num_procs;
  int my_id;
  int P_busy;
  int Q_busy;
  int R_busy;
  double hhx;
  double hhy;
  double hhz;
  double xx;
  double yy;
  double zz;
  double afp;
  double afm;
  double bfp;
  double bfm;
  double cfp;
  double cfm;
  double df;
  double ef;
  double ff;
  double gf;
  int nx_size;
  int ny_size;
  int nz_size;
  MPI_Comm_size(comm, &(num_procs));
  MPI_Comm_rank(comm, &(my_id));
  hypre_GeneratePartitioning(nx, P, &(nx_part));
  hypre_GeneratePartitioning(ny, Q, &(ny_part));
  hypre_GeneratePartitioning(nz, R, &(nz_part));
  global_part = (int*)(hypre_CAlloc((unsigned)(((P * Q) * R) + 1), (unsigned)(sizeof(int))));
  global_part_rhs = (int*)(hypre_CAlloc((unsigned)(((P * Q) * R) + 1), (unsigned)(sizeof(int))));
  global_part_x = (int*)(hypre_CAlloc((unsigned)(((P * Q) * R) + 1), (unsigned)(sizeof(int))));
  global_part[0] = 0;
  global_part_rhs[0] = 0;
  global_part_x[0] = 0;
  cnt = 1;
  for (iz = 0; iz < R; iz++) {
    nz_size = (int)((nz_part[iz + 1]) - (nz_part[iz]));
    for (iy = 0; iy < Q; iy++) {
      ny_size = (int)((ny_part[iy + 1]) - (ny_part[iy]));
      for (ix = 0; ix < P; ix++) {
        nx_size = (int)((nx_part[ix + 1]) - (nx_part[ix]));
        global_part[cnt] = global_part[cnt - 1];
        global_part[cnt] += (int)((nx_size * ny_size) * nz_size);
        global_part_rhs[cnt] = global_part[cnt];
        global_part_x[cnt] = global_part[cnt];
        cnt++;
      }
    }
  }
  nx_local = (int)((nx_part[p + 1]) - (nx_part[p]));
  ny_local = (int)((ny_part[q + 1]) - (ny_part[q]));
  nz_local = (int)((nz_part[r + 1]) - (nz_part[r]));
  local_num_rows = (nx_local * ny_local) * nz_local;
  ip = p;
  iq = q;
  ir = r;
  grid_size = (nx * ny) * nz;
  diag_i = (int*)(hypre_CAlloc((unsigned)(local_num_rows + 1), (unsigned)(sizeof(int))));
  offd_i = (int*)(hypre_CAlloc((unsigned)(local_num_rows + 1), (unsigned)(sizeof(int))));
  rhs_data = (double*)(hypre_CAlloc((unsigned)local_num_rows, (unsigned)(sizeof(double))));
  x_data = (double*)(hypre_CAlloc((unsigned)local_num_rows, (unsigned)(sizeof(double))));
  for (i = 0; i < local_num_rows; i++)
    x_data[i] = 0.0;
  P_busy = nx < P ? nx : P;
  Q_busy = ny < Q ? ny : Q;
  R_busy = nz < R ? nz : R;
  num_cols_offd = 0;
  if (p)
    num_cols_offd += ny_local * nz_local;
  if (p < (P_busy - 1))
    num_cols_offd += ny_local * nz_local;
  if (q)
    num_cols_offd += nx_local * nz_local;
  if (q < (Q_busy - 1))
    num_cols_offd += nx_local * nz_local;
  if (r)
    num_cols_offd += nx_local * ny_local;
  if (r < (R_busy - 1))
    num_cols_offd += nx_local * ny_local;
  if (!local_num_rows)
    num_cols_offd = 0;
  if (num_cols_offd)
    col_map_offd = (int*)(hypre_CAlloc((unsigned)num_cols_offd, (unsigned)(sizeof(int))));
  hhx = 1.0 / (double)(nx + 1);
  hhy = 1.0 / (double)(ny + 1);
  hhz = 1.0 / (double)(nz + 1);
  cnt = 1;
  o_cnt = 1;
  diag_i[0] = 0;
  offd_i[0] = 0;
  for (iz = 0; iz < nz_local; iz++) {
    for (iy = 0; iy < ny_local; iy++) {
      for (ix = 0; ix < nx_local; ix++) {
        diag_i[cnt] = diag_i[cnt - 1];
        offd_i[o_cnt] = offd_i[o_cnt - 1];
        diag_i[cnt]++;
        if (iz)
          diag_i[cnt]++;
        else {
          if (ir) {
            offd_i[o_cnt]++;
          }
        }
        if (iy)
          diag_i[cnt]++;
        else {
          if (iq) {
            offd_i[o_cnt]++;
          }
        }
        if (ix)
          diag_i[cnt]++;
        else {
          if (ip) {
            offd_i[o_cnt]++;
          }
        }
        if ((ix + 1) < nx_local)
          diag_i[cnt]++;
        else {
          if ((ip + 1) < P) {
            offd_i[o_cnt]++;
          }
        }
        if ((iy + 1) < ny_local)
          diag_i[cnt]++;
        else {
          if ((iq + 1) < Q) {
            offd_i[o_cnt]++;
          }
        }
        if ((iz + 1) < nz_local)
          diag_i[cnt]++;
        else {
          if ((ir + 1) < R) {
            offd_i[o_cnt]++;
          }
        }
        cnt++;
        o_cnt++;
      }
    }
  }
  diag_j = (int*)(hypre_CAlloc((unsigned)(diag_i[local_num_rows]), (unsigned)(sizeof(int))));
  diag_data = (double*)(hypre_CAlloc((unsigned)(diag_i[local_num_rows]), (unsigned)(sizeof(double))));
  if (num_procs > 1) {
    offd_j = (int*)(hypre_CAlloc((unsigned)(offd_i[local_num_rows]), (unsigned)(sizeof(int))));
    offd_data = (double*)(hypre_CAlloc((unsigned)(offd_i[local_num_rows]), (unsigned)(sizeof(double))));
  }
  row_index = 0;
  cnt = 0;
  o_cnt = 0;
  for (iz = 0; iz < nz_local; iz++) {
    zz = (double)(((nz_part[ir]) + iz) + 1) * hhz;
    for (iy = 0; iy < ny_local; iy++) {
      yy = (double)(((ny_part[iq]) + iy) + 1) * hhy;
      for (ix = 0; ix < nx_local; ix++) {
        xx = (double)(((nx_part[ip]) + ix) + 1) * hhx;
        afp = ((eps * afun(xx + (0.5 * hhx), yy, zz)) / hhx) / hhx;
        afm = ((eps * afun(xx - (0.5 * hhx), yy, zz)) / hhx) / hhx;
        bfp = ((eps * bfun(xx, yy + (0.5 * hhy), zz)) / hhy) / hhy;
        bfm = ((eps * bfun(xx, yy - (0.5 * hhy), zz)) / hhy) / hhy;
        cfp = ((eps * cfun(xx, yy, zz + (0.5 * hhz))) / hhz) / hhz;
        cfm = ((eps * cfun(xx, yy, zz - (0.5 * hhz))) / hhz) / hhz;
        df = dfun(xx, yy, zz) / hhx;
        ef = efun(xx, yy, zz) / hhy;
        ff = ffun(xx, yy, zz) / hhz;
        gf = gfun(xx, yy, zz);
        diag_j[cnt] = row_index;
        diag_data[cnt++] = ((((((((afp + afm) + bfp) + bfm) + cfp) + cfm) + gf) - df) - ef) - ff;
        rhs_data[row_index] = rfun(xx, yy, zz);
        if ((ix == 0) && (ip == 0))
          rhs_data[row_index] += afm * bndfun(0, yy, zz);
        if ((iy == 0) && (iq == 0))
          rhs_data[row_index] += bfm * bndfun(xx, 0, zz);
        if ((iz == 0) && (ir == 0))
          rhs_data[row_index] += cfm * bndfun(xx, yy, 0);
        if (((ix + 1) == nx_local) && ((ip + 1) == P))
          rhs_data[row_index] += (afp - df) * bndfun(1.0, yy, zz);
        if (((iy + 1) == ny_local) && ((iq + 1) == Q))
          rhs_data[row_index] += (bfp - ef) * bndfun(xx, 1.0, zz);
        if (((iz + 1) == nz_local) && ((ir + 1) == R))
          rhs_data[row_index] += (cfp - ff) * bndfun(xx, yy, 1.0);
        if (iz) {
          diag_j[cnt] = row_index - (nx_local * ny_local);
          diag_data[cnt++] = -cfm;
        }
        else {
          if (ir) {
            offd_j[o_cnt] = o_cnt;
            hypre_map(ix, iy, iz - 1, p, q, r - 1, P, Q, R, nx_part, ny_part, nz_part, global_part, &(col_map_offd[o_cnt]));
            offd_data[o_cnt++] = -cfm;
          }
        }
        if (iy) {
          diag_j[cnt] = row_index - nx_local;
          diag_data[cnt++] = -bfm;
        }
        else {
          if (iq) {
            offd_j[o_cnt] = o_cnt;
            hypre_map(ix, iy - 1, iz, p, q - 1, r, P, Q, R, nx_part, ny_part, nz_part, global_part, &(col_map_offd[o_cnt]));
            offd_data[o_cnt++] = -bfm;
          }
        }
        if (ix) {
          diag_j[cnt] = row_index - 1;
          diag_data[cnt++] = -afm;
        }
        else {
          if (ip) {
            offd_j[o_cnt] = o_cnt;
            hypre_map(ix - 1, iy, iz, p - 1, q, r, P, Q, R, nx_part, ny_part, nz_part, global_part, &(col_map_offd[o_cnt]));
            offd_data[o_cnt++] = -afm;
          }
        }
        if ((ix + 1) < nx_local) {
          diag_j[cnt] = row_index + 1;
          diag_data[cnt++] = (-afp) + df;
        }
        else {
          if ((ip + 1) < P) {
            offd_j[o_cnt] = o_cnt;
            hypre_map(ix + 1, iy, iz, p + 1, q, r, P, Q, R, nx_part, ny_part, nz_part, global_part, &(col_map_offd[o_cnt]));
            offd_data[o_cnt++] = (-afp) + df;
          }
        }
        if ((iy + 1) < ny_local) {
          diag_j[cnt] = row_index + nx_local;
          diag_data[cnt++] = (-bfp) + ef;
        }
        else {
          if ((iq + 1) < Q) {
            offd_j[o_cnt] = o_cnt;
            hypre_map(ix, iy + 1, iz, p, q + 1, r, P, Q, R, nx_part, ny_part, nz_part, global_part, &(col_map_offd[o_cnt]));
            offd_data[o_cnt++] = (-bfp) + ef;
          }
        }
        if ((iz + 1) < nz_local) {
          diag_j[cnt] = row_index + (nx_local * ny_local);
          diag_data[cnt++] = (-cfp) + ff;
        }
        else {
          if ((ir + 1) < R) {
            offd_j[o_cnt] = o_cnt;
            hypre_map(ix, iy, iz + 1, p, q, r + 1, P, Q, R, nx_part, ny_part, nz_part, global_part, &(col_map_offd[o_cnt]));
            offd_data[o_cnt++] = (-cfp) + ff;
          }
        }
        row_index++;
      }
    }
  }
  if (num_cols_offd)
    tmp_j = (int*)(hypre_CAlloc((unsigned)num_cols_offd, (unsigned)(sizeof(int))));
  if (num_procs > 1) {
    for (i = 0; i < num_cols_offd; i++)
      tmp_j[i] = offd_j[i];
    hypre_BigQsortbi(col_map_offd, tmp_j, 0, num_cols_offd - 1);
    for (i = 0; i < num_cols_offd; i++)
      for (j = 0; j < num_cols_offd; j++)
        if ((offd_j[i]) == (tmp_j[j])) {
          offd_j[i] = j;
          break;
        }
  }
  hypre_Free((char*)tmp_j), tmp_j = (void*)0;
  par_rhs = hypre_ParVectorCreate(comm, grid_size, global_part_rhs);
  rhs = (par_rhs)->local_vector;
  (rhs)->data = rhs_data;
  par_x = hypre_ParVectorCreate(comm, grid_size, global_part_x);
  x = (par_x)->local_vector;
  (x)->data = x_data;
  A = hypre_ParCSRMatrixCreate(comm, grid_size, grid_size, global_part, global_part, num_cols_offd, diag_i[local_num_rows], offd_i[local_num_rows]);
  (A)->col_map_offd = col_map_offd;
  diag = (A)->diag;
  (diag)->i = diag_i;
  (diag)->j = diag_j;
  (diag)->data = diag_data;
  offd = (A)->offd;
  (offd)->i = offd_i;
  if (num_cols_offd) {
    (offd)->j = offd_j;
    (offd)->data = offd_data;
  }
  hypre_Free((char*)nx_part), nx_part = (void*)0;
  hypre_Free((char*)ny_part), ny_part = (void*)0;
  hypre_Free((char*)nz_part), nz_part = (void*)0;
  *rhs_ptr = (HYPRE_ParVector)par_rhs;
  *x_ptr = (HYPRE_ParVector)par_x;
  return (HYPRE_ParCSRMatrix)A;
}
double afun(double xx, double yy, double zz) {
  double value;
  if ((((((((((xx < 0.1) && (yy < 0.1)) && (zz < 0.1)) || (((xx < 0.1) && (yy < 0.1)) && (zz > 0.9))) || (((xx < 0.1) && (yy > 0.9)) && (zz < 0.1))) || (((xx > 0.9) && (yy < 0.1)) && (zz < 0.1))) || (((xx > 0.9) && (yy > 0.9)) && (zz < 0.1))) || (((xx > 0.9) && (yy < 0.1)) && (zz > 0.9))) || (((xx < 0.1) && (yy > 0.9)) && (zz > 0.9))) || (((xx > 0.9) && (yy > 0.9)) && (zz > 0.9)))
    value = 0.01;
  else
    if ((((((xx >= 0.1) && (xx <= 0.9)) && (yy >= 0.1)) && (yy <= 0.9)) && (zz >= 0.1)) && (zz <= 0.9))
      value = 1000.0;
    else
      value = 1.0;
  return value;
}
double bfun(double xx, double yy, double zz) {
  double value;
  if ((((((((((xx < 0.1) && (yy < 0.1)) && (zz < 0.1)) || (((xx < 0.1) && (yy < 0.1)) && (zz > 0.9))) || (((xx < 0.1) && (yy > 0.9)) && (zz < 0.1))) || (((xx > 0.9) && (yy < 0.1)) && (zz < 0.1))) || (((xx > 0.9) && (yy > 0.9)) && (zz < 0.1))) || (((xx > 0.9) && (yy < 0.1)) && (zz > 0.9))) || (((xx < 0.1) && (yy > 0.9)) && (zz > 0.9))) || (((xx > 0.9) && (yy > 0.9)) && (zz > 0.9)))
    value = 0.01;
  else
    if ((((((xx >= 0.1) && (xx <= 0.9)) && (yy >= 0.1)) && (yy <= 0.9)) && (zz >= 0.1)) && (zz <= 0.9))
      value = 1000.0;
    else
      value = 1.0;
  return value;
}
double cfun(double xx, double yy, double zz) {
  double value;
  if ((((((((((xx < 0.1) && (yy < 0.1)) && (zz < 0.1)) || (((xx < 0.1) && (yy < 0.1)) && (zz > 0.9))) || (((xx < 0.1) && (yy > 0.9)) && (zz < 0.1))) || (((xx > 0.9) && (yy < 0.1)) && (zz < 0.1))) || (((xx > 0.9) && (yy > 0.9)) && (zz < 0.1))) || (((xx > 0.9) && (yy < 0.1)) && (zz > 0.9))) || (((xx < 0.1) && (yy > 0.9)) && (zz > 0.9))) || (((xx > 0.9) && (yy > 0.9)) && (zz > 0.9)))
    value = 0.01;
  else
    if ((((((xx >= 0.1) && (xx <= 0.9)) && (yy >= 0.1)) && (yy <= 0.9)) && (zz >= 0.1)) && (zz <= 0.9))
      value = 1000.0;
    else
      value = 1.0;
  return value;
}
double dfun(double xx, double yy, double zz) {
  double value;
  value = 0;
  return value;
}
double efun(double xx, double yy, double zz) {
  double value;
  value = 0;
  return value;
}
double ffun(double xx, double yy, double zz) {
  double value;
  value = 0.0;
  return value;
}
double gfun(double xx, double yy, double zz) {
  double value;
  value = 0.0;
  return value;
}
double rfun(double xx, double yy, double zz) {
  double value;
  value = 1.0;
  return value;
}
double bndfun(double xx, double yy, double zz) {
  double value;
  value = 0.0;
  return value;
}
//======================== partial.c =======================
int hypre_BoomerAMGBuildPartialStdInterp(hypre_ParCSRMatrix* A, int* CF_marker, hypre_ParCSRMatrix* S, int* num_cpts_global, int* num_old_cpts_global, int num_functions, int* dof_func, int debug_flag, double trunc_factor, int max_elmts, int sep_weight, int* col_offd_S_to_A, hypre_ParCSRMatrix** P_ptr) {
  MPI_Comm comm = (A)->comm;
  hypre_ParCSRCommPkg* comm_pkg = (A)->comm_pkg;
  int my_id;
  int num_procs;
  hypre_CSRMatrix* A_diag = (A)->diag;
  double* A_diag_data = (A_diag)->data;
  int* A_diag_i = (A_diag)->i;
  int* A_diag_j = (A_diag)->j;
  hypre_CSRMatrix* A_offd = (A)->offd;
  double* A_offd_data = (A_offd)->data;
  int* A_offd_i = (A_offd)->i;
  int* A_offd_j = (A_offd)->j;
  int num_cols_A_offd = (A_offd)->num_cols;
  int* col_map_offd = (A)->col_map_offd;
  int n_fine = (A_diag)->num_rows;
  int col_1 = (A)->first_row_index;
  int local_numrows = (A_diag)->num_rows;
  int col_n = col_1 + (int)local_numrows;
  int total_global_cpts;
  int my_first_cpt;
  int total_old_global_cpts;
  int my_first_old_cpt;
  int n_coarse;
  int n_coarse_old;
  hypre_CSRMatrix* S_diag = (S)->diag;
  int* S_diag_i = (S_diag)->i;
  int* S_diag_j = (S_diag)->j;
  hypre_CSRMatrix* S_offd = (S)->offd;
  int* S_offd_i = (S_offd)->i;
  int* S_offd_j = (S_offd)->j;
  hypre_ParCSRMatrix* P;
  hypre_CSRMatrix* P_diag;
  hypre_CSRMatrix* P_offd;
  double* P_diag_data = (void*)0;
  int* P_diag_i;
  int* P_diag_j = (void*)0;
  double* P_offd_data = (void*)0;
  int* P_offd_i;
  int* P_offd_j = (void*)0;
  int* col_map_offd_P;
  int* tmp_map_offd;
  int P_diag_size;
  int P_offd_size;
  int* P_marker = (void*)0;
  int* P_marker_offd = (void*)0;
  int* CF_marker_offd = (void*)0;
  int* tmp_CF_marker_offd = (void*)0;
  int* dof_func_offd = (void*)0;
  hypre_BigCSRMatrix* A_ext;
  double* A_ext_data;
  int* A_ext_i;
  int* big_A_ext_j;
  int* A_ext_j;
  int* fine_to_coarse = (void*)0;
  int* old_coarse_to_fine = (void*)0;
  int* fine_to_coarse_offd = (void*)0;
  int* found;
  int num_cols_P_offd;
  int newoff;
  int loc_col;
  int A_ext_rows;
  int full_off_procNodes;
  hypre_BigCSRMatrix* Sop;
  int* Sop_i;
  int* big_Sop_j;
  int* Sop_j;
  int Soprows;
  int jj_counter;
  int jj_counter_offd;
  int jj_begin_row;
  int jj_end_row;
  int jj_begin_row_offd = 0;
  int jj_end_row_offd = 0;
  int coarse_counter;
  int coarse_counter_offd;
  int* ihat = (void*)0;
  int* ihat_offd = (void*)0;
  int* ipnt = (void*)0;
  int* ipnt_offd = (void*)0;
  int strong_f_marker = -2;
  double* ahat_offd = (void*)0;
  double* ahat = (void*)0;
  double sum_pos;
  double sum_pos_C;
  double sum_neg;
  double sum_neg_C;
  double sum;
  double sum_C;
  double diagonal;
  double distribute;
  double alfa;
  double beta;
  int index;
  int cnt;
  int old_cnt;
  int start_indexing = 0;
  int i;
  int ii;
  int i1;
  int j1;
  int jj;
  int kk;
  int k1;
  int cnt_c;
  int cnt_f;
  int cnt_c_offd;
  int cnt_f_offd;
  int indx;
  double zero = 0.0;
  double one = 1.0;
  double wall_time;
  double wall_1 = 0;
  double wall_2 = 0;
  double wall_3 = 0;
  hypre_ParCSRCommPkg* extend_comm_pkg = (void*)0;
  if (debug_flag == 4)
    wall_time = time_getWallclockSeconds();
  MPI_Comm_size(comm, &(num_procs));
  MPI_Comm_rank(comm, &(my_id));
  my_first_cpt = num_cpts_global[my_id];
  my_first_old_cpt = num_old_cpts_global[my_id];
  total_global_cpts = num_cpts_global[num_procs];
  total_old_global_cpts = num_old_cpts_global[num_procs];
  n_coarse_old = (int)((num_old_cpts_global[my_id + 1]) - (num_old_cpts_global[my_id]));
  n_coarse = (int)((num_cpts_global[my_id + 1]) - (num_cpts_global[my_id]));
  if (!comm_pkg) {
    hypre_MatvecCommPkgCreate(A);
    comm_pkg = (A)->comm_pkg;
  }
  newoff = 0;
  full_off_procNodes = 0;
  if (num_procs > 1) {
    A_ext = hypre_ParCSRMatrixExtractBigExt(A, A, 1);
    A_ext_i = (A_ext)->i;
    big_A_ext_j = (A_ext)->j;
    A_ext_data = (A_ext)->data;
    A_ext_rows = (A_ext)->num_rows;
    Sop = hypre_ParCSRMatrixExtractBigExt(S, A, 0);
    Sop_i = (Sop)->i;
    big_Sop_j = (Sop)->j;
    Soprows = (Sop)->num_rows;
    newoff = new_offd_nodes(&(found), A_ext_rows, A_ext_i, big_A_ext_j, &(A_ext_j), Soprows, col_map_offd, col_1, col_n, Sop_i, big_Sop_j, &(Sop_j), CF_marker, comm_pkg);
    (A_ext)->j = (void*)0;
    (Sop)->j = (void*)0;
    if (newoff >= 0)
      full_off_procNodes = newoff + num_cols_A_offd;
    else
      return 1;
    hypre_ParCSRFindExtendCommPkg(A, newoff, found, &(extend_comm_pkg));
    CF_marker_offd = (int*)(hypre_CAlloc((unsigned)full_off_procNodes, (unsigned)(sizeof(int))));
    if ((num_functions > 1) && (full_off_procNodes > 0))
      dof_func_offd = (int*)(hypre_CAlloc((unsigned)full_off_procNodes, (unsigned)(sizeof(int))));
    alt_insert_new_nodes(comm_pkg, extend_comm_pkg, CF_marker, full_off_procNodes, CF_marker_offd);
    if (num_functions > 1)
      alt_insert_new_nodes(comm_pkg, extend_comm_pkg, dof_func, full_off_procNodes, dof_func_offd);
  }
  P_diag_i = (int*)(hypre_CAlloc((unsigned)(n_coarse_old + 1), (unsigned)(sizeof(int))));
  P_offd_i = (int*)(hypre_CAlloc((unsigned)(n_coarse_old + 1), (unsigned)(sizeof(int))));
  if (n_coarse_old)
    old_coarse_to_fine = (int*)(hypre_CAlloc((unsigned)n_coarse_old, (unsigned)(sizeof(int))));
  if (n_fine) {
    fine_to_coarse = (int*)(hypre_CAlloc((unsigned)n_fine, (unsigned)(sizeof(int))));
    P_marker = (int*)(hypre_CAlloc((unsigned)n_fine, (unsigned)(sizeof(int))));
  }
  if (full_off_procNodes) {
    P_marker_offd = (int*)(hypre_CAlloc((unsigned)full_off_procNodes, (unsigned)(sizeof(int))));
    fine_to_coarse_offd = (int*)(hypre_CAlloc((unsigned)full_off_procNodes, (unsigned)(sizeof(int))));
    tmp_CF_marker_offd = (int*)(hypre_CAlloc((unsigned)full_off_procNodes, (unsigned)(sizeof(int))));
  }
  for (i = 0; i < full_off_procNodes; i++) {
    P_marker_offd[i] = -1;
    tmp_CF_marker_offd[i] = -1;
    fine_to_coarse_offd[i] = -1;
  }
  for (i = 0; i < n_fine; i++) {
    P_marker[i] = -1;
    fine_to_coarse[i] = -1;
  }
  jj_counter = start_indexing;
  jj_counter_offd = start_indexing;
  coarse_counter = 0;
  coarse_counter_offd = 0;
  cnt = 0;
  old_cnt = 0;
  for (i = 0; i < n_fine; i++) {
    fine_to_coarse[i] = -1;
    if ((CF_marker[i]) == 1) {
      fine_to_coarse[i] = cnt++;
      old_coarse_to_fine[old_cnt++] = i;
    }
    else
      if ((CF_marker[i]) == (-2)) {
        old_coarse_to_fine[old_cnt++] = i;
      }
  }
  for (ii = 0; ii < n_coarse_old; ii++) {
    P_diag_i[ii] = jj_counter;
    if (num_procs > 1)
      P_offd_i[ii] = jj_counter_offd;
    i = old_coarse_to_fine[ii];
    if ((CF_marker[i]) > 0) {
      jj_counter++;
      coarse_counter++;
    }
    else
      if ((CF_marker[i]) == (-2)) {
        for (jj = S_diag_i[i]; jj < (S_diag_i[i + 1]); jj++) {
          i1 = S_diag_j[jj];
          if ((CF_marker[i1]) > 0) {
            if ((P_marker[i1]) < (P_diag_i[ii])) {
              P_marker[i1] = jj_counter;
              jj_counter++;
            }
          }
          else
            if ((CF_marker[i1]) != (-3)) {
              for (kk = S_diag_i[i1]; kk < (S_diag_i[i1 + 1]); kk++) {
                k1 = S_diag_j[kk];
                if ((CF_marker[k1]) > 0) {
                  if ((P_marker[k1]) < (P_diag_i[ii])) {
                    P_marker[k1] = jj_counter;
                    jj_counter++;
                  }
                }
              }
              if (num_procs > 1) {
                for (kk = S_offd_i[i1]; kk < (S_offd_i[i1 + 1]); kk++) {
                  if (col_offd_S_to_A)
                    k1 = col_offd_S_to_A[S_offd_j[kk]];
                  else
                    k1 = S_offd_j[kk];
                  if ((CF_marker_offd[k1]) > 0) {
                    if ((P_marker_offd[k1]) < (P_offd_i[ii])) {
                      tmp_CF_marker_offd[k1] = 1;
                      P_marker_offd[k1] = jj_counter_offd;
                      jj_counter_offd++;
                    }
                  }
                }
              }
            }
        }
        if (num_procs > 1) {
          for (jj = S_offd_i[i]; jj < (S_offd_i[i + 1]); jj++) {
            i1 = S_offd_j[jj];
            if (col_offd_S_to_A)
              i1 = col_offd_S_to_A[i1];
            if ((CF_marker_offd[i1]) > 0) {
              if ((P_marker_offd[i1]) < (P_offd_i[ii])) {
                tmp_CF_marker_offd[i1] = 1;
                P_marker_offd[i1] = jj_counter_offd;
                jj_counter_offd++;
              }
            }
            else
              if ((CF_marker_offd[i1]) != (-3)) {
                for (kk = Sop_i[i1]; kk < (Sop_i[i1 + 1]); kk++) {
                  loc_col = Sop_j[kk];
                  if (loc_col > (-1)) {
                    if ((CF_marker[loc_col]) > 0) {
                      if ((P_marker[loc_col]) < (P_diag_i[ii])) {
                        P_marker[loc_col] = jj_counter;
                        jj_counter++;
                      }
                    }
                  }
                  else {
                    loc_col = (-loc_col) - 1;
                    if ((CF_marker_offd[loc_col]) > 0) {
                      if ((P_marker_offd[loc_col]) < (P_offd_i[ii])) {
                        P_marker_offd[loc_col] = jj_counter_offd;
                        tmp_CF_marker_offd[loc_col] = 1;
                        jj_counter_offd++;
                      }
                    }
                  }
                }
              }
          }
        }
      }
  }
  if (debug_flag == 4) {
    wall_time = time_getWallclockSeconds() - wall_time;
    printf("Proc = %d     determine structure    %f\n", my_id, wall_time);
    fflush((void*)0);
  }
  P_diag_size = jj_counter;
  P_offd_size = jj_counter_offd;
  if (P_diag_size) {
    P_diag_j = (int*)(hypre_CAlloc((unsigned)P_diag_size, (unsigned)(sizeof(int))));
    P_diag_data = (double*)(hypre_CAlloc((unsigned)P_diag_size, (unsigned)(sizeof(double))));
  }
  if (P_offd_size) {
    P_offd_j = (int*)(hypre_CAlloc((unsigned)P_offd_size, (unsigned)(sizeof(int))));
    P_offd_data = (double*)(hypre_CAlloc((unsigned)P_offd_size, (unsigned)(sizeof(double))));
  }
  P_diag_i[n_coarse_old] = jj_counter;
  P_offd_i[n_coarse_old] = jj_counter_offd;
  jj_counter = start_indexing;
  jj_counter_offd = start_indexing;
  if (num_procs > 1) {
    big_insert_new_nodes(comm_pkg, extend_comm_pkg, fine_to_coarse, full_off_procNodes, my_first_cpt, fine_to_coarse_offd);
  }
  if (n_fine) {
    ahat = (double*)(hypre_CAlloc((unsigned)n_fine, (unsigned)(sizeof(double))));
    ihat = (int*)(hypre_CAlloc((unsigned)n_fine, (unsigned)(sizeof(int))));
    ipnt = (int*)(hypre_CAlloc((unsigned)n_fine, (unsigned)(sizeof(int))));
  }
  if (full_off_procNodes) {
    ahat_offd = (double*)(hypre_CAlloc((unsigned)full_off_procNodes, (unsigned)(sizeof(double))));
    ihat_offd = (int*)(hypre_CAlloc((unsigned)full_off_procNodes, (unsigned)(sizeof(int))));
    ipnt_offd = (int*)(hypre_CAlloc((unsigned)full_off_procNodes, (unsigned)(sizeof(int))));
  }
  for (i = 0; i < n_fine; i++) {
    P_marker[i] = -1;
    ahat[i] = 0;
    ihat[i] = -1;
  }
  for (i = 0; i < full_off_procNodes; i++) {
    P_marker_offd[i] = -1;
    ahat_offd[i] = 0;
    ihat_offd[i] = -1;
  }
  for (ii = 0; ii < n_coarse_old; ii++) {
    jj_begin_row = jj_counter;
    jj_begin_row_offd = jj_counter_offd;
    i = old_coarse_to_fine[ii];
    if ((CF_marker[i]) > 0) {
      P_diag_j[jj_counter] = fine_to_coarse[i];
      P_diag_data[jj_counter] = one;
      jj_counter++;
    }
    else
      if ((CF_marker[i]) == (-2)) {
        if (debug_flag == 4)
          wall_time = time_getWallclockSeconds();
        strong_f_marker--;
        for (jj = S_diag_i[i]; jj < (S_diag_i[i + 1]); jj++) {
          i1 = S_diag_j[jj];
          if ((CF_marker[i1]) > 0) {
            if ((P_marker[i1]) < jj_begin_row) {
              P_marker[i1] = jj_counter;
              P_diag_j[jj_counter] = i1;
              P_diag_data[jj_counter] = zero;
              jj_counter++;
            }
          }
          else
            if ((CF_marker[i1]) != (-3)) {
              P_marker[i1] = strong_f_marker;
              for (kk = S_diag_i[i1]; kk < (S_diag_i[i1 + 1]); kk++) {
                k1 = S_diag_j[kk];
                if ((CF_marker[k1]) > 0) {
                  if ((P_marker[k1]) < jj_begin_row) {
                    P_marker[k1] = jj_counter;
                    P_diag_j[jj_counter] = k1;
                    P_diag_data[jj_counter] = zero;
                    jj_counter++;
                  }
                }
              }
              if (num_procs > 1) {
                for (kk = S_offd_i[i1]; kk < (S_offd_i[i1 + 1]); kk++) {
                  if (col_offd_S_to_A)
                    k1 = col_offd_S_to_A[S_offd_j[kk]];
                  else
                    k1 = S_offd_j[kk];
                  if ((CF_marker_offd[k1]) > 0) {
                    if ((P_marker_offd[k1]) < jj_begin_row_offd) {
                      P_marker_offd[k1] = jj_counter_offd;
                      P_offd_j[jj_counter_offd] = k1;
                      P_offd_data[jj_counter_offd] = zero;
                      jj_counter_offd++;
                    }
                  }
                }
              }
            }
        }
        if (num_procs > 1) {
          for (jj = S_offd_i[i]; jj < (S_offd_i[i + 1]); jj++) {
            i1 = S_offd_j[jj];
            if (col_offd_S_to_A)
              i1 = col_offd_S_to_A[i1];
            if ((CF_marker_offd[i1]) > 0) {
              if ((P_marker_offd[i1]) < jj_begin_row_offd) {
                P_marker_offd[i1] = jj_counter_offd;
                P_offd_j[jj_counter_offd] = i1;
                P_offd_data[jj_counter_offd] = zero;
                jj_counter_offd++;
              }
            }
            else
              if ((CF_marker_offd[i1]) != (-3)) {
                P_marker_offd[i1] = strong_f_marker;
                for (kk = Sop_i[i1]; kk < (Sop_i[i1 + 1]); kk++) {
                  loc_col = Sop_j[kk];
                  if (loc_col > (-1)) {
                    if ((CF_marker[loc_col]) > 0) {
                      if ((P_marker[loc_col]) < jj_begin_row) {
                        P_marker[loc_col] = jj_counter;
                        P_diag_j[jj_counter] = loc_col;
                        P_diag_data[jj_counter] = zero;
                        jj_counter++;
                      }
                    }
                  }
                  else {
                    loc_col = (-loc_col) - 1;
                    if ((CF_marker_offd[loc_col]) > 0) {
                      if ((P_marker_offd[loc_col]) < jj_begin_row_offd) {
                        P_marker_offd[loc_col] = jj_counter_offd;
                        P_offd_j[jj_counter_offd] = loc_col;
                        P_offd_data[jj_counter_offd] = zero;
                        jj_counter_offd++;
                      }
                    }
                  }
                }
              }
          }
        }
        jj_end_row = jj_counter;
        jj_end_row_offd = jj_counter_offd;
        if (debug_flag == 4) {
          wall_time = time_getWallclockSeconds() - wall_time;
          wall_1 += wall_time;
          fflush((void*)0);
        }
        if (debug_flag == 4)
          wall_time = time_getWallclockSeconds();
        cnt_c = 0;
        cnt_f = jj_end_row - jj_begin_row;
        cnt_c_offd = 0;
        cnt_f_offd = jj_end_row_offd - jj_begin_row_offd;
        ihat[i] = cnt_f;
        ipnt[cnt_f] = i;
        ahat[cnt_f++] = A_diag_data[A_diag_i[i]];
        for (jj = (A_diag_i[i]) + 1; jj < (A_diag_i[i + 1]); jj++) {
          i1 = A_diag_j[jj];
          if ((P_marker[i1]) != strong_f_marker) {
            indx = ihat[i1];
            if (indx > (-1))
              ahat[indx] += A_diag_data[jj];
            else
              if ((P_marker[i1]) >= jj_begin_row) {
                ihat[i1] = cnt_c;
                ipnt[cnt_c] = i1;
                ahat[cnt_c++] += A_diag_data[jj];
              }
              else
                if ((CF_marker[i1]) != (-3)) {
                  ihat[i1] = cnt_f;
                  ipnt[cnt_f] = i1;
                  ahat[cnt_f++] += A_diag_data[jj];
                }
          }
          else {
            if ((num_functions == 1) || ((dof_func[i]) == (dof_func[i1]))) {
              distribute = (A_diag_data[jj]) / (A_diag_data[A_diag_i[i1]]);
              for (kk = (A_diag_i[i1]) + 1; kk < (A_diag_i[i1 + 1]); kk++) {
                k1 = A_diag_j[kk];
                indx = ihat[k1];
                if (indx > (-1))
                  (ahat[indx]) -= ((A_diag_data[kk]) * distribute);
                else
                  if ((P_marker[k1]) >= jj_begin_row) {
                    ihat[k1] = cnt_c;
                    ipnt[cnt_c] = k1;
                    (ahat[cnt_c++]) -= ((A_diag_data[kk]) * distribute);
                  }
                  else {
                    ihat[k1] = cnt_f;
                    ipnt[cnt_f] = k1;
                    (ahat[cnt_f++]) -= ((A_diag_data[kk]) * distribute);
                  }
              }
              if (num_procs > 1) {
                for (kk = A_offd_i[i1]; kk < (A_offd_i[i1 + 1]); kk++) {
                  k1 = A_offd_j[kk];
                  indx = ihat_offd[k1];
                  if ((num_functions == 1) || ((dof_func[i1]) == (dof_func_offd[k1]))) {
                    if (indx > (-1))
                      (ahat_offd[indx]) -= ((A_offd_data[kk]) * distribute);
                    else
                      if ((P_marker_offd[k1]) >= jj_begin_row_offd) {
                        ihat_offd[k1] = cnt_c_offd;
                        ipnt_offd[cnt_c_offd] = k1;
                        (ahat_offd[cnt_c_offd++]) -= ((A_offd_data[kk]) * distribute);
                      }
                      else {
                        ihat_offd[k1] = cnt_f_offd;
                        ipnt_offd[cnt_f_offd] = k1;
                        (ahat_offd[cnt_f_offd++]) -= ((A_offd_data[kk]) * distribute);
                      }
                  }
                }
              }
            }
          }
        }
        if (num_procs > 1) {
          for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
            i1 = A_offd_j[jj];
            if ((P_marker_offd[i1]) != strong_f_marker) {
              indx = ihat_offd[i1];
              if (indx > (-1))
                ahat_offd[indx] += A_offd_data[jj];
              else
                if ((P_marker_offd[i1]) >= jj_begin_row_offd) {
                  ihat_offd[i1] = cnt_c_offd;
                  ipnt_offd[cnt_c_offd] = i1;
                  ahat_offd[cnt_c_offd++] += A_offd_data[jj];
                }
                else
                  if ((CF_marker_offd[i1]) != (-3)) {
                    ihat_offd[i1] = cnt_f_offd;
                    ipnt_offd[cnt_f_offd] = i1;
                    ahat_offd[cnt_f_offd++] += A_offd_data[jj];
                  }
            }
            else {
              if ((num_functions == 1) || ((dof_func[i]) == (dof_func_offd[i1]))) {
                distribute = (A_offd_data[jj]) / (A_ext_data[A_ext_i[i1]]);
                for (kk = (A_ext_i[i1]) + 1; kk < (A_ext_i[i1 + 1]); kk++) {
                  loc_col = A_ext_j[kk];
                  if (loc_col > (-1)) {
                    indx = ihat[loc_col];
                    if (indx > (-1))
                      (ahat[indx]) -= ((A_ext_data[kk]) * distribute);
                    else
                      if ((P_marker[loc_col]) >= jj_begin_row) {
                        ihat[loc_col] = cnt_c;
                        ipnt[cnt_c] = loc_col;
                        (ahat[cnt_c++]) -= ((A_ext_data[kk]) * distribute);
                      }
                      else {
                        ihat[loc_col] = cnt_f;
                        ipnt[cnt_f] = loc_col;
                        (ahat[cnt_f++]) -= ((A_ext_data[kk]) * distribute);
                      }
                  }
                  else {
                    loc_col = (-loc_col) - 1;
                    if ((num_functions == 1) || ((dof_func_offd[loc_col]) == (dof_func_offd[i1]))) {
                      indx = ihat_offd[loc_col];
                      if (indx > (-1))
                        (ahat_offd[indx]) -= ((A_ext_data[kk]) * distribute);
                      else
                        if ((P_marker_offd[loc_col]) >= jj_begin_row_offd) {
                          ihat_offd[loc_col] = cnt_c_offd;
                          ipnt_offd[cnt_c_offd] = loc_col;
                          (ahat_offd[cnt_c_offd++]) -= ((A_ext_data[kk]) * distribute);
                        }
                        else {
                          ihat_offd[loc_col] = cnt_f_offd;
                          ipnt_offd[cnt_f_offd] = loc_col;
                          (ahat_offd[cnt_f_offd++]) -= ((A_ext_data[kk]) * distribute);
                        }
                    }
                  }
                }
              }
            }
          }
        }
        if (debug_flag == 4) {
          wall_time = time_getWallclockSeconds() - wall_time;
          wall_2 += wall_time;
          fflush((void*)0);
        }
        if (debug_flag == 4)
          wall_time = time_getWallclockSeconds();
        diagonal = ahat[cnt_c];
        ahat[cnt_c] = 0;
        sum_pos = 0;
        sum_pos_C = 0;
        sum_neg = 0;
        sum_neg_C = 0;
        sum = 0;
        sum_C = 0;
        if (sep_weight == 1) {
          for (jj = 0; jj < cnt_c; jj++) {
            if ((ahat[jj]) > 0) {
              sum_pos_C += ahat[jj];
            }
            else {
              sum_neg_C += ahat[jj];
            }
          }
          if (num_procs > 1) {
            for (jj = 0; jj < cnt_c_offd; jj++) {
              if ((ahat_offd[jj]) > 0) {
                sum_pos_C += ahat_offd[jj];
              }
              else {
                sum_neg_C += ahat_offd[jj];
              }
            }
          }
          sum_pos = sum_pos_C;
          sum_neg = sum_neg_C;
          for (jj = cnt_c + 1; jj < cnt_f; jj++) {
            if ((ahat[jj]) > 0) {
              sum_pos += ahat[jj];
            }
            else {
              sum_neg += ahat[jj];
            }
            ahat[jj] = 0;
          }
          if (num_procs > 1) {
            for (jj = cnt_c_offd; jj < cnt_f_offd; jj++) {
              if ((ahat_offd[jj]) > 0) {
                sum_pos += ahat_offd[jj];
              }
              else {
                sum_neg += ahat_offd[jj];
              }
              ahat_offd[jj] = 0;
            }
          }
          if (sum_neg_C)
            alfa = (sum_neg / sum_neg_C) / diagonal;
          if (sum_pos_C)
            beta = (sum_pos / sum_pos_C) / diagonal;
          for (jj = jj_begin_row; jj < jj_end_row; jj++) {
            j1 = ihat[P_diag_j[jj]];
            if ((ahat[j1]) > 0)
              P_diag_data[jj] = (-beta) * (ahat[j1]);
            else
              P_diag_data[jj] = (-alfa) * (ahat[j1]);
            P_diag_j[jj] = fine_to_coarse[P_diag_j[jj]];
            ahat[j1] = 0;
          }
          for (jj = 0; jj < cnt_f; jj++)
            ihat[ipnt[jj]] = -1;
          if (num_procs > 1) {
            for (jj = jj_begin_row_offd; jj < jj_end_row_offd; jj++) {
              j1 = ihat_offd[P_offd_j[jj]];
              if ((ahat_offd[j1]) > 0)
                P_offd_data[jj] = (-beta) * (ahat_offd[j1]);
              else
                P_offd_data[jj] = (-alfa) * (ahat_offd[j1]);
              ahat_offd[j1] = 0;
            }
            for (jj = 0; jj < cnt_f_offd; jj++)
              ihat_offd[ipnt_offd[jj]] = -1;
          }
        }
        else {
          for (jj = 0; jj < cnt_c; jj++) {
            sum_C += ahat[jj];
          }
          if (num_procs > 1) {
            for (jj = 0; jj < cnt_c_offd; jj++) {
              sum_C += ahat_offd[jj];
            }
          }
          sum = sum_C;
          for (jj = cnt_c + 1; jj < cnt_f; jj++) {
            sum += ahat[jj];
            ahat[jj] = 0;
          }
          if (num_procs > 1) {
            for (jj = cnt_c_offd; jj < cnt_f_offd; jj++) {
              sum += ahat_offd[jj];
              ahat_offd[jj] = 0;
            }
          }
          if (sum_C)
            alfa = (sum / sum_C) / diagonal;
          for (jj = jj_begin_row; jj < jj_end_row; jj++) {
            j1 = ihat[P_diag_j[jj]];
            P_diag_data[jj] = (-alfa) * (ahat[j1]);
            P_diag_j[jj] = fine_to_coarse[P_diag_j[jj]];
            ahat[j1] = 0;
          }
          for (jj = 0; jj < cnt_f; jj++)
            ihat[ipnt[jj]] = -1;
          if (num_procs > 1) {
            for (jj = jj_begin_row_offd; jj < jj_end_row_offd; jj++) {
              j1 = ihat_offd[P_offd_j[jj]];
              P_offd_data[jj] = (-alfa) * (ahat_offd[j1]);
              ahat_offd[j1] = 0;
            }
            for (jj = 0; jj < cnt_f_offd; jj++)
              ihat_offd[ipnt_offd[jj]] = -1;
          }
        }
        if (debug_flag == 4) {
          wall_time = time_getWallclockSeconds() - wall_time;
          wall_3 += wall_time;
          fflush((void*)0);
        }
      }
  }
  if (debug_flag == 4) {
    printf("Proc = %d fill part 1 %f part 2 %f  part 3 %f\n", my_id, wall_1, wall_2, wall_3);
    fflush((void*)0);
  }
  P = hypre_ParCSRMatrixCreate(comm, total_old_global_cpts, total_global_cpts, num_old_cpts_global, num_cpts_global, 0, P_diag_i[n_coarse_old], P_offd_i[n_coarse_old]);
  P_diag = (P)->diag;
  (P_diag)->data = P_diag_data;
  (P_diag)->i = P_diag_i;
  (P_diag)->j = P_diag_j;
  P_offd = (P)->offd;
  (P_offd)->data = P_offd_data;
  (P_offd)->i = P_offd_i;
  (P_offd)->j = P_offd_j;
  (P)->owns_row_starts = 0;
  if ((trunc_factor != 0.0) || (max_elmts > 0)) {
    hypre_BoomerAMGInterpTruncation(P, trunc_factor, max_elmts);
    P_diag_data = (P_diag)->data;
    P_diag_i = (P_diag)->i;
    P_diag_j = (P_diag)->j;
    P_offd_data = (P_offd)->data;
    P_offd_i = (P_offd)->i;
    P_offd_j = (P_offd)->j;
    P_diag_size = P_diag_i[n_coarse_old];
    P_offd_size = P_offd_i[n_coarse_old];
  }
  num_cols_P_offd = 0;
  if (P_offd_size) {
    num_cols_P_offd = 0;
    for (i = 0; i < P_offd_size; i++) {
      index = P_offd_j[i];
      if ((tmp_CF_marker_offd[index]) == 1) {
        num_cols_P_offd++;
        tmp_CF_marker_offd[index] = 2;
      }
    }
    if (num_cols_P_offd) {
      col_map_offd_P = (int*)(hypre_CAlloc((unsigned)num_cols_P_offd, (unsigned)(sizeof(int))));
      tmp_map_offd = (int*)(hypre_CAlloc((unsigned)num_cols_P_offd, (unsigned)(sizeof(int))));
    }
    index = 0;
    for (i = 0; i < num_cols_P_offd; i++) {
      while ((tmp_CF_marker_offd[index]) == (-1))
        index++;
      col_map_offd_P[i] = fine_to_coarse_offd[index];
      tmp_map_offd[i] = index++;
    }
    hypre_BigQsortbi(col_map_offd_P, tmp_map_offd, 0, num_cols_P_offd - 1);
    for (i = 0; i < num_cols_P_offd; i++)
      tmp_CF_marker_offd[tmp_map_offd[i]] = i;
    for (i = 0; i < P_offd_size; i++)
      P_offd_j[i] = tmp_CF_marker_offd[P_offd_j[i]];
  }
  if (num_cols_P_offd) {
    (P)->col_map_offd = col_map_offd_P;
    (P_offd)->num_cols = num_cols_P_offd;
    hypre_Free((char*)tmp_map_offd), tmp_map_offd = (void*)0;
  }
  hypre_MatvecCommPkgCreate(P);
  for (i = 0; i < n_fine; i++)
    if ((CF_marker[i]) < (-1))
      CF_marker[i] = -1;
  *P_ptr = P;
  hypre_Free((char*)fine_to_coarse), fine_to_coarse = (void*)0;
  hypre_Free((char*)old_coarse_to_fine), old_coarse_to_fine = (void*)0;
  hypre_Free((char*)P_marker), P_marker = (void*)0;
  hypre_Free((char*)ahat), ahat = (void*)0;
  hypre_Free((char*)ihat), ihat = (void*)0;
  hypre_Free((char*)ipnt), ipnt = (void*)0;
  if (full_off_procNodes) {
    hypre_Free((char*)ahat_offd), ahat_offd = (void*)0;
    hypre_Free((char*)ihat_offd), ihat_offd = (void*)0;
    hypre_Free((char*)ipnt_offd), ipnt_offd = (void*)0;
  }
  if (num_procs > 1) {
    hypre_BigCSRMatrixDestroy(Sop);
    hypre_BigCSRMatrixDestroy(A_ext);
    hypre_Free((char*)fine_to_coarse_offd), fine_to_coarse_offd = (void*)0;
    hypre_Free((char*)P_marker_offd), P_marker_offd = (void*)0;
    hypre_Free((char*)CF_marker_offd), CF_marker_offd = (void*)0;
    hypre_Free((char*)tmp_CF_marker_offd), tmp_CF_marker_offd = (void*)0;
    if (num_functions > 1)
      hypre_Free((char*)dof_func_offd), dof_func_offd = (void*)0;
    hypre_Free((char*)found), found = (void*)0;
    hypre_MatvecCommPkgDestroy(extend_comm_pkg);
  }
  return hypre__global_error;
}
int hypre_BoomerAMGBuildPartialExtPIInterp(hypre_ParCSRMatrix* A, int* CF_marker, hypre_ParCSRMatrix* S, int* num_cpts_global, int* num_old_cpts_global, int num_functions, int* dof_func, int debug_flag, double trunc_factor, int max_elmts, int* col_offd_S_to_A, hypre_ParCSRMatrix** P_ptr) {
  MPI_Comm comm = (A)->comm;
  hypre_ParCSRCommPkg* comm_pkg = (A)->comm_pkg;
  int my_id;
  int num_procs;
  hypre_CSRMatrix* A_diag = (A)->diag;
  double* A_diag_data = (A_diag)->data;
  int* A_diag_i = (A_diag)->i;
  int* A_diag_j = (A_diag)->j;
  hypre_CSRMatrix* A_offd = (A)->offd;
  double* A_offd_data = (A_offd)->data;
  int* A_offd_i = (A_offd)->i;
  int* A_offd_j = (A_offd)->j;
  int num_cols_A_offd = (A_offd)->num_cols;
  int* col_map_offd = (A)->col_map_offd;
  int n_fine = (A_diag)->num_rows;
  int col_1 = (A)->first_row_index;
  int local_numrows = (A_diag)->num_rows;
  int col_n = col_1 + (int)local_numrows;
  int total_global_cpts;
  int my_first_cpt;
  int total_old_global_cpts;
  int my_first_old_cpt;
  int n_coarse;
  int n_coarse_old;
  hypre_CSRMatrix* S_diag = (S)->diag;
  int* S_diag_i = (S_diag)->i;
  int* S_diag_j = (S_diag)->j;
  hypre_CSRMatrix* S_offd = (S)->offd;
  int* S_offd_i = (S_offd)->i;
  int* S_offd_j = (S_offd)->j;
  hypre_ParCSRMatrix* P;
  hypre_CSRMatrix* P_diag;
  hypre_CSRMatrix* P_offd;
  double* P_diag_data = (void*)0;
  int* P_diag_i;
  int* P_diag_j = (void*)0;
  double* P_offd_data = (void*)0;
  int* P_offd_i;
  int* P_offd_j = (void*)0;
  int* col_map_offd_P;
  int* tmp_map_offd;
  int P_diag_size;
  int P_offd_size;
  int* P_marker = (void*)0;
  int* P_marker_offd = (void*)0;
  int* CF_marker_offd = (void*)0;
  int* tmp_CF_marker_offd = (void*)0;
  int* dof_func_offd = (void*)0;
  hypre_BigCSRMatrix* A_ext;
  double* A_ext_data;
  int* A_ext_i;
  int* big_A_ext_j;
  int* A_ext_j;
  int* fine_to_coarse = (void*)0;
  int* old_coarse_to_fine = (void*)0;
  int* fine_to_coarse_offd = (void*)0;
  int* found;
  int num_cols_P_offd;
  int newoff;
  int loc_col;
  int A_ext_rows;
  int full_off_procNodes;
  hypre_BigCSRMatrix* Sop;
  int* Sop_i;
  int* big_Sop_j;
  int* Sop_j;
  int Soprows;
  int sgn;
  int jj_counter;
  int jj_counter_offd;
  int jj_begin_row;
  int jj_end_row;
  int jj_begin_row_offd = 0;
  int jj_end_row_offd = 0;
  int coarse_counter;
  int coarse_counter_offd;
  double sum;
  double diagonal;
  double distribute;
  int strong_f_marker = -2;
  int index;
  int ii;
  int cnt;
  int old_cnt;
  int start_indexing = 0;
  int i;
  int i1;
  int i2;
  int jj;
  int kk;
  int k1;
  int jj1;
  double zero = 0.0;
  double one = 1.0;
  double wall_time;
  hypre_ParCSRCommPkg* extend_comm_pkg = (void*)0;
  if (debug_flag == 4)
    wall_time = time_getWallclockSeconds();
  MPI_Comm_size(comm, &(num_procs));
  MPI_Comm_rank(comm, &(my_id));
  my_first_cpt = num_cpts_global[my_id];
  my_first_old_cpt = num_old_cpts_global[my_id];
  total_global_cpts = num_cpts_global[num_procs];
  total_old_global_cpts = num_old_cpts_global[num_procs];
  n_coarse_old = (int)((num_old_cpts_global[my_id + 1]) - (num_old_cpts_global[my_id]));
  n_coarse = (int)((num_cpts_global[my_id + 1]) - (num_cpts_global[my_id]));
  if (!comm_pkg) {
    hypre_MatvecCommPkgCreate(A);
    comm_pkg = (A)->comm_pkg;
  }
  newoff = 0;
  full_off_procNodes = 0;
  if (num_procs > 1) {
    A_ext = hypre_ParCSRMatrixExtractBigExt(A, A, 1);
    A_ext_i = (A_ext)->i;
    big_A_ext_j = (A_ext)->j;
    A_ext_data = (A_ext)->data;
    A_ext_rows = (A_ext)->num_rows;
    Sop = hypre_ParCSRMatrixExtractBigExt(S, A, 0);
    Sop_i = (Sop)->i;
    big_Sop_j = (Sop)->j;
    Soprows = (Sop)->num_rows;
    newoff = new_offd_nodes(&(found), A_ext_rows, A_ext_i, big_A_ext_j, &(A_ext_j), Soprows, col_map_offd, col_1, col_n, Sop_i, big_Sop_j, &(Sop_j), CF_marker, comm_pkg);
    (A_ext)->j = (void*)0;
    (Sop)->j = (void*)0;
    if (newoff >= 0)
      full_off_procNodes = newoff + num_cols_A_offd;
    else
      return 1;
    hypre_ParCSRFindExtendCommPkg(A, newoff, found, &(extend_comm_pkg));
    CF_marker_offd = (int*)(hypre_CAlloc((unsigned)full_off_procNodes, (unsigned)(sizeof(int))));
    if ((num_functions > 1) && (full_off_procNodes > 0))
      dof_func_offd = (int*)(hypre_CAlloc((unsigned)full_off_procNodes, (unsigned)(sizeof(int))));
    alt_insert_new_nodes(comm_pkg, extend_comm_pkg, CF_marker, full_off_procNodes, CF_marker_offd);
    if (num_functions > 1)
      alt_insert_new_nodes(comm_pkg, extend_comm_pkg, dof_func, full_off_procNodes, dof_func_offd);
  }
  P_diag_i = (int*)(hypre_CAlloc((unsigned)(n_fine + 1), (unsigned)(sizeof(int))));
  P_offd_i = (int*)(hypre_CAlloc((unsigned)(n_fine + 1), (unsigned)(sizeof(int))));
  if (n_coarse_old)
    old_coarse_to_fine = (int*)(hypre_CAlloc((unsigned)n_coarse_old, (unsigned)(sizeof(int))));
  if (n_fine) {
    fine_to_coarse = (int*)(hypre_CAlloc((unsigned)n_fine, (unsigned)(sizeof(int))));
    P_marker = (int*)(hypre_CAlloc((unsigned)n_fine, (unsigned)(sizeof(int))));
  }
  if (full_off_procNodes) {
    P_marker_offd = (int*)(hypre_CAlloc((unsigned)full_off_procNodes, (unsigned)(sizeof(int))));
    fine_to_coarse_offd = (int*)(hypre_CAlloc((unsigned)full_off_procNodes, (unsigned)(sizeof(int))));
    tmp_CF_marker_offd = (int*)(hypre_CAlloc((unsigned)full_off_procNodes, (unsigned)(sizeof(int))));
  }
  for (i = 0; i < full_off_procNodes; i++) {
    P_marker_offd[i] = -1;
    tmp_CF_marker_offd[i] = -1;
    fine_to_coarse_offd[i] = -1;
  }
  for (i = 0; i < n_fine; i++) {
    P_marker[i] = -1;
    fine_to_coarse[i] = -1;
  }
  jj_counter = start_indexing;
  jj_counter_offd = start_indexing;
  coarse_counter = 0;
  coarse_counter_offd = 0;
  cnt = 0;
  old_cnt = 0;
  for (i = 0; i < n_fine; i++) {
    fine_to_coarse[i] = -1;
    if ((CF_marker[i]) == 1) {
      fine_to_coarse[i] = cnt++;
      old_coarse_to_fine[old_cnt++] = i;
    }
    else
      if ((CF_marker[i]) == (-2)) {
        old_coarse_to_fine[old_cnt++] = i;
      }
  }
  for (ii = 0; ii < n_coarse_old; ii++) {
    P_diag_i[ii] = jj_counter;
    if (num_procs > 1)
      P_offd_i[ii] = jj_counter_offd;
    i = old_coarse_to_fine[ii];
    if ((CF_marker[i]) >= 0) {
      jj_counter++;
      coarse_counter++;
    }
    else
      if ((CF_marker[i]) == (-2)) {
        for (jj = S_diag_i[i]; jj < (S_diag_i[i + 1]); jj++) {
          i1 = S_diag_j[jj];
          if ((CF_marker[i1]) > 0) {
            if ((P_marker[i1]) < (P_diag_i[ii])) {
              P_marker[i1] = jj_counter;
              jj_counter++;
            }
          }
          else
            if ((CF_marker[i1]) != (-3)) {
              for (kk = S_diag_i[i1]; kk < (S_diag_i[i1 + 1]); kk++) {
                k1 = S_diag_j[kk];
                if ((CF_marker[k1]) > 0) {
                  if ((P_marker[k1]) < (P_diag_i[ii])) {
                    P_marker[k1] = jj_counter;
                    jj_counter++;
                  }
                }
              }
              if (num_procs > 1) {
                for (kk = S_offd_i[i1]; kk < (S_offd_i[i1 + 1]); kk++) {
                  if (col_offd_S_to_A)
                    k1 = col_offd_S_to_A[S_offd_j[kk]];
                  else
                    k1 = S_offd_j[kk];
                  if ((CF_marker_offd[k1]) > 0) {
                    if ((P_marker_offd[k1]) < (P_offd_i[ii])) {
                      tmp_CF_marker_offd[k1] = 1;
                      P_marker_offd[k1] = jj_counter_offd;
                      jj_counter_offd++;
                    }
                  }
                }
              }
            }
        }
        if (num_procs > 1) {
          for (jj = S_offd_i[i]; jj < (S_offd_i[i + 1]); jj++) {
            i1 = S_offd_j[jj];
            if (col_offd_S_to_A)
              i1 = col_offd_S_to_A[i1];
            if ((CF_marker_offd[i1]) > 0) {
              if ((P_marker_offd[i1]) < (P_offd_i[ii])) {
                tmp_CF_marker_offd[i1] = 1;
                P_marker_offd[i1] = jj_counter_offd;
                jj_counter_offd++;
              }
            }
            else
              if ((CF_marker_offd[i1]) != (-3)) {
                for (kk = Sop_i[i1]; kk < (Sop_i[i1 + 1]); kk++) {
                  loc_col = Sop_j[kk];
                  if (loc_col > (-1)) {
                    if ((CF_marker[loc_col]) > 0) {
                      if ((P_marker[loc_col]) < (P_diag_i[ii])) {
                        P_marker[loc_col] = jj_counter;
                        jj_counter++;
                      }
                    }
                  }
                  else {
                    loc_col = (-loc_col) - 1;
                    if ((CF_marker_offd[loc_col]) > 0) {
                      if ((P_marker_offd[loc_col]) < (P_offd_i[ii])) {
                        P_marker_offd[loc_col] = jj_counter_offd;
                        tmp_CF_marker_offd[loc_col] = 1;
                        jj_counter_offd++;
                      }
                    }
                  }
                }
              }
          }
        }
      }
  }
  if (debug_flag == 4) {
    wall_time = time_getWallclockSeconds() - wall_time;
    printf("Proc = %d     determine structure    %f\n", my_id, wall_time);
    fflush((void*)0);
  }
  if (debug_flag == 4)
    wall_time = time_getWallclockSeconds();
  P_diag_size = jj_counter;
  P_offd_size = jj_counter_offd;
  if (P_diag_size) {
    P_diag_j = (int*)(hypre_CAlloc((unsigned)P_diag_size, (unsigned)(sizeof(int))));
    P_diag_data = (double*)(hypre_CAlloc((unsigned)P_diag_size, (unsigned)(sizeof(double))));
  }
  if (P_offd_size) {
    P_offd_j = (int*)(hypre_CAlloc((unsigned)P_offd_size, (unsigned)(sizeof(int))));
    P_offd_data = (double*)(hypre_CAlloc((unsigned)P_offd_size, (unsigned)(sizeof(double))));
  }
  P_diag_i[n_coarse_old] = jj_counter;
  P_offd_i[n_coarse_old] = jj_counter_offd;
  jj_counter = start_indexing;
  jj_counter_offd = start_indexing;
  if (num_procs > 1) {
    big_insert_new_nodes(comm_pkg, extend_comm_pkg, fine_to_coarse, full_off_procNodes, my_first_cpt, fine_to_coarse_offd);
  }
  for (i = 0; i < n_fine; i++)
    P_marker[i] = -1;
  for (i = 0; i < full_off_procNodes; i++)
    P_marker_offd[i] = -1;
  for (ii = 0; ii < n_coarse_old; ii++) {
    jj_begin_row = jj_counter;
    jj_begin_row_offd = jj_counter_offd;
    i = old_coarse_to_fine[ii];
    if ((CF_marker[i]) > 0) {
      P_diag_j[jj_counter] = fine_to_coarse[i];
      P_diag_data[jj_counter] = one;
      jj_counter++;
    }
    else
      if ((CF_marker[i]) == (-2)) {
        strong_f_marker--;
        for (jj = S_diag_i[i]; jj < (S_diag_i[i + 1]); jj++) {
          i1 = S_diag_j[jj];
          if ((CF_marker[i1]) > 0) {
            if ((P_marker[i1]) < jj_begin_row) {
              P_marker[i1] = jj_counter;
              P_diag_j[jj_counter] = fine_to_coarse[i1];
              P_diag_data[jj_counter] = zero;
              jj_counter++;
            }
          }
          else
            if ((CF_marker[i1]) != (-3)) {
              P_marker[i1] = strong_f_marker;
              for (kk = S_diag_i[i1]; kk < (S_diag_i[i1 + 1]); kk++) {
                k1 = S_diag_j[kk];
                if ((CF_marker[k1]) > 0) {
                  if ((P_marker[k1]) < jj_begin_row) {
                    P_marker[k1] = jj_counter;
                    P_diag_j[jj_counter] = fine_to_coarse[k1];
                    P_diag_data[jj_counter] = zero;
                    jj_counter++;
                  }
                }
              }
              if (num_procs > 1) {
                for (kk = S_offd_i[i1]; kk < (S_offd_i[i1 + 1]); kk++) {
                  if (col_offd_S_to_A)
                    k1 = col_offd_S_to_A[S_offd_j[kk]];
                  else
                    k1 = S_offd_j[kk];
                  if ((CF_marker_offd[k1]) > 0) {
                    if ((P_marker_offd[k1]) < jj_begin_row_offd) {
                      P_marker_offd[k1] = jj_counter_offd;
                      P_offd_j[jj_counter_offd] = k1;
                      P_offd_data[jj_counter_offd] = zero;
                      jj_counter_offd++;
                    }
                  }
                }
              }
            }
        }
        if (num_procs > 1) {
          for (jj = S_offd_i[i]; jj < (S_offd_i[i + 1]); jj++) {
            i1 = S_offd_j[jj];
            if (col_offd_S_to_A)
              i1 = col_offd_S_to_A[i1];
            if ((CF_marker_offd[i1]) > 0) {
              if ((P_marker_offd[i1]) < jj_begin_row_offd) {
                P_marker_offd[i1] = jj_counter_offd;
                P_offd_j[jj_counter_offd] = i1;
                P_offd_data[jj_counter_offd] = zero;
                jj_counter_offd++;
              }
            }
            else
              if ((CF_marker_offd[i1]) != (-3)) {
                P_marker_offd[i1] = strong_f_marker;
                for (kk = Sop_i[i1]; kk < (Sop_i[i1 + 1]); kk++) {
                  loc_col = Sop_j[kk];
                  if (loc_col > (-1)) {
                    if ((CF_marker[loc_col]) > 0) {
                      if ((P_marker[loc_col]) < jj_begin_row) {
                        P_marker[loc_col] = jj_counter;
                        P_diag_j[jj_counter] = fine_to_coarse[loc_col];
                        P_diag_data[jj_counter] = zero;
                        jj_counter++;
                      }
                    }
                  }
                  else {
                    loc_col = (-loc_col) - 1;
                    if ((CF_marker_offd[loc_col]) > 0) {
                      if ((P_marker_offd[loc_col]) < jj_begin_row_offd) {
                        P_marker_offd[loc_col] = jj_counter_offd;
                        P_offd_j[jj_counter_offd] = loc_col;
                        P_offd_data[jj_counter_offd] = zero;
                        jj_counter_offd++;
                      }
                    }
                  }
                }
              }
          }
        }
        jj_end_row = jj_counter;
        jj_end_row_offd = jj_counter_offd;
        diagonal = A_diag_data[A_diag_i[i]];
        for (jj = (A_diag_i[i]) + 1; jj < (A_diag_i[i + 1]); jj++) {
          i1 = A_diag_j[jj];
          if ((P_marker[i1]) >= jj_begin_row) {
            P_diag_data[P_marker[i1]] += A_diag_data[jj];
          }
          else
            if ((P_marker[i1]) == strong_f_marker) {
              sum = zero;
              sgn = 1;
              if ((A_diag_data[A_diag_i[i1]]) < 0)
                sgn = -1;
              for (jj1 = (A_diag_i[i1]) + 1; jj1 < (A_diag_i[i1 + 1]); jj1++) {
                i2 = A_diag_j[jj1];
                if ((((P_marker[i2]) >= jj_begin_row) || (i2 == i)) && ((sgn * (A_diag_data[jj1])) < 0))
                  sum += A_diag_data[jj1];
              }
              if (num_procs > 1) {
                for (jj1 = A_offd_i[i1]; jj1 < (A_offd_i[i1 + 1]); jj1++) {
                  i2 = A_offd_j[jj1];
                  if (((P_marker_offd[i2]) >= jj_begin_row_offd) && ((sgn * (A_offd_data[jj1])) < 0))
                    sum += A_offd_data[jj1];
                }
              }
              if (sum != 0) {
                distribute = (A_diag_data[jj]) / sum;
                for (jj1 = (A_diag_i[i1]) + 1; jj1 < (A_diag_i[i1 + 1]); jj1++) {
                  i2 = A_diag_j[jj1];
                  if (((P_marker[i2]) >= jj_begin_row) && ((sgn * (A_diag_data[jj1])) < 0))
                    P_diag_data[P_marker[i2]] += distribute * (A_diag_data[jj1]);
                  if ((i2 == i) && ((sgn * (A_diag_data[jj1])) < 0))
                    diagonal += distribute * (A_diag_data[jj1]);
                }
                if (num_procs > 1) {
                  for (jj1 = A_offd_i[i1]; jj1 < (A_offd_i[i1 + 1]); jj1++) {
                    i2 = A_offd_j[jj1];
                    if (((P_marker_offd[i2]) >= jj_begin_row_offd) && ((sgn * (A_offd_data[jj1])) < 0))
                      P_offd_data[P_marker_offd[i2]] += distribute * (A_offd_data[jj1]);
                  }
                }
              }
              else {
                diagonal += A_diag_data[jj];
              }
            }
            else
              if ((CF_marker[i1]) != (-3)) {
                if ((num_functions == 1) || ((dof_func[i]) == (dof_func[i1])))
                  diagonal += A_diag_data[jj];
              }
        }
        if (num_procs > 1) {
          for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
            i1 = A_offd_j[jj];
            if ((P_marker_offd[i1]) >= jj_begin_row_offd)
              P_offd_data[P_marker_offd[i1]] += A_offd_data[jj];
            else
              if ((P_marker_offd[i1]) == strong_f_marker) {
                sum = zero;
                sgn = 1;
                if ((A_ext_data[A_ext_i[i1]]) < 0)
                  sgn = -1;
                for (jj1 = (A_ext_i[i1]) + 1; jj1 < (A_ext_i[i1 + 1]); jj1++) {
                  loc_col = A_ext_j[jj1];
                  if (loc_col > (-1)) {
                    if ((((P_marker[loc_col]) >= jj_begin_row) || (loc_col == i)) && ((sgn * (A_ext_data[jj1])) < 0))
                      sum += A_ext_data[jj1];
                  }
                  else {
                    loc_col = (-loc_col) - 1;
                    if (((P_marker_offd[loc_col]) >= jj_begin_row_offd) && ((sgn * (A_ext_data[jj1])) < 0))
                      sum += A_ext_data[jj1];
                  }
                }
                if (sum != 0) {
                  distribute = (A_offd_data[jj]) / sum;
                  for (jj1 = (A_ext_i[i1]) + 1; jj1 < (A_ext_i[i1 + 1]); jj1++) {
                    loc_col = A_ext_j[jj1];
                    if (loc_col > (-1)) {
                      if (((P_marker[loc_col]) >= jj_begin_row) && ((sgn * (A_ext_data[jj1])) < 0))
                        P_diag_data[P_marker[loc_col]] += distribute * (A_ext_data[jj1]);
                      if ((loc_col == i) && ((sgn * (A_ext_data[jj1])) < 0))
                        diagonal += distribute * (A_ext_data[jj1]);
                    }
                    else {
                      loc_col = (-loc_col) - 1;
                      if (((P_marker_offd[loc_col]) >= jj_begin_row_offd) && ((sgn * (A_ext_data[jj1])) < 0))
                        P_offd_data[P_marker_offd[loc_col]] += distribute * (A_ext_data[jj1]);
                    }
                  }
                }
                else {
                  diagonal += A_offd_data[jj];
                }
              }
              else
                if ((CF_marker_offd[i1]) != (-3)) {
                  if ((num_functions == 1) || ((dof_func[i]) == (dof_func_offd[i1])))
                    diagonal += A_offd_data[jj];
                }
          }
        }
        for (jj = jj_begin_row; jj < jj_end_row; jj++)
          (P_diag_data[jj]) /= (-diagonal);
        for (jj = jj_begin_row_offd; jj < jj_end_row_offd; jj++)
          (P_offd_data[jj]) /= (-diagonal);
      }
    strong_f_marker--;
  }
  if (debug_flag == 4) {
    wall_time = time_getWallclockSeconds() - wall_time;
    printf("Proc = %d     fill structure    %f\n", my_id, wall_time);
    fflush((void*)0);
  }
  P = hypre_ParCSRMatrixCreate(comm, total_old_global_cpts, total_global_cpts, num_old_cpts_global, num_cpts_global, 0, P_diag_i[n_coarse_old], P_offd_i[n_coarse_old]);
  P_diag = (P)->diag;
  (P_diag)->data = P_diag_data;
  (P_diag)->i = P_diag_i;
  (P_diag)->j = P_diag_j;
  P_offd = (P)->offd;
  (P_offd)->data = P_offd_data;
  (P_offd)->i = P_offd_i;
  (P_offd)->j = P_offd_j;
  (P)->owns_row_starts = 0;
  if ((trunc_factor != 0.0) || (max_elmts > 0)) {
    hypre_BoomerAMGInterpTruncation(P, trunc_factor, max_elmts);
    P_diag_data = (P_diag)->data;
    P_diag_i = (P_diag)->i;
    P_diag_j = (P_diag)->j;
    P_offd_data = (P_offd)->data;
    P_offd_i = (P_offd)->i;
    P_offd_j = (P_offd)->j;
    P_diag_size = P_diag_i[n_coarse_old];
    P_offd_size = P_offd_i[n_coarse_old];
  }
  num_cols_P_offd = 0;
  if (P_offd_size) {
    num_cols_P_offd = 0;
    for (i = 0; i < P_offd_size; i++) {
      index = P_offd_j[i];
      if ((tmp_CF_marker_offd[index]) == 1) {
        num_cols_P_offd++;
        tmp_CF_marker_offd[index] = 2;
      }
    }
    if (num_cols_P_offd) {
      col_map_offd_P = (int*)(hypre_CAlloc((unsigned)num_cols_P_offd, (unsigned)(sizeof(int))));
      tmp_map_offd = (int*)(hypre_CAlloc((unsigned)num_cols_P_offd, (unsigned)(sizeof(int))));
    }
    index = 0;
    for (i = 0; i < num_cols_P_offd; i++) {
      while ((tmp_CF_marker_offd[index]) != 2)
        index++;
      col_map_offd_P[i] = fine_to_coarse_offd[index];
      tmp_map_offd[i] = index++;
    }
    hypre_BigQsortbi(col_map_offd_P, tmp_map_offd, 0, num_cols_P_offd - 1);
    for (i = 0; i < num_cols_P_offd; i++)
      tmp_CF_marker_offd[tmp_map_offd[i]] = i;
    for (i = 0; i < P_offd_size; i++)
      P_offd_j[i] = tmp_CF_marker_offd[P_offd_j[i]];
  }
  if (num_cols_P_offd) {
    (P)->col_map_offd = col_map_offd_P;
    (P_offd)->num_cols = num_cols_P_offd;
    hypre_Free((char*)tmp_map_offd), tmp_map_offd = (void*)0;
  }
  hypre_MatvecCommPkgCreate(P);
  for (i = 0; i < n_fine; i++)
    if ((CF_marker[i]) < (-1))
      CF_marker[i] = -1;
  *P_ptr = P;
  hypre_Free((char*)fine_to_coarse), fine_to_coarse = (void*)0;
  hypre_Free((char*)old_coarse_to_fine), old_coarse_to_fine = (void*)0;
  hypre_Free((char*)P_marker), P_marker = (void*)0;
  if (num_procs > 1) {
    hypre_BigCSRMatrixDestroy(Sop);
    hypre_BigCSRMatrixDestroy(A_ext);
    hypre_Free((char*)fine_to_coarse_offd), fine_to_coarse_offd = (void*)0;
    hypre_Free((char*)P_marker_offd), P_marker_offd = (void*)0;
    hypre_Free((char*)CF_marker_offd), CF_marker_offd = (void*)0;
    hypre_Free((char*)tmp_CF_marker_offd), tmp_CF_marker_offd = (void*)0;
    if (num_functions > 1)
      hypre_Free((char*)dof_func_offd), dof_func_offd = (void*)0;
    hypre_Free((char*)found), found = (void*)0;
    hypre_MatvecCommPkgDestroy(extend_comm_pkg);
  }
  return hypre__global_error;
}
int hypre_BoomerAMGBuildPartialExtInterp(hypre_ParCSRMatrix* A, int* CF_marker, hypre_ParCSRMatrix* S, int* num_cpts_global, int* num_old_cpts_global, int num_functions, int* dof_func, int debug_flag, double trunc_factor, int max_elmts, int* col_offd_S_to_A, hypre_ParCSRMatrix** P_ptr) {
  MPI_Comm comm = (A)->comm;
  hypre_ParCSRCommPkg* comm_pkg = (A)->comm_pkg;
  int my_id;
  int num_procs;
  hypre_CSRMatrix* A_diag = (A)->diag;
  double* A_diag_data = (A_diag)->data;
  int* A_diag_i = (A_diag)->i;
  int* A_diag_j = (A_diag)->j;
  hypre_CSRMatrix* A_offd = (A)->offd;
  double* A_offd_data = (A_offd)->data;
  int* A_offd_i = (A_offd)->i;
  int* A_offd_j = (A_offd)->j;
  int num_cols_A_offd = (A_offd)->num_cols;
  int* col_map_offd = (A)->col_map_offd;
  int n_fine = (A_diag)->num_rows;
  int col_1 = (A)->first_row_index;
  int local_numrows = (A_diag)->num_rows;
  int col_n = col_1 + (int)local_numrows;
  int total_global_cpts;
  int my_first_cpt;
  int total_old_global_cpts;
  int my_first_old_cpt;
  int n_coarse;
  int n_coarse_old;
  hypre_CSRMatrix* S_diag = (S)->diag;
  int* S_diag_i = (S_diag)->i;
  int* S_diag_j = (S_diag)->j;
  hypre_CSRMatrix* S_offd = (S)->offd;
  int* S_offd_i = (S_offd)->i;
  int* S_offd_j = (S_offd)->j;
  hypre_ParCSRMatrix* P;
  hypre_CSRMatrix* P_diag;
  hypre_CSRMatrix* P_offd;
  double* P_diag_data = (void*)0;
  int* P_diag_i;
  int* P_diag_j = (void*)0;
  double* P_offd_data = (void*)0;
  int* P_offd_i;
  int* P_offd_j = (void*)0;
  int* col_map_offd_P;
  int* tmp_map_offd;
  int P_diag_size;
  int P_offd_size;
  int* P_marker = (void*)0;
  int* P_marker_offd = (void*)0;
  int* CF_marker_offd = (void*)0;
  int* tmp_CF_marker_offd = (void*)0;
  int* dof_func_offd = (void*)0;
  hypre_BigCSRMatrix* A_ext;
  double* A_ext_data;
  int* A_ext_i;
  int* big_A_ext_j;
  int* A_ext_j;
  int* fine_to_coarse = (void*)0;
  int* old_coarse_to_fine = (void*)0;
  int* fine_to_coarse_offd = (void*)0;
  int* found;
  int num_cols_P_offd;
  int newoff;
  int loc_col;
  int A_ext_rows;
  int full_off_procNodes;
  hypre_BigCSRMatrix* Sop;
  int* Sop_i;
  int* big_Sop_j;
  int* Sop_j;
  int Soprows;
  int sgn;
  int jj_counter;
  int jj_counter_offd;
  int jj_begin_row;
  int jj_end_row;
  int jj_begin_row_offd = 0;
  int jj_end_row_offd = 0;
  int coarse_counter;
  int coarse_counter_offd;
  double sum;
  double diagonal;
  double distribute;
  int strong_f_marker = -2;
  int index;
  int ii;
  int cnt;
  int old_cnt;
  int start_indexing = 0;
  int i;
  int i1;
  int i2;
  int jj;
  int kk;
  int k1;
  int jj1;
  double zero = 0.0;
  double one = 1.0;
  double wall_time;
  hypre_ParCSRCommPkg* extend_comm_pkg = (void*)0;
  if (debug_flag == 4)
    wall_time = time_getWallclockSeconds();
  MPI_Comm_size(comm, &(num_procs));
  MPI_Comm_rank(comm, &(my_id));
  my_first_cpt = num_cpts_global[my_id];
  my_first_old_cpt = num_old_cpts_global[my_id];
  total_global_cpts = num_cpts_global[num_procs];
  total_old_global_cpts = num_old_cpts_global[num_procs];
  n_coarse_old = (int)((num_old_cpts_global[my_id + 1]) - (num_old_cpts_global[my_id]));
  n_coarse = (int)((num_cpts_global[my_id + 1]) - (num_cpts_global[my_id]));
  if (!comm_pkg) {
    hypre_MatvecCommPkgCreate(A);
    comm_pkg = (A)->comm_pkg;
  }
  newoff = 0;
  full_off_procNodes = 0;
  if (num_procs > 1) {
    A_ext = hypre_ParCSRMatrixExtractBigExt(A, A, 1);
    A_ext_i = (A_ext)->i;
    big_A_ext_j = (A_ext)->j;
    A_ext_data = (A_ext)->data;
    A_ext_rows = (A_ext)->num_rows;
    Sop = hypre_ParCSRMatrixExtractBigExt(S, A, 0);
    Sop_i = (Sop)->i;
    big_Sop_j = (Sop)->j;
    Soprows = (Sop)->num_rows;
    newoff = new_offd_nodes(&(found), A_ext_rows, A_ext_i, big_A_ext_j, &(A_ext_j), Soprows, col_map_offd, col_1, col_n, Sop_i, big_Sop_j, &(Sop_j), CF_marker, comm_pkg);
    (A_ext)->j = (void*)0;
    (Sop)->j = (void*)0;
    if (newoff >= 0)
      full_off_procNodes = newoff + num_cols_A_offd;
    else
      return 1;
    hypre_ParCSRFindExtendCommPkg(A, newoff, found, &(extend_comm_pkg));
    CF_marker_offd = (int*)(hypre_CAlloc((unsigned)full_off_procNodes, (unsigned)(sizeof(int))));
    if ((num_functions > 1) && (full_off_procNodes > 0))
      dof_func_offd = (int*)(hypre_CAlloc((unsigned)full_off_procNodes, (unsigned)(sizeof(int))));
    alt_insert_new_nodes(comm_pkg, extend_comm_pkg, CF_marker, full_off_procNodes, CF_marker_offd);
    if (num_functions > 1)
      alt_insert_new_nodes(comm_pkg, extend_comm_pkg, dof_func, full_off_procNodes, dof_func_offd);
  }
  P_diag_i = (int*)(hypre_CAlloc((unsigned)(n_fine + 1), (unsigned)(sizeof(int))));
  P_offd_i = (int*)(hypre_CAlloc((unsigned)(n_fine + 1), (unsigned)(sizeof(int))));
  if (n_coarse_old)
    old_coarse_to_fine = (int*)(hypre_CAlloc((unsigned)n_coarse_old, (unsigned)(sizeof(int))));
  if (n_fine) {
    fine_to_coarse = (int*)(hypre_CAlloc((unsigned)n_fine, (unsigned)(sizeof(int))));
    P_marker = (int*)(hypre_CAlloc((unsigned)n_fine, (unsigned)(sizeof(int))));
  }
  if (full_off_procNodes) {
    P_marker_offd = (int*)(hypre_CAlloc((unsigned)full_off_procNodes, (unsigned)(sizeof(int))));
    fine_to_coarse_offd = (int*)(hypre_CAlloc((unsigned)full_off_procNodes, (unsigned)(sizeof(int))));
    tmp_CF_marker_offd = (int*)(hypre_CAlloc((unsigned)full_off_procNodes, (unsigned)(sizeof(int))));
  }
  for (i = 0; i < full_off_procNodes; i++) {
    P_marker_offd[i] = -1;
    tmp_CF_marker_offd[i] = -1;
    fine_to_coarse_offd[i] = -1;
  }
  for (i = 0; i < n_fine; i++) {
    P_marker[i] = -1;
    fine_to_coarse[i] = -1;
  }
  jj_counter = start_indexing;
  jj_counter_offd = start_indexing;
  coarse_counter = 0;
  coarse_counter_offd = 0;
  cnt = 0;
  old_cnt = 0;
  for (i = 0; i < n_fine; i++) {
    fine_to_coarse[i] = -1;
    if ((CF_marker[i]) == 1) {
      fine_to_coarse[i] = cnt++;
      old_coarse_to_fine[old_cnt++] = i;
    }
    else
      if ((CF_marker[i]) == (-2)) {
        old_coarse_to_fine[old_cnt++] = i;
      }
  }
  for (ii = 0; ii < n_coarse_old; ii++) {
    P_diag_i[ii] = jj_counter;
    if (num_procs > 1)
      P_offd_i[ii] = jj_counter_offd;
    i = old_coarse_to_fine[ii];
    if ((CF_marker[i]) >= 0) {
      jj_counter++;
      coarse_counter++;
    }
    else
      if ((CF_marker[i]) == (-2)) {
        for (jj = S_diag_i[i]; jj < (S_diag_i[i + 1]); jj++) {
          i1 = S_diag_j[jj];
          if ((CF_marker[i1]) > 0) {
            if ((P_marker[i1]) < (P_diag_i[ii])) {
              P_marker[i1] = jj_counter;
              jj_counter++;
            }
          }
          else
            if ((CF_marker[i1]) != (-3)) {
              for (kk = S_diag_i[i1]; kk < (S_diag_i[i1 + 1]); kk++) {
                k1 = S_diag_j[kk];
                if ((CF_marker[k1]) > 0) {
                  if ((P_marker[k1]) < (P_diag_i[ii])) {
                    P_marker[k1] = jj_counter;
                    jj_counter++;
                  }
                }
              }
              if (num_procs > 1) {
                for (kk = S_offd_i[i1]; kk < (S_offd_i[i1 + 1]); kk++) {
                  if (col_offd_S_to_A)
                    k1 = col_offd_S_to_A[S_offd_j[kk]];
                  else
                    k1 = S_offd_j[kk];
                  if ((CF_marker_offd[k1]) > 0) {
                    if ((P_marker_offd[k1]) < (P_offd_i[ii])) {
                      tmp_CF_marker_offd[k1] = 1;
                      P_marker_offd[k1] = jj_counter_offd;
                      jj_counter_offd++;
                    }
                  }
                }
              }
            }
        }
        if (num_procs > 1) {
          for (jj = S_offd_i[i]; jj < (S_offd_i[i + 1]); jj++) {
            i1 = S_offd_j[jj];
            if (col_offd_S_to_A)
              i1 = col_offd_S_to_A[i1];
            if ((CF_marker_offd[i1]) > 0) {
              if ((P_marker_offd[i1]) < (P_offd_i[ii])) {
                tmp_CF_marker_offd[i1] = 1;
                P_marker_offd[i1] = jj_counter_offd;
                jj_counter_offd++;
              }
            }
            else
              if ((CF_marker_offd[i1]) != (-3)) {
                for (kk = Sop_i[i1]; kk < (Sop_i[i1 + 1]); kk++) {
                  loc_col = Sop_j[kk];
                  if (loc_col > (-1)) {
                    if ((CF_marker[loc_col]) > 0) {
                      if ((P_marker[loc_col]) < (P_diag_i[ii])) {
                        P_marker[loc_col] = jj_counter;
                        jj_counter++;
                      }
                    }
                  }
                  else {
                    loc_col = (-loc_col) - 1;
                    if ((CF_marker_offd[loc_col]) > 0) {
                      if ((P_marker_offd[loc_col]) < (P_offd_i[ii])) {
                        P_marker_offd[loc_col] = jj_counter_offd;
                        tmp_CF_marker_offd[loc_col] = 1;
                        jj_counter_offd++;
                      }
                    }
                  }
                }
              }
          }
        }
      }
  }
  if (debug_flag == 4) {
    wall_time = time_getWallclockSeconds() - wall_time;
    printf("Proc = %d     determine structure    %f\n", my_id, wall_time);
    fflush((void*)0);
  }
  if (debug_flag == 4)
    wall_time = time_getWallclockSeconds();
  P_diag_size = jj_counter;
  P_offd_size = jj_counter_offd;
  if (P_diag_size) {
    P_diag_j = (int*)(hypre_CAlloc((unsigned)P_diag_size, (unsigned)(sizeof(int))));
    P_diag_data = (double*)(hypre_CAlloc((unsigned)P_diag_size, (unsigned)(sizeof(double))));
  }
  if (P_offd_size) {
    P_offd_j = (int*)(hypre_CAlloc((unsigned)P_offd_size, (unsigned)(sizeof(int))));
    P_offd_data = (double*)(hypre_CAlloc((unsigned)P_offd_size, (unsigned)(sizeof(double))));
  }
  P_diag_i[n_coarse_old] = jj_counter;
  P_offd_i[n_coarse_old] = jj_counter_offd;
  jj_counter = start_indexing;
  jj_counter_offd = start_indexing;
  if (num_procs > 1) {
    big_insert_new_nodes(comm_pkg, extend_comm_pkg, fine_to_coarse, full_off_procNodes, my_first_cpt, fine_to_coarse_offd);
  }
  for (i = 0; i < n_fine; i++)
    P_marker[i] = -1;
  for (i = 0; i < full_off_procNodes; i++)
    P_marker_offd[i] = -1;
  for (ii = 0; ii < n_coarse_old; ii++) {
    jj_begin_row = jj_counter;
    jj_begin_row_offd = jj_counter_offd;
    i = old_coarse_to_fine[ii];
    if ((CF_marker[i]) > 0) {
      P_diag_j[jj_counter] = fine_to_coarse[i];
      P_diag_data[jj_counter] = one;
      jj_counter++;
    }
    else
      if ((CF_marker[i]) == (-2)) {
        strong_f_marker--;
        for (jj = S_diag_i[i]; jj < (S_diag_i[i + 1]); jj++) {
          i1 = S_diag_j[jj];
          if ((CF_marker[i1]) > 0) {
            if ((P_marker[i1]) < jj_begin_row) {
              P_marker[i1] = jj_counter;
              P_diag_j[jj_counter] = fine_to_coarse[i1];
              P_diag_data[jj_counter] = zero;
              jj_counter++;
            }
          }
          else
            if ((CF_marker[i1]) != (-3)) {
              P_marker[i1] = strong_f_marker;
              for (kk = S_diag_i[i1]; kk < (S_diag_i[i1 + 1]); kk++) {
                k1 = S_diag_j[kk];
                if ((CF_marker[k1]) > 0) {
                  if ((P_marker[k1]) < jj_begin_row) {
                    P_marker[k1] = jj_counter;
                    P_diag_j[jj_counter] = fine_to_coarse[k1];
                    P_diag_data[jj_counter] = zero;
                    jj_counter++;
                  }
                }
              }
              if (num_procs > 1) {
                for (kk = S_offd_i[i1]; kk < (S_offd_i[i1 + 1]); kk++) {
                  if (col_offd_S_to_A)
                    k1 = col_offd_S_to_A[S_offd_j[kk]];
                  else
                    k1 = S_offd_j[kk];
                  if ((CF_marker_offd[k1]) > 0) {
                    if ((P_marker_offd[k1]) < jj_begin_row_offd) {
                      P_marker_offd[k1] = jj_counter_offd;
                      P_offd_j[jj_counter_offd] = k1;
                      P_offd_data[jj_counter_offd] = zero;
                      jj_counter_offd++;
                    }
                  }
                }
              }
            }
        }
        if (num_procs > 1) {
          for (jj = S_offd_i[i]; jj < (S_offd_i[i + 1]); jj++) {
            i1 = S_offd_j[jj];
            if (col_offd_S_to_A)
              i1 = col_offd_S_to_A[i1];
            if ((CF_marker_offd[i1]) > 0) {
              if ((P_marker_offd[i1]) < jj_begin_row_offd) {
                P_marker_offd[i1] = jj_counter_offd;
                P_offd_j[jj_counter_offd] = i1;
                P_offd_data[jj_counter_offd] = zero;
                jj_counter_offd++;
              }
            }
            else
              if ((CF_marker_offd[i1]) != (-3)) {
                P_marker_offd[i1] = strong_f_marker;
                for (kk = Sop_i[i1]; kk < (Sop_i[i1 + 1]); kk++) {
                  loc_col = Sop_j[kk];
                  if (loc_col > (-1)) {
                    if ((CF_marker[loc_col]) > 0) {
                      if ((P_marker[loc_col]) < jj_begin_row) {
                        P_marker[loc_col] = jj_counter;
                        P_diag_j[jj_counter] = fine_to_coarse[loc_col];
                        P_diag_data[jj_counter] = zero;
                        jj_counter++;
                      }
                    }
                  }
                  else {
                    loc_col = (-loc_col) - 1;
                    if ((CF_marker_offd[loc_col]) > 0) {
                      if ((P_marker_offd[loc_col]) < jj_begin_row_offd) {
                        P_marker_offd[loc_col] = jj_counter_offd;
                        P_offd_j[jj_counter_offd] = loc_col;
                        P_offd_data[jj_counter_offd] = zero;
                        jj_counter_offd++;
                      }
                    }
                  }
                }
              }
          }
        }
        jj_end_row = jj_counter;
        jj_end_row_offd = jj_counter_offd;
        diagonal = A_diag_data[A_diag_i[i]];
        for (jj = (A_diag_i[i]) + 1; jj < (A_diag_i[i + 1]); jj++) {
          i1 = A_diag_j[jj];
          if ((P_marker[i1]) >= jj_begin_row) {
            P_diag_data[P_marker[i1]] += A_diag_data[jj];
          }
          else
            if ((P_marker[i1]) == strong_f_marker) {
              sum = zero;
              sgn = 1;
              if ((A_diag_data[A_diag_i[i1]]) < 0)
                sgn = -1;
              for (jj1 = (A_diag_i[i1]) + 1; jj1 < (A_diag_i[i1 + 1]); jj1++) {
                i2 = A_diag_j[jj1];
                if (((P_marker[i2]) >= jj_begin_row) && ((sgn * (A_diag_data[jj1])) < 0))
                  sum += A_diag_data[jj1];
              }
              if (num_procs > 1) {
                for (jj1 = A_offd_i[i1]; jj1 < (A_offd_i[i1 + 1]); jj1++) {
                  i2 = A_offd_j[jj1];
                  if (((P_marker_offd[i2]) >= jj_begin_row_offd) && ((sgn * (A_offd_data[jj1])) < 0))
                    sum += A_offd_data[jj1];
                }
              }
              if (sum != 0) {
                distribute = (A_diag_data[jj]) / sum;
                for (jj1 = (A_diag_i[i1]) + 1; jj1 < (A_diag_i[i1 + 1]); jj1++) {
                  i2 = A_diag_j[jj1];
                  if (((P_marker[i2]) >= jj_begin_row) && ((sgn * (A_diag_data[jj1])) < 0))
                    P_diag_data[P_marker[i2]] += distribute * (A_diag_data[jj1]);
                }
                if (num_procs > 1) {
                  for (jj1 = A_offd_i[i1]; jj1 < (A_offd_i[i1 + 1]); jj1++) {
                    i2 = A_offd_j[jj1];
                    if (((P_marker_offd[i2]) >= jj_begin_row_offd) && ((sgn * (A_offd_data[jj1])) < 0))
                      P_offd_data[P_marker_offd[i2]] += distribute * (A_offd_data[jj1]);
                  }
                }
              }
              else {
                diagonal += A_diag_data[jj];
              }
            }
            else
              if ((CF_marker[i1]) != (-3)) {
                if ((num_functions == 1) || ((dof_func[i]) == (dof_func[i1])))
                  diagonal += A_diag_data[jj];
              }
        }
        if (num_procs > 1) {
          for (jj = A_offd_i[i]; jj < (A_offd_i[i + 1]); jj++) {
            i1 = A_offd_j[jj];
            if ((P_marker_offd[i1]) >= jj_begin_row_offd)
              P_offd_data[P_marker_offd[i1]] += A_offd_data[jj];
            else
              if ((P_marker_offd[i1]) == strong_f_marker) {
                sum = zero;
                sgn = 1;
                if ((A_ext_data[A_ext_i[i1]]) < 0)
                  sgn = -1;
                for (jj1 = (A_ext_i[i1]) + 1; jj1 < (A_ext_i[i1 + 1]); jj1++) {
                  loc_col = A_ext_j[jj1];
                  if (loc_col > (-1)) {
                    if (((P_marker[loc_col]) >= jj_begin_row) && ((sgn * (A_ext_data[jj1])) < 0))
                      sum += A_ext_data[jj1];
                  }
                  else {
                    loc_col = (-loc_col) - 1;
                    if (((P_marker_offd[loc_col]) >= jj_begin_row_offd) && ((sgn * (A_ext_data[jj1])) < 0))
                      sum += A_ext_data[jj1];
                  }
                }
                if (sum != 0) {
                  distribute = (A_offd_data[jj]) / sum;
                  for (jj1 = (A_ext_i[i1]) + 1; jj1 < (A_ext_i[i1 + 1]); jj1++) {
                    loc_col = A_ext_j[jj1];
                    if (loc_col > (-1)) {
                      if (((P_marker[loc_col]) >= jj_begin_row) && ((sgn * (A_ext_data[jj1])) < 0))
                        P_diag_data[P_marker[loc_col]] += distribute * (A_ext_data[jj1]);
                    }
                    else {
                      loc_col = (-loc_col) - 1;
                      if (((P_marker_offd[loc_col]) >= jj_begin_row_offd) && ((sgn * (A_ext_data[jj1])) < 0))
                        P_offd_data[P_marker_offd[loc_col]] += distribute * (A_ext_data[jj1]);
                    }
                  }
                }
                else {
                  diagonal += A_offd_data[jj];
                }
              }
              else
                if ((CF_marker_offd[i1]) != (-3)) {
                  if ((num_functions == 1) || ((dof_func[i]) == (dof_func_offd[i1])))
                    diagonal += A_offd_data[jj];
                }
          }
        }
        for (jj = jj_begin_row; jj < jj_end_row; jj++)
          (P_diag_data[jj]) /= (-diagonal);
        for (jj = jj_begin_row_offd; jj < jj_end_row_offd; jj++)
          (P_offd_data[jj]) /= (-diagonal);
      }
    strong_f_marker--;
  }
  if (debug_flag == 4) {
    wall_time = time_getWallclockSeconds() - wall_time;
    printf("Proc = %d     fill structure    %f\n", my_id, wall_time);
    fflush((void*)0);
  }
  P = hypre_ParCSRMatrixCreate(comm, total_old_global_cpts, total_global_cpts, num_old_cpts_global, num_cpts_global, 0, P_diag_i[n_coarse_old], P_offd_i[n_coarse_old]);
  P_diag = (P)->diag;
  (P_diag)->data = P_diag_data;
  (P_diag)->i = P_diag_i;
  (P_diag)->j = P_diag_j;
  P_offd = (P)->offd;
  (P_offd)->data = P_offd_data;
  (P_offd)->i = P_offd_i;
  (P_offd)->j = P_offd_j;
  (P)->owns_row_starts = 0;
  if ((trunc_factor != 0.0) || (max_elmts > 0)) {
    hypre_BoomerAMGInterpTruncation(P, trunc_factor, max_elmts);
    P_diag_data = (P_diag)->data;
    P_diag_i = (P_diag)->i;
    P_diag_j = (P_diag)->j;
    P_offd_data = (P_offd)->data;
    P_offd_i = (P_offd)->i;
    P_offd_j = (P_offd)->j;
    P_diag_size = P_diag_i[n_coarse_old];
    P_offd_size = P_offd_i[n_coarse_old];
  }
  num_cols_P_offd = 0;
  if (P_offd_size) {
    num_cols_P_offd = 0;
    for (i = 0; i < P_offd_size; i++) {
      index = P_offd_j[i];
      if ((tmp_CF_marker_offd[index]) == 1) {
        num_cols_P_offd++;
        tmp_CF_marker_offd[index] = 2;
      }
    }
    if (num_cols_P_offd) {
      col_map_offd_P = (int*)(hypre_CAlloc((unsigned)num_cols_P_offd, (unsigned)(sizeof(int))));
      tmp_map_offd = (int*)(hypre_CAlloc((unsigned)num_cols_P_offd, (unsigned)(sizeof(int))));
    }
    index = 0;
    for (i = 0; i < num_cols_P_offd; i++) {
      while ((tmp_CF_marker_offd[index]) != 2)
        index++;
      col_map_offd_P[i] = fine_to_coarse_offd[index];
      tmp_map_offd[i] = index++;
    }
    hypre_BigQsortbi(col_map_offd_P, tmp_map_offd, 0, num_cols_P_offd - 1);
    for (i = 0; i < num_cols_P_offd; i++)
      tmp_CF_marker_offd[tmp_map_offd[i]] = i;
    for (i = 0; i < P_offd_size; i++)
      P_offd_j[i] = tmp_CF_marker_offd[P_offd_j[i]];
  }
  if (num_cols_P_offd) {
    (P)->col_map_offd = col_map_offd_P;
    (P_offd)->num_cols = num_cols_P_offd;
    hypre_Free((char*)tmp_map_offd), tmp_map_offd = (void*)0;
  }
  hypre_MatvecCommPkgCreate(P);
  for (i = 0; i < n_fine; i++)
    if ((CF_marker[i]) < (-1))
      CF_marker[i] = -1;
  *P_ptr = P;
  hypre_Free((char*)fine_to_coarse), fine_to_coarse = (void*)0;
  hypre_Free((char*)old_coarse_to_fine), old_coarse_to_fine = (void*)0;
  hypre_Free((char*)P_marker), P_marker = (void*)0;
  if (num_procs > 1) {
    hypre_BigCSRMatrixDestroy(Sop);
    hypre_BigCSRMatrixDestroy(A_ext);
    hypre_Free((char*)fine_to_coarse_offd), fine_to_coarse_offd = (void*)0;
    hypre_Free((char*)P_marker_offd), P_marker_offd = (void*)0;
    hypre_Free((char*)CF_marker_offd), CF_marker_offd = (void*)0;
    hypre_Free((char*)tmp_CF_marker_offd), tmp_CF_marker_offd = (void*)0;
    if (num_functions > 1)
      hypre_Free((char*)dof_func_offd), dof_func_offd = (void*)0;
    hypre_Free((char*)found), found = (void*)0;
    hypre_MatvecCommPkgDestroy(extend_comm_pkg);
  }
  return hypre__global_error;
}
//======================== pcg_par.c =======================
int hypre_ParKrylovFree(char* ptr) {
  int ierr = 0;
  hypre_Free(ptr);
  return ierr;
}
void* hypre_ParKrylovCreateVector(void* vvector) {
  hypre_ParVector* vector = vvector;
  hypre_ParVector* new_vector;
  new_vector = hypre_ParVectorCreate((vector)->comm, (vector)->global_size, (vector)->partitioning);
  hypre_ParVectorSetPartitioningOwner(new_vector, 0);
  hypre_ParVectorInitialize(new_vector);
  return (void*)new_vector;
}
void* hypre_ParKrylovCreateVectorArray(int n, void* vvector) {
  hypre_ParVector* vector = vvector;
  hypre_ParVector** new_vector;
  int i;
  new_vector = (hypre_ParVector**)(hypre_CAlloc((unsigned)n, (unsigned)(sizeof(hypre_ParVector*))));
  for (i = 0; i < n; i++) {
    new_vector[i] = hypre_ParVectorCreate((vector)->comm, (vector)->global_size, (vector)->partitioning);
    hypre_ParVectorSetPartitioningOwner(new_vector[i], 0);
    hypre_ParVectorInitialize(new_vector[i]);
  }
  return (void*)new_vector;
}
int hypre_ParKrylovDestroyVector(void* vvector) {
  hypre_ParVector* vector = vvector;
  return hypre_ParVectorDestroy(vector);
}
void* hypre_ParKrylovMatvecCreate(void* A, void* x) {
  void* matvec_data;
  matvec_data = (void*)0;
  return matvec_data;
}
int hypre_ParKrylovMatvec(void* matvec_data, double alpha, void* A, void* x, double beta, void* y) {
  return hypre_ParCSRMatrixMatvec(alpha, (hypre_ParCSRMatrix*)A, (hypre_ParVector*)x, beta, (hypre_ParVector*)y);
}
int hypre_ParKrylovMatvecDestroy(void* matvec_data) {
  return 0;
}
double hypre_ParKrylovInnerProd(void* x, void* y) {
  return hypre_ParVectorInnerProd((hypre_ParVector*)x, (hypre_ParVector*)y);
}
int hypre_ParKrylovCopyVector(void* x, void* y) {
  return hypre_ParVectorCopy((hypre_ParVector*)x, (hypre_ParVector*)y);
}
int hypre_ParKrylovClearVector(void* x) {
  return hypre_ParVectorSetConstantValues((hypre_ParVector*)x, 0.0);
}
int hypre_ParKrylovScaleVector(double alpha, void* x) {
  return hypre_ParVectorScale(alpha, (hypre_ParVector*)x);
}
int hypre_ParKrylovAxpy(double alpha, void* x, void* y) {
  return hypre_ParVectorAxpy(alpha, (hypre_ParVector*)x, (hypre_ParVector*)y);
}
int hypre_ParKrylovCommInfo(void* A, int* my_id, int* num_procs) {
  MPI_Comm comm = ((hypre_ParCSRMatrix*)A)->comm;
  MPI_Comm_size(comm, num_procs);
  MPI_Comm_rank(comm, my_id);
  return 0;
}
int hypre_ParKrylovIdentitySetup(void* vdata, void* A, void* b, void* x) {
  return 0;
}
int hypre_ParKrylovIdentity(void* vdata, void* A, void* b, void* x) {
  return hypre_ParKrylovCopyVector(b, x);
}
//================== HYPRE_parcsr_matrix.c =================
int HYPRE_ParCSRMatrixDestroy(HYPRE_ParCSRMatrix matrix) {
  return hypre_ParCSRMatrixDestroy((hypre_ParCSRMatrix*)matrix);
}
int HYPRE_ParCSRMatrixPrintIJ(HYPRE_ParCSRMatrix matrix, int base_i, int base_j, char* file_name) {
  hypre_ParCSRMatrixPrintIJ((hypre_ParCSRMatrix*)matrix, base_i, base_j, file_name);
  return hypre__global_error;
}
int HYPRE_ParCSRMatrixGetRow(HYPRE_ParCSRMatrix matrix, int row, int* size, int** col_ind, double** values) {
  if (!matrix) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_mv/HYPRE_parcsr_matrix.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  hypre_ParCSRMatrixGetRow((hypre_ParCSRMatrix*)matrix, row, size, col_ind, values);
  return hypre__global_error;
}
int HYPRE_ParCSRMatrixRestoreRow(HYPRE_ParCSRMatrix matrix, int row, int* size, int** col_ind, double** values) {
  if (!matrix) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_mv/HYPRE_parcsr_matrix.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  hypre_ParCSRMatrixRestoreRow((hypre_ParCSRMatrix*)matrix, row, size, col_ind, values);
  return hypre__global_error;
}
int HYPRE_ParCSRMatrixMatvec(double alpha, HYPRE_ParCSRMatrix A, HYPRE_ParVector x, double beta, HYPRE_ParVector y) {
  return hypre_ParCSRMatrixMatvec(alpha, (hypre_ParCSRMatrix*)A, (hypre_ParVector*)x, beta, (hypre_ParVector*)y);
}
//================== HYPRE_parcsr_vector.c =================
int HYPRE_ParVectorDestroy(HYPRE_ParVector vector) {
  return hypre_ParVectorDestroy((hypre_ParVector*)vector);
}
int HYPRE_ParVectorPrintIJ(HYPRE_ParVector vector, int base_i, char* file_name) {
  return hypre_ParVectorPrintIJ((hypre_ParVector*)vector, base_i, file_name);
}
//================= par_csr_assumed_part.c =================
int hypre_ParCSRMatrixDestroyAssumedPartition(hypre_ParCSRMatrix* matrix) {
  hypre_IJAssumedPart* apart;
  apart = (matrix)->assumed_partition;
  if ((apart)->storage_length > 0) {
    hypre_Free((char*)((apart)->proc_list)), (apart)->proc_list = (void*)0;
    hypre_Free((char*)((apart)->row_start_list)), (apart)->row_start_list = (void*)0;
    hypre_Free((char*)((apart)->row_end_list)), (apart)->row_end_list = (void*)0;
    hypre_Free((char*)((apart)->sort_index)), (apart)->sort_index = (void*)0;
  }
  hypre_Free((char*)apart), apart = (void*)0;
  return hypre__global_error;
}
int hypre_ParVectorDestroyAssumedPartition(hypre_ParVector* vector) {
  hypre_IJAssumedPart* apart;
  apart = (vector)->assumed_partition;
  if ((apart)->storage_length > 0) {
    hypre_Free((char*)((apart)->proc_list)), (apart)->proc_list = (void*)0;
    hypre_Free((char*)((apart)->row_start_list)), (apart)->row_start_list = (void*)0;
    hypre_Free((char*)((apart)->row_end_list)), (apart)->row_end_list = (void*)0;
    hypre_Free((char*)((apart)->sort_index)), (apart)->sort_index = (void*)0;
  }
  hypre_Free((char*)apart), apart = (void*)0;
  return hypre__global_error;
}
//================= par_csr_communication.c ================
hypre_ParCSRCommHandle* hypre_ParCSRCommHandleCreate(int job, hypre_ParCSRCommPkg* comm_pkg, void* send_data, void* recv_data) {
  int num_sends = (comm_pkg)->num_sends;
  int num_recvs = (comm_pkg)->num_recvs;
  MPI_Comm comm = (comm_pkg)->comm;
  hypre_ParCSRCommHandle* comm_handle;
  int num_requests;
  MPI_Request* requests;
  int i;
  int j;
  int my_id;
  int num_procs;
  int ip;
  int vec_start;
  int vec_len;
  num_requests = num_sends + num_recvs;
  requests = (MPI_Request*)(hypre_CAlloc((unsigned)num_requests, (unsigned)(sizeof(MPI_Request))));
  MPI_Comm_size(comm, &(num_procs));
  MPI_Comm_rank(comm, &(my_id));
  j = 0;
  switch (job) {
    case 1:
{
      double* d_send_data = (double*)send_data;
      double* d_recv_data = (double*)recv_data;
      for (i = 0; i < num_recvs; i++) {
        ip = (comm_pkg)->recv_procs[i];
        vec_start = (comm_pkg)->recv_vec_starts[i];
        vec_len = ((comm_pkg)->recv_vec_starts[i + 1]) - vec_start;
        MPI_Irecv(&(d_recv_data[vec_start]), vec_len, MPI_DOUBLE, ip, 0, comm, &(requests[j++]));
      }
      for (i = 0; i < num_sends; i++) {
        vec_start = (comm_pkg)->send_map_starts[i];
        vec_len = ((comm_pkg)->send_map_starts[i + 1]) - vec_start;
        ip = (comm_pkg)->send_procs[i];
        MPI_Isend(&(d_send_data[vec_start]), vec_len, MPI_DOUBLE, ip, 0, comm, &(requests[j++]));
      }
      break;
    }
    case 2:
{
      double* d_send_data = (double*)send_data;
      double* d_recv_data = (double*)recv_data;
      for (i = 0; i < num_sends; i++) {
        vec_start = (comm_pkg)->send_map_starts[i];
        vec_len = ((comm_pkg)->send_map_starts[i + 1]) - vec_start;
        ip = (comm_pkg)->send_procs[i];
        MPI_Irecv(&(d_recv_data[vec_start]), vec_len, MPI_DOUBLE, ip, 0, comm, &(requests[j++]));
      }
      for (i = 0; i < num_recvs; i++) {
        ip = (comm_pkg)->recv_procs[i];
        vec_start = (comm_pkg)->recv_vec_starts[i];
        vec_len = ((comm_pkg)->recv_vec_starts[i + 1]) - vec_start;
        MPI_Isend(&(d_send_data[vec_start]), vec_len, MPI_DOUBLE, ip, 0, comm, &(requests[j++]));
      }
      break;
    }
    case 11:
{
      int* i_send_data = (int*)send_data;
      int* i_recv_data = (int*)recv_data;
      for (i = 0; i < num_recvs; i++) {
        ip = (comm_pkg)->recv_procs[i];
        vec_start = (comm_pkg)->recv_vec_starts[i];
        vec_len = ((comm_pkg)->recv_vec_starts[i + 1]) - vec_start;
        MPI_Irecv(&(i_recv_data[vec_start]), vec_len, MPI_INT, ip, 0, comm, &(requests[j++]));
      }
      for (i = 0; i < num_sends; i++) {
        vec_start = (comm_pkg)->send_map_starts[i];
        vec_len = ((comm_pkg)->send_map_starts[i + 1]) - vec_start;
        ip = (comm_pkg)->send_procs[i];
        MPI_Isend(&(i_send_data[vec_start]), vec_len, MPI_INT, ip, 0, comm, &(requests[j++]));
      }
      break;
    }
    case 12:
{
      int* i_send_data = (int*)send_data;
      int* i_recv_data = (int*)recv_data;
      for (i = 0; i < num_sends; i++) {
        vec_start = (comm_pkg)->send_map_starts[i];
        vec_len = ((comm_pkg)->send_map_starts[i + 1]) - vec_start;
        ip = (comm_pkg)->send_procs[i];
        MPI_Irecv(&(i_recv_data[vec_start]), vec_len, MPI_INT, ip, 0, comm, &(requests[j++]));
      }
      for (i = 0; i < num_recvs; i++) {
        ip = (comm_pkg)->recv_procs[i];
        vec_start = (comm_pkg)->recv_vec_starts[i];
        vec_len = ((comm_pkg)->recv_vec_starts[i + 1]) - vec_start;
        MPI_Isend(&(i_send_data[vec_start]), vec_len, MPI_INT, ip, 0, comm, &(requests[j++]));
      }
      break;
    }
    case 21:
{
      int* i_send_data = (int*)send_data;
      int* i_recv_data = (int*)recv_data;
      for (i = 0; i < num_recvs; i++) {
        ip = (comm_pkg)->recv_procs[i];
        vec_start = (comm_pkg)->recv_vec_starts[i];
        vec_len = ((comm_pkg)->recv_vec_starts[i + 1]) - vec_start;
        MPI_Irecv(&(i_recv_data[vec_start]), vec_len, MPI_INT, ip, 0, comm, &(requests[j++]));
      }
      for (i = 0; i < num_sends; i++) {
        vec_start = (comm_pkg)->send_map_starts[i];
        vec_len = ((comm_pkg)->send_map_starts[i + 1]) - vec_start;
        ip = (comm_pkg)->send_procs[i];
        MPI_Isend(&(i_send_data[vec_start]), vec_len, MPI_INT, ip, 0, comm, &(requests[j++]));
      }
      break;
    }
    case 22:
{
      int* i_send_data = (int*)send_data;
      int* i_recv_data = (int*)recv_data;
      for (i = 0; i < num_sends; i++) {
        vec_start = (comm_pkg)->send_map_starts[i];
        vec_len = ((comm_pkg)->send_map_starts[i + 1]) - vec_start;
        ip = (comm_pkg)->send_procs[i];
        MPI_Irecv(&(i_recv_data[vec_start]), vec_len, MPI_INT, ip, 0, comm, &(requests[j++]));
      }
      for (i = 0; i < num_recvs; i++) {
        ip = (comm_pkg)->recv_procs[i];
        vec_start = (comm_pkg)->recv_vec_starts[i];
        vec_len = ((comm_pkg)->recv_vec_starts[i + 1]) - vec_start;
        MPI_Isend(&(i_send_data[vec_start]), vec_len, MPI_INT, ip, 0, comm, &(requests[j++]));
      }
      break;
    }
  }
  comm_handle = (hypre_ParCSRCommHandle*)(hypre_CAlloc((unsigned)1, (unsigned)(sizeof(hypre_ParCSRCommHandle))));
  (comm_handle)->comm_pkg = comm_pkg;
  (comm_handle)->send_data = send_data;
  (comm_handle)->recv_data = recv_data;
  (comm_handle)->num_requests = num_requests;
  (comm_handle)->requests = requests;
  return comm_handle;
}
int hypre_ParCSRCommHandleDestroy(hypre_ParCSRCommHandle* comm_handle) {
  MPI_Status* status0;
  int ierr = 0;
  if (comm_handle == (void*)0)
    return ierr;
  if ((comm_handle)->num_requests) {
    status0 = (MPI_Status*)(hypre_CAlloc((unsigned)((comm_handle)->num_requests), (unsigned)(sizeof(MPI_Status))));
    MPI_Waitall((comm_handle)->num_requests, (comm_handle)->requests, status0);
    hypre_Free((char*)status0), status0 = (void*)0;
  }
  hypre_Free((char*)((comm_handle)->requests)), (comm_handle)->requests = (void*)0;
  hypre_Free((char*)comm_handle), comm_handle = (void*)0;
  return ierr;
}
void hypre_MatvecCommPkgCreate_core(MPI_Comm comm, int* col_map_offd, int first_col_diag, int* col_starts, int num_cols_diag, int num_cols_offd, int firstColDiag, int* colMapOffd, int data, int* p_num_recvs, int** p_recv_procs, int** p_recv_vec_starts, int* p_num_sends, int** p_send_procs, int** p_send_map_starts, int** p_send_map_elmts) {
  int i;
  int j;
  int num_procs;
  int my_id;
  int proc_num;
  int num_elmts;
  int local_info;
  int offd_col;
  int* big_buf_data = (void*)0;
  int* proc_mark;
  int* proc_add;
  int* tmp;
  int* recv_buf;
  int* displs;
  int* info;
  int num_recvs;
  int* recv_procs;
  int* recv_vec_starts;
  int num_sends;
  int* send_procs;
  int* send_map_starts;
  int* send_map_elmts;
  int ip;
  int vec_start;
  int vec_len;
  int num_requests;
  MPI_Request* requests;
  MPI_Status* status;
  MPI_Comm_size(comm, &(num_procs));
  MPI_Comm_rank(comm, &(my_id));
  proc_mark = (int*)(hypre_CAlloc((unsigned)num_procs, (unsigned)(sizeof(int))));
  proc_add = (int*)(hypre_CAlloc((unsigned)num_procs, (unsigned)(sizeof(int))));
  info = (int*)(hypre_CAlloc((unsigned)num_procs, (unsigned)(sizeof(int))));
  for (i = 0; i < num_procs; i++)
    proc_add[i] = 0;
  proc_num = 0;
  if (num_cols_offd)
    offd_col = col_map_offd[0];
  num_recvs = 0;
  j = 0;
  for (i = 0; i < num_cols_offd; i++) {
    if (num_cols_diag)
      proc_num = (num_procs - 1) < (offd_col / num_cols_diag) ? num_procs - 1 : offd_col / num_cols_diag;
    while ((col_starts[proc_num]) > offd_col)
      proc_num = proc_num - 1;
    while (((col_starts[proc_num + 1]) - 1) < offd_col)
      proc_num = proc_num + 1;
    proc_mark[num_recvs] = proc_num;
    j = i;
    while ((col_starts[proc_num + 1]) > offd_col) {
      proc_add[num_recvs]++;
      if (j < (num_cols_offd - 1)) {
        j++;
        offd_col = col_map_offd[j];
      }
      else {
        j++;
        offd_col = col_starts[num_procs];
      }
    }
    num_recvs++;
    if (j < num_cols_offd)
      i = j - 1;
    else
      i = j;
  }
  local_info = 2 * num_recvs;
  MPI_Allgather(&(local_info), 1, MPI_INT, info, 1, MPI_INT, comm);
  displs = (int*)(hypre_CAlloc((unsigned)(num_procs + 1), (unsigned)(sizeof(int))));
  displs[0] = 0;
  for (i = 1; i < (num_procs + 1); i++)
    displs[i] = (displs[i - 1]) + (info[i - 1]);
  recv_buf = (int*)(hypre_CAlloc((unsigned)(displs[num_procs]), (unsigned)(sizeof(int))));
  recv_procs = (void*)0;
  tmp = (void*)0;
  if (num_recvs) {
    recv_procs = (int*)(hypre_CAlloc((unsigned)num_recvs, (unsigned)(sizeof(int))));
    tmp = (int*)(hypre_CAlloc((unsigned)local_info, (unsigned)(sizeof(int))));
  }
  recv_vec_starts = (int*)(hypre_CAlloc((unsigned)(num_recvs + 1), (unsigned)(sizeof(int))));
  j = 0;
  if (num_recvs)
    recv_vec_starts[0] = 0;
  for (i = 0; i < num_recvs; i++) {
    num_elmts = proc_add[i];
    recv_procs[i] = proc_mark[i];
    recv_vec_starts[i + 1] = (recv_vec_starts[i]) + num_elmts;
    tmp[j++] = proc_mark[i];
    tmp[j++] = num_elmts;
  }
  MPI_Allgatherv(tmp, local_info, MPI_INT, recv_buf, info, displs, MPI_INT, comm);
  num_sends = 0;
  num_elmts = 0;
  proc_add[0] = 0;
  for (i = 0; i < num_procs; i++) {
    j = displs[i];
    while (j < (displs[i + 1])) {
      if ((recv_buf[j++]) == my_id) {
        proc_mark[num_sends] = i;
        num_sends++;
        proc_add[num_sends] = (proc_add[num_sends - 1]) + (recv_buf[j]);
        break;
      }
      j++;
    }
  }
  send_procs = (void*)0;
  send_map_elmts = (void*)0;
  if (num_sends) {
    send_procs = (int*)(hypre_CAlloc((unsigned)num_sends, (unsigned)(sizeof(int))));
    send_map_elmts = (int*)(hypre_CAlloc((unsigned)(proc_add[num_sends]), (unsigned)(sizeof(int))));
    big_buf_data = (int*)(hypre_CAlloc((unsigned)(proc_add[num_sends]), (unsigned)(sizeof(int))));
  }
  send_map_starts = (int*)(hypre_CAlloc((unsigned)(num_sends + 1), (unsigned)(sizeof(int))));
  num_requests = num_recvs + num_sends;
  if (num_requests) {
    requests = (MPI_Request*)(hypre_CAlloc((unsigned)num_requests, (unsigned)(sizeof(MPI_Request))));
    status = (MPI_Status*)(hypre_CAlloc((unsigned)num_requests, (unsigned)(sizeof(MPI_Status))));
  }
  if (num_sends)
    send_map_starts[0] = 0;
  for (i = 0; i < num_sends; i++) {
    send_map_starts[i + 1] = proc_add[i + 1];
    send_procs[i] = proc_mark[i];
  }
  j = 0;
  for (i = 0; i < num_sends; i++) {
    vec_start = send_map_starts[i];
    vec_len = (send_map_starts[i + 1]) - vec_start;
    ip = send_procs[i];
    MPI_Irecv(&(big_buf_data[vec_start]), vec_len, MPI_INT, ip, 0, comm, &(requests[j++]));
  }
  for (i = 0; i < num_recvs; i++) {
    vec_start = recv_vec_starts[i];
    vec_len = (recv_vec_starts[i + 1]) - vec_start;
    ip = recv_procs[i];
    MPI_Isend(&(col_map_offd[vec_start]), vec_len, MPI_INT, ip, 0, comm, &(requests[j++]));
  }
  if (num_requests) {
    MPI_Waitall(num_requests, requests, status);
    hypre_Free((char*)requests), requests = (void*)0;
    hypre_Free((char*)status), status = (void*)0;
  }
  if (num_sends) {
    for (i = 0; i < (send_map_starts[num_sends]); i++)
      send_map_elmts[i] = (int)((big_buf_data[i]) - first_col_diag);
  }
  hypre_Free((char*)proc_add), proc_add = (void*)0;
  hypre_Free((char*)proc_mark), proc_mark = (void*)0;
  hypre_Free((char*)tmp), tmp = (void*)0;
  hypre_Free((char*)recv_buf), recv_buf = (void*)0;
  hypre_Free((char*)displs), displs = (void*)0;
  hypre_Free((char*)info), info = (void*)0;
  hypre_Free((char*)big_buf_data), big_buf_data = (void*)0;
  *p_num_recvs = num_recvs;
  *p_recv_procs = recv_procs;
  *p_recv_vec_starts = recv_vec_starts;
  *p_num_sends = num_sends;
  *p_send_procs = send_procs;
  *p_send_map_starts = send_map_starts;
  *p_send_map_elmts = send_map_elmts;
}
int hypre_MatvecCommPkgCreate(hypre_ParCSRMatrix* A) {
  hypre_ParCSRCommPkg* comm_pkg;
  MPI_Comm comm = (A)->comm;
  int num_sends;
  int* send_procs;
  int* send_map_starts;
  int* send_map_elmts;
  int num_recvs;
  int* recv_procs;
  int* recv_vec_starts;
  int* col_map_offd = (A)->col_map_offd;
  int first_col_diag = (A)->first_col_diag;
  int* col_starts = (A)->col_starts;
  int ierr = 0;
  int num_cols_diag = ((A)->diag)->num_cols;
  int num_cols_offd = ((A)->offd)->num_cols;
  hypre_MatvecCommPkgCreate_core(comm, col_map_offd, first_col_diag, col_starts, num_cols_diag, num_cols_offd, first_col_diag, col_map_offd, 1, &(num_recvs), &(recv_procs), &(recv_vec_starts), &(num_sends), &(send_procs), &(send_map_starts), &(send_map_elmts));
  comm_pkg = (hypre_ParCSRCommPkg*)(hypre_CAlloc((unsigned)1, (unsigned)(sizeof(hypre_ParCSRCommPkg))));
  (comm_pkg)->comm = comm;
  (comm_pkg)->num_recvs = num_recvs;
  (comm_pkg)->recv_procs = recv_procs;
  (comm_pkg)->recv_vec_starts = recv_vec_starts;
  (comm_pkg)->num_sends = num_sends;
  (comm_pkg)->send_procs = send_procs;
  (comm_pkg)->send_map_starts = send_map_starts;
  (comm_pkg)->send_map_elmts = send_map_elmts;
  (A)->comm_pkg = comm_pkg;
  return ierr;
}
int hypre_MatvecCommPkgDestroy(hypre_ParCSRCommPkg* comm_pkg) {
  int ierr = 0;
  if ((comm_pkg)->num_sends) {
    hypre_Free((char*)((comm_pkg)->send_procs)), (comm_pkg)->send_procs = (void*)0;
    hypre_Free((char*)((comm_pkg)->send_map_elmts)), (comm_pkg)->send_map_elmts = (void*)0;
  }
  hypre_Free((char*)((comm_pkg)->send_map_starts)), (comm_pkg)->send_map_starts = (void*)0;
  if ((comm_pkg)->num_recvs) {
    hypre_Free((char*)((comm_pkg)->recv_procs)), (comm_pkg)->recv_procs = (void*)0;
  }
  hypre_Free((char*)((comm_pkg)->recv_vec_starts)), (comm_pkg)->recv_vec_starts = (void*)0;
  hypre_Free((char*)comm_pkg), comm_pkg = (void*)0;
  return ierr;
}
//===================== par_csr_matop.c ====================
void hypre_ParMatmul_RowSizes(int** C_diag_i, int** C_offd_i, int** B_marker, int* A_diag_i, int* A_diag_j, int* A_offd_i, int* A_offd_j, int* B_diag_i, int* B_diag_j, int* B_offd_i, int* B_offd_j, int* B_ext_diag_i, int* B_ext_diag_j, int* B_ext_offd_i, int* B_ext_offd_j, int* map_B_to_C, int* C_diag_size, int* C_offd_size, int num_rows_diag_A, int num_cols_offd_A, int allsquare, int num_cols_diag_B, int num_cols_offd_B, int num_cols_offd_C) {
  int i1;
  int i2;
  int i3;
  int jj2;
  int jj3;
  int jj_count_diag;
  int jj_count_offd;
  int jj_row_begin_diag;
  int jj_row_begin_offd;
  int start_indexing = 0;
  *C_diag_i = (int*)(hypre_CAlloc((unsigned)(num_rows_diag_A + 1), (unsigned)(sizeof(int))));
  *C_offd_i = (int*)(hypre_CAlloc((unsigned)(num_rows_diag_A + 1), (unsigned)(sizeof(int))));
  jj_count_diag = start_indexing;
  jj_count_offd = start_indexing;
  for (i1 = 0; i1 < (num_cols_diag_B + num_cols_offd_C); i1++) {
    *B_marker[i1] = -1;
  }
  for (i1 = 0; i1 < num_rows_diag_A; i1++) {
    jj_row_begin_diag = jj_count_diag;
    jj_row_begin_offd = jj_count_offd;
    if (allsquare) {
      *B_marker[i1] = jj_count_diag;
      jj_count_diag++;
    }
    if (num_cols_offd_A) {
      for (jj2 = A_offd_i[i1]; jj2 < (A_offd_i[i1 + 1]); jj2++) {
        i2 = A_offd_j[jj2];
        for (jj3 = B_ext_offd_i[i2]; jj3 < (B_ext_offd_i[i2 + 1]); jj3++) {
          i3 = num_cols_diag_B + (B_ext_offd_j[jj3]);
          if ((*B_marker[i3]) < jj_row_begin_offd) {
            *B_marker[i3] = jj_count_offd;
            jj_count_offd++;
          }
        }
        for (jj3 = B_ext_diag_i[i2]; jj3 < (B_ext_diag_i[i2 + 1]); jj3++) {
          i3 = B_ext_diag_j[jj3];
          if ((*B_marker[i3]) < jj_row_begin_diag) {
            *B_marker[i3] = jj_count_diag;
            jj_count_diag++;
          }
        }
      }
    }
    for (jj2 = A_diag_i[i1]; jj2 < (A_diag_i[i1 + 1]); jj2++) {
      i2 = A_diag_j[jj2];
      for (jj3 = B_diag_i[i2]; jj3 < (B_diag_i[i2 + 1]); jj3++) {
        i3 = B_diag_j[jj3];
        if ((*B_marker[i3]) < jj_row_begin_diag) {
          *B_marker[i3] = jj_count_diag;
          jj_count_diag++;
        }
      }
      if (num_cols_offd_B) {
        for (jj3 = B_offd_i[i2]; jj3 < (B_offd_i[i2 + 1]); jj3++) {
          i3 = num_cols_diag_B + (map_B_to_C[B_offd_j[jj3]]);
          if ((*B_marker[i3]) < jj_row_begin_offd) {
            *B_marker[i3] = jj_count_offd;
            jj_count_offd++;
          }
        }
      }
    }
    *C_diag_i[i1] = jj_row_begin_diag;
    *C_offd_i[i1] = jj_row_begin_offd;
  }
  *C_diag_i[num_rows_diag_A] = jj_count_diag;
  *C_offd_i[num_rows_diag_A] = jj_count_offd;
  *C_diag_size = jj_count_diag;
  *C_offd_size = jj_count_offd;
}
hypre_ParCSRMatrix* hypre_ParMatmul(hypre_ParCSRMatrix* A, hypre_ParCSRMatrix* B) {
  MPI_Comm comm = (A)->comm;
  hypre_CSRMatrix* A_diag = (A)->diag;
  double* A_diag_data = (A_diag)->data;
  int* A_diag_i = (A_diag)->i;
  int* A_diag_j = (A_diag)->j;
  hypre_CSRMatrix* A_offd = (A)->offd;
  double* A_offd_data = (A_offd)->data;
  int* A_offd_i = (A_offd)->i;
  int* A_offd_j = (A_offd)->j;
  int* row_starts_A = (A)->row_starts;
  int num_rows_diag_A = (A_diag)->num_rows;
  int num_cols_diag_A = (A_diag)->num_cols;
  int num_cols_offd_A = (A_offd)->num_cols;
  hypre_CSRMatrix* B_diag = (B)->diag;
  double* B_diag_data = (B_diag)->data;
  int* B_diag_i = (B_diag)->i;
  int* B_diag_j = (B_diag)->j;
  hypre_CSRMatrix* B_offd = (B)->offd;
  int* col_map_offd_B = (B)->col_map_offd;
  double* B_offd_data = (B_offd)->data;
  int* B_offd_i = (B_offd)->i;
  int* B_offd_j = (B_offd)->j;
  int first_col_diag_B = (B)->first_col_diag;
  int last_col_diag_B;
  int* col_starts_B = (B)->col_starts;
  int num_rows_diag_B = (B_diag)->num_rows;
  int num_cols_diag_B = (B_diag)->num_cols;
  int num_cols_offd_B = (B_offd)->num_cols;
  hypre_ParCSRMatrix* C;
  int* col_map_offd_C;
  int* map_B_to_C;
  hypre_CSRMatrix* C_diag;
  double* C_diag_data;
  int* C_diag_i;
  int* C_diag_j;
  hypre_CSRMatrix* C_offd;
  double* C_offd_data = (void*)0;
  int* C_offd_i = (void*)0;
  int* C_offd_j = (void*)0;
  int C_diag_size;
  int C_offd_size;
  int num_cols_offd_C = 0;
  hypre_BigCSRMatrix* Bs_ext;
  double* Bs_ext_data;
  int* Bs_ext_i;
  int* Bs_ext_j;
  int* temp;
  double* B_ext_diag_data;
  int* B_ext_diag_i;
  int* B_ext_diag_j;
  int B_ext_diag_size;
  double* B_ext_offd_data;
  int* B_ext_offd_i;
  int* B_ext_offd_j;
  int B_ext_offd_size;
  int* B_marker;
  int i;
  int j;
  int i1;
  int i2;
  int i3;
  int jj2;
  int jj3;
  int jj_count_diag;
  int jj_count_offd;
  int jj_row_begin_diag;
  int jj_row_begin_offd;
  int start_indexing = 0;
  int n_rows_A;
  int n_cols_A;
  int n_rows_B;
  int n_cols_B;
  int value;
  int allsquare = 0;
  int cnt;
  int cnt_offd;
  int cnt_diag;
  int num_procs;
  double a_entry;
  double a_b_product;
  double zero = 0.0;
  n_rows_A = (A)->global_num_rows;
  n_cols_A = (A)->global_num_cols;
  n_rows_B = (B)->global_num_rows;
  n_cols_B = (B)->global_num_cols;
  if ((n_cols_A != n_rows_B) || (num_cols_diag_A != num_rows_diag_B)) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_mv/par_csr_matop.c", 908, 4 | (1 << 3));
    printf(" Error! Incompatible matrix dimensions!\n");
    return (void*)0;
  }
  if (num_rows_diag_A == num_cols_diag_B)
    allsquare = 1;
  MPI_Comm_size(comm, &(num_procs));
  if (num_procs > 1) {
    Bs_ext = hypre_ParCSRMatrixExtractBigExt(B, A, 1);
    Bs_ext_data = (Bs_ext)->data;
    Bs_ext_i = (Bs_ext)->i;
    Bs_ext_j = (Bs_ext)->j;
  }
  B_ext_diag_i = (int*)(hypre_CAlloc((unsigned)(num_cols_offd_A + 1), (unsigned)(sizeof(int))));
  B_ext_offd_i = (int*)(hypre_CAlloc((unsigned)(num_cols_offd_A + 1), (unsigned)(sizeof(int))));
  B_ext_diag_size = 0;
  B_ext_offd_size = 0;
  last_col_diag_B = (first_col_diag_B + (int)num_cols_diag_B) - 1;
  for (i = 0; i < num_cols_offd_A; i++) {
    for (j = Bs_ext_i[i]; j < (Bs_ext_i[i + 1]); j++)
      if (((Bs_ext_j[j]) < first_col_diag_B) || ((Bs_ext_j[j]) > last_col_diag_B))
        B_ext_offd_size++;
      else
        B_ext_diag_size++;
    B_ext_diag_i[i + 1] = B_ext_diag_size;
    B_ext_offd_i[i + 1] = B_ext_offd_size;
  }
  if (B_ext_diag_size) {
    B_ext_diag_j = (int*)(hypre_CAlloc((unsigned)B_ext_diag_size, (unsigned)(sizeof(int))));
    B_ext_diag_data = (double*)(hypre_CAlloc((unsigned)B_ext_diag_size, (unsigned)(sizeof(double))));
  }
  if (B_ext_offd_size) {
    B_ext_offd_j = (int*)(hypre_CAlloc((unsigned)B_ext_offd_size, (unsigned)(sizeof(int))));
    B_ext_offd_data = (double*)(hypre_CAlloc((unsigned)B_ext_offd_size, (unsigned)(sizeof(double))));
  }
  cnt_offd = 0;
  cnt_diag = 0;
  for (i = 0; i < num_cols_offd_A; i++) {
    for (j = Bs_ext_i[i]; j < (Bs_ext_i[i + 1]); j++)
      if (((Bs_ext_j[j]) < first_col_diag_B) || ((Bs_ext_j[j]) > last_col_diag_B)) {
        Bs_ext_j[cnt_offd] = Bs_ext_j[j];
        B_ext_offd_data[cnt_offd++] = Bs_ext_data[j];
      }
      else {
        B_ext_diag_j[cnt_diag] = (int)((Bs_ext_j[j]) - first_col_diag_B);
        B_ext_diag_data[cnt_diag++] = Bs_ext_data[j];
      }
  }
  cnt = 0;
  if (B_ext_offd_size || num_cols_offd_B) {
    temp = (int*)(hypre_CAlloc((unsigned)(B_ext_offd_size + num_cols_offd_B), (unsigned)(sizeof(int))));
    for (i = 0; i < B_ext_offd_size; i++)
      temp[i] = Bs_ext_j[i];
    cnt = B_ext_offd_size;
    for (i = 0; i < num_cols_offd_B; i++)
      temp[cnt++] = col_map_offd_B[i];
  }
  if (cnt) {
    hypre_BigQsort0(temp, 0, cnt - 1);
    num_cols_offd_C = 1;
    value = temp[0];
    for (i = 1; i < cnt; i++) {
      if ((temp[i]) > value) {
        value = temp[i];
        temp[num_cols_offd_C++] = value;
      }
    }
  }
  if (num_cols_offd_C)
    col_map_offd_C = (int*)(hypre_CAlloc((unsigned)num_cols_offd_C, (unsigned)(sizeof(int))));
  for (i = 0; i < num_cols_offd_C; i++)
    col_map_offd_C[i] = temp[i];
  if (B_ext_offd_size || num_cols_offd_B)
    hypre_Free((char*)temp), temp = (void*)0;
  for (i = 0; i < B_ext_offd_size; i++)
    B_ext_offd_j[i] = hypre_BigBinarySearch(col_map_offd_C, Bs_ext_j[i], num_cols_offd_C);
  if (num_procs > 1) {
    hypre_BigCSRMatrixDestroy(Bs_ext);
    Bs_ext = (void*)0;
  }
  if (num_cols_offd_B) {
    map_B_to_C = (int*)(hypre_CAlloc((unsigned)num_cols_offd_B, (unsigned)(sizeof(int))));
    cnt = 0;
    for (i = 0; i < num_cols_offd_C; i++)
      if ((col_map_offd_C[i]) == (col_map_offd_B[cnt])) {
        map_B_to_C[cnt++] = i;
        if (cnt == num_cols_offd_B)
          break;
      }
  }
  B_marker = (int*)(hypre_CAlloc((unsigned)(num_cols_diag_B + num_cols_offd_C), (unsigned)(sizeof(int))));
  for (i1 = 0; i1 < (num_cols_diag_B + num_cols_offd_C); i1++) {
    B_marker[i1] = -1;
  }
  hypre_ParMatmul_RowSizes(&(C_diag_i), &(C_offd_i), &(B_marker), A_diag_i, A_diag_j, A_offd_i, A_offd_j, B_diag_i, B_diag_j, B_offd_i, B_offd_j, B_ext_diag_i, B_ext_diag_j, B_ext_offd_i, B_ext_offd_j, map_B_to_C, &(C_diag_size), &(C_offd_size), num_rows_diag_A, num_cols_offd_A, allsquare, num_cols_diag_B, num_cols_offd_B, num_cols_offd_C);
  last_col_diag_B = (first_col_diag_B + (int)num_cols_diag_B) - 1;
  C_diag_data = (double*)(hypre_CAlloc((unsigned)C_diag_size, (unsigned)(sizeof(double))));
  C_diag_j = (int*)(hypre_CAlloc((unsigned)C_diag_size, (unsigned)(sizeof(int))));
  if (C_offd_size) {
    C_offd_data = (double*)(hypre_CAlloc((unsigned)C_offd_size, (unsigned)(sizeof(double))));
    C_offd_j = (int*)(hypre_CAlloc((unsigned)C_offd_size, (unsigned)(sizeof(int))));
  }
  jj_count_diag = start_indexing;
  jj_count_offd = start_indexing;
  for (i1 = 0; i1 < (num_cols_diag_B + num_cols_offd_C); i1++) {
    B_marker[i1] = -1;
  }
  for (i1 = 0; i1 < num_rows_diag_A; i1++) {
    jj_row_begin_diag = jj_count_diag;
    jj_row_begin_offd = jj_count_offd;
    if (allsquare) {
      B_marker[i1] = jj_count_diag;
      C_diag_data[jj_count_diag] = zero;
      C_diag_j[jj_count_diag] = i1;
      jj_count_diag++;
    }
    if (num_cols_offd_A) {
      for (jj2 = A_offd_i[i1]; jj2 < (A_offd_i[i1 + 1]); jj2++) {
        i2 = A_offd_j[jj2];
        a_entry = A_offd_data[jj2];
        for (jj3 = B_ext_offd_i[i2]; jj3 < (B_ext_offd_i[i2 + 1]); jj3++) {
          i3 = num_cols_diag_B + (B_ext_offd_j[jj3]);
          a_b_product = a_entry * (B_ext_offd_data[jj3]);
          if ((B_marker[i3]) < jj_row_begin_offd) {
            B_marker[i3] = jj_count_offd;
            C_offd_data[jj_count_offd] = a_b_product;
            C_offd_j[jj_count_offd] = i3 - num_cols_diag_B;
            jj_count_offd++;
          }
          else
            C_offd_data[B_marker[i3]] += a_b_product;
        }
        for (jj3 = B_ext_diag_i[i2]; jj3 < (B_ext_diag_i[i2 + 1]); jj3++) {
          i3 = B_ext_diag_j[jj3];
          a_b_product = a_entry * (B_ext_diag_data[jj3]);
          if ((B_marker[i3]) < jj_row_begin_diag) {
            B_marker[i3] = jj_count_diag;
            C_diag_data[jj_count_diag] = a_b_product;
            C_diag_j[jj_count_diag] = i3;
            jj_count_diag++;
          }
          else
            C_diag_data[B_marker[i3]] += a_b_product;
        }
      }
    }
    for (jj2 = A_diag_i[i1]; jj2 < (A_diag_i[i1 + 1]); jj2++) {
      i2 = A_diag_j[jj2];
      a_entry = A_diag_data[jj2];
      for (jj3 = B_diag_i[i2]; jj3 < (B_diag_i[i2 + 1]); jj3++) {
        i3 = B_diag_j[jj3];
        a_b_product = a_entry * (B_diag_data[jj3]);
        if ((B_marker[i3]) < jj_row_begin_diag) {
          B_marker[i3] = jj_count_diag;
          C_diag_data[jj_count_diag] = a_b_product;
          C_diag_j[jj_count_diag] = i3;
          jj_count_diag++;
        }
        else {
          C_diag_data[B_marker[i3]] += a_b_product;
        }
      }
      if (num_cols_offd_B) {
        for (jj3 = B_offd_i[i2]; jj3 < (B_offd_i[i2 + 1]); jj3++) {
          i3 = num_cols_diag_B + (map_B_to_C[B_offd_j[jj3]]);
          a_b_product = a_entry * (B_offd_data[jj3]);
          if ((B_marker[i3]) < jj_row_begin_offd) {
            B_marker[i3] = jj_count_offd;
            C_offd_data[jj_count_offd] = a_b_product;
            C_offd_j[jj_count_offd] = i3 - num_cols_diag_B;
            jj_count_offd++;
          }
          else {
            C_offd_data[B_marker[i3]] += a_b_product;
          }
        }
      }
    }
  }
  C = hypre_ParCSRMatrixCreate(comm, n_rows_A, n_cols_B, row_starts_A, col_starts_B, num_cols_offd_C, C_diag_size, C_offd_size);
  hypre_ParCSRMatrixSetRowStartsOwner(C, 0);
  hypre_ParCSRMatrixSetColStartsOwner(C, 0);
  C_diag = (C)->diag;
  (C_diag)->data = C_diag_data;
  (C_diag)->i = C_diag_i;
  (C_diag)->j = C_diag_j;
  C_offd = (C)->offd;
  (C_offd)->i = C_offd_i;
  (C)->offd = C_offd;
  if (num_cols_offd_C) {
    (C_offd)->data = C_offd_data;
    (C_offd)->j = C_offd_j;
    (C)->col_map_offd = col_map_offd_C;
  }
  hypre_Free((char*)B_marker), B_marker = (void*)0;
  hypre_Free((char*)B_ext_diag_i), B_ext_diag_i = (void*)0;
  if (B_ext_diag_size) {
    hypre_Free((char*)B_ext_diag_j), B_ext_diag_j = (void*)0;
    hypre_Free((char*)B_ext_diag_data), B_ext_diag_data = (void*)0;
  }
  hypre_Free((char*)B_ext_offd_i), B_ext_offd_i = (void*)0;
  if (B_ext_offd_size) {
    hypre_Free((char*)B_ext_offd_j), B_ext_offd_j = (void*)0;
    hypre_Free((char*)B_ext_offd_data), B_ext_offd_data = (void*)0;
  }
  if (num_cols_offd_B)
    hypre_Free((char*)map_B_to_C), map_B_to_C = (void*)0;
  return C;
}
hypre_CSRMatrix* hypre_ParCSRMatrixExtractConvBExt(hypre_ParCSRMatrix* B, hypre_ParCSRMatrix* A, int data) {
  MPI_Comm comm = (B)->comm;
  int first_col_diag = (B)->first_col_diag;
  int* col_map_offd = (B)->col_map_offd;
  hypre_ParCSRCommPkg* comm_pkg = (A)->comm_pkg;
  int num_recvs;
  int* recv_vec_starts;
  int num_sends;
  int* send_map_starts;
  int* send_map_elmts;
  hypre_CSRMatrix* diag = (B)->diag;
  int* diag_i = (diag)->i;
  int* diag_j = (diag)->j;
  double* diag_data = (diag)->data;
  hypre_CSRMatrix* offd = (B)->offd;
  int* offd_i = (offd)->i;
  int* offd_j = (offd)->j;
  double* offd_data = (offd)->data;
  int num_cols_offd = (offd)->num_cols;
  int num_cols_B;
  int num_nonzeros;
  int num_rows_B_ext;
  hypre_CSRMatrix* B_ext;
  int* B_ext_i;
  int* B_tmp_j;
  int* B_ext_j;
  double* B_ext_data;
  hypre_ParCSRCommHandle* comm_handle;
  hypre_ParCSRCommPkg* tmp_comm_pkg;
  int* B_int_i;
  int* B_int_j;
  double* B_int_data;
  int num_procs;
  int my_id;
  int* jdata_recv_vec_starts;
  int* jdata_send_map_starts;
  int i;
  int j;
  int k;
  int counter;
  int cnt;
  int start_index;
  int j_cnt;
  int j_cnt_rm;
  int jrow;
  int big_k;
  int col_1;
  int col_n;
  MPI_Comm_size(comm, &(num_procs));
  MPI_Comm_rank(comm, &(my_id));
  num_cols_B = (diag)->num_rows;
  col_1 = first_col_diag;
  col_n = first_col_diag + (int)num_cols_B;
  if (!(A)->comm_pkg) {
    hypre_MatvecCommPkgCreate(A);
  }
  comm_pkg = (A)->comm_pkg;
  num_recvs = (comm_pkg)->num_recvs;
  recv_vec_starts = (comm_pkg)->recv_vec_starts;
  num_sends = (comm_pkg)->num_sends;
  send_map_starts = (comm_pkg)->send_map_starts;
  send_map_elmts = (comm_pkg)->send_map_elmts;
  num_cols_B = (B)->global_num_cols;
  num_rows_B_ext = recv_vec_starts[num_recvs];
  num_rows_B_ext = recv_vec_starts[num_recvs];
  if (num_rows_B_ext < 0) {
    B_ext_i = (void*)0;
    B_ext_j = (void*)0;
    if (data)
      B_ext_data = (void*)0;
    num_nonzeros = 0;
    return 0;
  }
  ;
  B_int_i = (int*)(hypre_CAlloc((unsigned)((send_map_starts[num_sends]) + 1), (unsigned)(sizeof(int))));
  B_ext_i = (int*)(hypre_CAlloc((unsigned)(num_rows_B_ext + 1), (unsigned)(sizeof(int))));
  B_int_i[0] = 0;
  j_cnt = 0;
  j_cnt_rm = 0;
  num_nonzeros = 0;
  for (i = 0; i < num_sends; i++) {
    for (j = send_map_starts[i]; j < (send_map_starts[i + 1]); j++) {
      jrow = send_map_elmts[j];
      B_int_i[++j_cnt] = (((offd_i[jrow + 1]) - (offd_i[jrow])) + (diag_i[jrow + 1])) - (diag_i[jrow]);
      num_nonzeros += B_int_i[j_cnt];
    }
  }
  comm_handle = hypre_ParCSRCommHandleCreate(11, comm_pkg, &(B_int_i[1]), &(B_ext_i[1]));
  B_int_j = (int*)(hypre_CAlloc((unsigned)num_nonzeros, (unsigned)(sizeof(int))));
  if (data)
    B_int_data = (double*)(hypre_CAlloc((unsigned)num_nonzeros, (unsigned)(sizeof(double))));
  jdata_send_map_starts = (int*)(hypre_CAlloc((unsigned)(num_sends + 1), (unsigned)(sizeof(int))));
  jdata_recv_vec_starts = (int*)(hypre_CAlloc((unsigned)(num_recvs + 1), (unsigned)(sizeof(int))));
  start_index = B_int_i[0];
  jdata_send_map_starts[0] = start_index;
  counter = 0;
  for (i = 0; i < num_sends; i++) {
    num_nonzeros = counter;
    for (j = send_map_starts[i]; j < (send_map_starts[i + 1]); j++) {
      jrow = send_map_elmts[j];
      for (k = diag_i[jrow]; k < (diag_i[jrow + 1]); k++) {
        B_int_j[counter] = (int)(diag_j[k]) + first_col_diag;
        if (data)
          B_int_data[counter] = diag_data[k];
        counter++;
      }
      for (k = offd_i[jrow]; k < (offd_i[jrow + 1]); k++) {
        B_int_j[counter] = col_map_offd[offd_j[k]];
        if (data)
          B_int_data[counter] = offd_data[k];
        counter++;
      }
    }
    num_nonzeros = counter - num_nonzeros;
    start_index += num_nonzeros;
    jdata_send_map_starts[i + 1] = start_index;
  }
  tmp_comm_pkg = (hypre_ParCSRCommPkg*)(hypre_CAlloc((unsigned)1, (unsigned)(sizeof(hypre_ParCSRCommPkg))));
  (tmp_comm_pkg)->comm = comm;
  (tmp_comm_pkg)->num_sends = num_sends;
  (tmp_comm_pkg)->num_recvs = num_recvs;
  (tmp_comm_pkg)->send_procs = (comm_pkg)->send_procs;
  (tmp_comm_pkg)->recv_procs = (comm_pkg)->recv_procs;
  (tmp_comm_pkg)->send_map_starts = jdata_send_map_starts;
  hypre_ParCSRCommHandleDestroy(comm_handle);
  comm_handle = (void*)0;
  for (i = 0; i < num_recvs; i++)
    for (j = recv_vec_starts[i]; j < (recv_vec_starts[i + 1]); j++)
      B_ext_i[j + 1] += B_ext_i[j];
  num_nonzeros = B_ext_i[num_rows_B_ext];
  B_tmp_j = (int*)(hypre_CAlloc((unsigned)num_nonzeros, (unsigned)(sizeof(int))));
  B_ext_j = (int*)(hypre_CAlloc((unsigned)num_nonzeros, (unsigned)(sizeof(int))));
  if (data)
    B_ext_data = (double*)(hypre_CAlloc((unsigned)num_nonzeros, (unsigned)(sizeof(double))));
  for (i = 0; i < num_recvs; i++) {
    start_index = B_ext_i[recv_vec_starts[i]];
    num_nonzeros = (B_ext_i[recv_vec_starts[i + 1]]) - start_index;
    jdata_recv_vec_starts[i + 1] = B_ext_i[recv_vec_starts[i + 1]];
  }
  (tmp_comm_pkg)->recv_vec_starts = jdata_recv_vec_starts;
  comm_handle = hypre_ParCSRCommHandleCreate(21, tmp_comm_pkg, B_int_j, B_tmp_j);
  hypre_ParCSRCommHandleDestroy(comm_handle);
  comm_handle = (void*)0;
  if (data) {
    comm_handle = hypre_ParCSRCommHandleCreate(1, tmp_comm_pkg, B_int_data, B_ext_data);
    hypre_ParCSRCommHandleDestroy(comm_handle);
    comm_handle = (void*)0;
  }
  hypre_Free((char*)jdata_send_map_starts), jdata_send_map_starts = (void*)0;
  hypre_Free((char*)jdata_recv_vec_starts), jdata_recv_vec_starts = (void*)0;
  hypre_Free((char*)tmp_comm_pkg), tmp_comm_pkg = (void*)0;
  hypre_Free((char*)B_int_i), B_int_i = (void*)0;
  hypre_Free((char*)B_int_j), B_int_j = (void*)0;
  if (data)
    hypre_Free((char*)B_int_data), B_int_data = (void*)0;
  cnt = 0;
  for (i = 0; i < num_rows_B_ext; i++) {
    for (j = B_ext_i[i]; j < (B_ext_i[i + 1]); j++) {
      big_k = B_tmp_j[j];
      if ((big_k >= col_1) && (big_k < col_n)) {
        if (data)
          B_ext_data[cnt] = B_ext_data[j];
        B_ext_j[cnt++] = (int)(big_k - col_1);
      }
      else {
        k = hypre_BigBinarySearch(col_map_offd, big_k, num_cols_offd);
        if (k > (-1)) {
          if (data)
            B_ext_data[cnt] = B_ext_data[j];
          B_ext_j[cnt++] = (-k) - 1;
        }
      }
    }
    B_ext_i[i] = cnt;
  }
  for (i = num_rows_B_ext; i > 0; i--)
    B_ext_i[i] = B_ext_i[i - 1];
  if (num_procs > 1)
    B_ext_i[0] = 0;
  B_ext = hypre_CSRMatrixCreate(num_rows_B_ext, num_cols_B, num_nonzeros);
  (B_ext)->i = B_ext_i;
  (B_ext)->j = B_ext_j;
  if (data)
    (B_ext)->data = B_ext_data;
  return B_ext;
}
hypre_BigCSRMatrix* hypre_ParCSRMatrixExtractBigExt(hypre_ParCSRMatrix* B, hypre_ParCSRMatrix* A, int data) {
  MPI_Comm comm = (B)->comm;
  int first_col_diag = (B)->first_col_diag;
  int* col_map_offd = (B)->col_map_offd;
  hypre_ParCSRCommPkg* comm_pkg = (A)->comm_pkg;
  int num_recvs;
  int* recv_vec_starts;
  int num_sends;
  int* send_map_starts;
  int* send_map_elmts;
  hypre_CSRMatrix* diag = (B)->diag;
  int* diag_i = (diag)->i;
  int* diag_j = (diag)->j;
  double* diag_data = (diag)->data;
  hypre_CSRMatrix* offd = (B)->offd;
  int* offd_i = (offd)->i;
  int* offd_j = (offd)->j;
  double* offd_data = (offd)->data;
  int num_cols_B;
  int num_nonzeros;
  hypre_BigCSRMatrix* B_ext;
  int* B_ext_i;
  int* B_ext_j;
  double* B_ext_data;
  hypre_ParCSRCommHandle* comm_handle;
  hypre_ParCSRCommPkg* tmp_comm_pkg;
  int* B_int_i;
  int* B_int_j;
  double* B_int_data;
  int num_procs;
  int my_id;
  int* jdata_recv_vec_starts;
  int* jdata_send_map_starts;
  int i;
  int j;
  int k;
  int counter;
  int start_index;
  int j_cnt;
  int j_cnt_rm;
  int jrow;
  int num_rows_B_ext;
  MPI_Comm_size(comm, &(num_procs));
  MPI_Comm_rank(comm, &(my_id));
  if (!(A)->comm_pkg) {
    hypre_MatvecCommPkgCreate(A);
  }
  comm_pkg = (A)->comm_pkg;
  num_recvs = (comm_pkg)->num_recvs;
  recv_vec_starts = (comm_pkg)->recv_vec_starts;
  num_sends = (comm_pkg)->num_sends;
  send_map_starts = (comm_pkg)->send_map_starts;
  send_map_elmts = (comm_pkg)->send_map_elmts;
  num_cols_B = (B)->global_num_cols;
  num_rows_B_ext = recv_vec_starts[num_recvs];
  num_rows_B_ext = recv_vec_starts[num_recvs];
  if (num_rows_B_ext < 0) {
    B_ext_i = (void*)0;
    B_ext_j = (void*)0;
    if (data)
      B_ext_data = (void*)0;
    num_nonzeros = 0;
    return 0;
  }
  ;
  B_int_i = (int*)(hypre_CAlloc((unsigned)((send_map_starts[num_sends]) + 1), (unsigned)(sizeof(int))));
  B_ext_i = (int*)(hypre_CAlloc((unsigned)(num_rows_B_ext + 1), (unsigned)(sizeof(int))));
  B_int_i[0] = 0;
  j_cnt = 0;
  j_cnt_rm = 0;
  num_nonzeros = 0;
  for (i = 0; i < num_sends; i++) {
    for (j = send_map_starts[i]; j < (send_map_starts[i + 1]); j++) {
      jrow = send_map_elmts[j];
      B_int_i[++j_cnt] = (((offd_i[jrow + 1]) - (offd_i[jrow])) + (diag_i[jrow + 1])) - (diag_i[jrow]);
      num_nonzeros += B_int_i[j_cnt];
    }
  }
  comm_handle = hypre_ParCSRCommHandleCreate(11, comm_pkg, &(B_int_i[1]), &(B_ext_i[1]));
  B_int_j = (int*)(hypre_CAlloc((unsigned)num_nonzeros, (unsigned)(sizeof(int))));
  if (data)
    B_int_data = (double*)(hypre_CAlloc((unsigned)num_nonzeros, (unsigned)(sizeof(double))));
  jdata_send_map_starts = (int*)(hypre_CAlloc((unsigned)(num_sends + 1), (unsigned)(sizeof(int))));
  jdata_recv_vec_starts = (int*)(hypre_CAlloc((unsigned)(num_recvs + 1), (unsigned)(sizeof(int))));
  start_index = B_int_i[0];
  jdata_send_map_starts[0] = start_index;
  counter = 0;
  for (i = 0; i < num_sends; i++) {
    num_nonzeros = counter;
    for (j = send_map_starts[i]; j < (send_map_starts[i + 1]); j++) {
      jrow = send_map_elmts[j];
      for (k = diag_i[jrow]; k < (diag_i[jrow + 1]); k++) {
        B_int_j[counter] = (int)(diag_j[k]) + first_col_diag;
        if (data)
          B_int_data[counter] = diag_data[k];
        counter++;
      }
      for (k = offd_i[jrow]; k < (offd_i[jrow + 1]); k++) {
        B_int_j[counter] = col_map_offd[offd_j[k]];
        if (data)
          B_int_data[counter] = offd_data[k];
        counter++;
      }
    }
    num_nonzeros = counter - num_nonzeros;
    start_index += num_nonzeros;
    jdata_send_map_starts[i + 1] = start_index;
  }
  tmp_comm_pkg = (hypre_ParCSRCommPkg*)(hypre_CAlloc((unsigned)1, (unsigned)(sizeof(hypre_ParCSRCommPkg))));
  (tmp_comm_pkg)->comm = comm;
  (tmp_comm_pkg)->num_sends = num_sends;
  (tmp_comm_pkg)->num_recvs = num_recvs;
  (tmp_comm_pkg)->send_procs = (comm_pkg)->send_procs;
  (tmp_comm_pkg)->recv_procs = (comm_pkg)->recv_procs;
  (tmp_comm_pkg)->send_map_starts = jdata_send_map_starts;
  hypre_ParCSRCommHandleDestroy(comm_handle);
  comm_handle = (void*)0;
  for (i = 0; i < num_recvs; i++)
    for (j = recv_vec_starts[i]; j < (recv_vec_starts[i + 1]); j++)
      B_ext_i[j + 1] += B_ext_i[j];
  num_nonzeros = B_ext_i[num_rows_B_ext];
  B_ext_j = (int*)(hypre_CAlloc((unsigned)num_nonzeros, (unsigned)(sizeof(int))));
  if (data)
    B_ext_data = (double*)(hypre_CAlloc((unsigned)num_nonzeros, (unsigned)(sizeof(double))));
  for (i = 0; i < num_recvs; i++) {
    start_index = B_ext_i[recv_vec_starts[i]];
    num_nonzeros = (B_ext_i[recv_vec_starts[i + 1]]) - start_index;
    jdata_recv_vec_starts[i + 1] = B_ext_i[recv_vec_starts[i + 1]];
  }
  (tmp_comm_pkg)->recv_vec_starts = jdata_recv_vec_starts;
  comm_handle = hypre_ParCSRCommHandleCreate(21, tmp_comm_pkg, B_int_j, B_ext_j);
  hypre_ParCSRCommHandleDestroy(comm_handle);
  comm_handle = (void*)0;
  if (data) {
    comm_handle = hypre_ParCSRCommHandleCreate(1, tmp_comm_pkg, B_int_data, B_ext_data);
    hypre_ParCSRCommHandleDestroy(comm_handle);
    comm_handle = (void*)0;
  }
  hypre_Free((char*)jdata_send_map_starts), jdata_send_map_starts = (void*)0;
  hypre_Free((char*)jdata_recv_vec_starts), jdata_recv_vec_starts = (void*)0;
  hypre_Free((char*)tmp_comm_pkg), tmp_comm_pkg = (void*)0;
  hypre_Free((char*)B_int_i), B_int_i = (void*)0;
  hypre_Free((char*)B_int_j), B_int_j = (void*)0;
  if (data)
    hypre_Free((char*)B_int_data), B_int_data = (void*)0;
  B_ext = hypre_BigCSRMatrixCreate(num_rows_B_ext, num_cols_B, num_nonzeros);
  (B_ext)->i = B_ext_i;
  (B_ext)->j = B_ext_j;
  if (data)
    (B_ext)->data = B_ext_data;
  return B_ext;
}
//================= par_csr_matop_marked.c =================
void hypre_ParMatmul_RowSizes_Marked(int** C_diag_i, int** C_offd_i, int** B_marker, int* A_diag_i, int* A_diag_j, int* A_offd_i, int* A_offd_j, int* B_diag_i, int* B_diag_j, int* B_offd_i, int* B_offd_j, int* B_ext_diag_i, int* B_ext_diag_j, int* B_ext_offd_i, int* B_ext_offd_j, int* map_B_to_C, int* C_diag_size, int* C_offd_size, int num_rows_diag_A, int num_cols_offd_A, int allsquare, int num_cols_diag_B, int num_cols_offd_B, int num_cols_offd_C, int* CF_marker, int* dof_func, int* dof_func_offd) {
  int i1;
  int i2;
  int i3;
  int jj2;
  int jj3;
  int jj_count_diag;
  int jj_count_offd;
  int jj_row_begin_diag;
  int jj_row_begin_offd;
  int start_indexing = 0;
  *C_diag_i = (int*)(hypre_CAlloc((unsigned)(num_rows_diag_A + 1), (unsigned)(sizeof(int))));
  *C_offd_i = (int*)(hypre_CAlloc((unsigned)(num_rows_diag_A + 1), (unsigned)(sizeof(int))));
  jj_count_diag = start_indexing;
  jj_count_offd = start_indexing;
  for (i1 = 0; i1 < (num_cols_diag_B + num_cols_offd_C); i1++) {
    *B_marker[i1] = -1;
  }
  for (i1 = 0; i1 < num_rows_diag_A; i1++)
    if ((CF_marker[i1]) >= 0) {
      jj_row_begin_diag = jj_count_diag;
      jj_row_begin_offd = jj_count_offd;
      jj_count_diag += (B_diag_i[i1 + 1]) - (B_diag_i[i1]);
      jj_count_offd += (B_offd_i[i1 + 1]) - (B_offd_i[i1]);
      *C_diag_i[i1] = jj_row_begin_diag;
      *C_offd_i[i1] = jj_row_begin_offd;
    }
    else {
      jj_row_begin_diag = jj_count_diag;
      jj_row_begin_offd = jj_count_offd;
      if (allsquare) {
        *B_marker[i1] = jj_count_diag;
        jj_count_diag++;
      }
      if (num_cols_offd_A) {
        for (jj2 = A_offd_i[i1]; jj2 < (A_offd_i[i1 + 1]); jj2++) {
          i2 = A_offd_j[jj2];
          if ((dof_func == (void*)0) || ((dof_func[i1]) == (dof_func_offd[i2]))) {
            for (jj3 = B_ext_offd_i[i2]; jj3 < (B_ext_offd_i[i2 + 1]); jj3++) {
              i3 = num_cols_diag_B + (B_ext_offd_j[jj3]);
              if ((*B_marker[i3]) < jj_row_begin_offd) {
                *B_marker[i3] = jj_count_offd;
                jj_count_offd++;
              }
            }
            for (jj3 = B_ext_diag_i[i2]; jj3 < (B_ext_diag_i[i2 + 1]); jj3++) {
              i3 = B_ext_diag_j[jj3];
              if ((*B_marker[i3]) < jj_row_begin_diag) {
                *B_marker[i3] = jj_count_diag;
                jj_count_diag++;
              }
            }
          }
        }
      }
      for (jj2 = A_diag_i[i1]; jj2 < (A_diag_i[i1 + 1]); jj2++) {
        i2 = A_diag_j[jj2];
        if ((dof_func == (void*)0) || ((dof_func[i1]) == (dof_func[i2]))) {
          for (jj3 = B_diag_i[i2]; jj3 < (B_diag_i[i2 + 1]); jj3++) {
            i3 = B_diag_j[jj3];
            if ((*B_marker[i3]) < jj_row_begin_diag) {
              *B_marker[i3] = jj_count_diag;
              jj_count_diag++;
            }
          }
          if (num_cols_offd_B) {
            for (jj3 = B_offd_i[i2]; jj3 < (B_offd_i[i2 + 1]); jj3++) {
              i3 = num_cols_diag_B + (map_B_to_C[B_offd_j[jj3]]);
              if ((*B_marker[i3]) < jj_row_begin_offd) {
                *B_marker[i3] = jj_count_offd;
                jj_count_offd++;
              }
            }
          }
        }
      }
      *C_diag_i[i1] = jj_row_begin_diag;
      *C_offd_i[i1] = jj_row_begin_offd;
    }
  *C_diag_i[num_rows_diag_A] = jj_count_diag;
  *C_offd_i[num_rows_diag_A] = jj_count_offd;
  *C_diag_size = jj_count_diag;
  *C_offd_size = jj_count_offd;
}
hypre_ParCSRMatrix* hypre_ParMatmul_FC(hypre_ParCSRMatrix* A, hypre_ParCSRMatrix* P, int* CF_marker, int* dof_func, int* dof_func_offd) {
  MPI_Comm comm = (A)->comm;
  hypre_CSRMatrix* A_diag = (A)->diag;
  double* A_diag_data = (A_diag)->data;
  int* A_diag_i = (A_diag)->i;
  int* A_diag_j = (A_diag)->j;
  hypre_CSRMatrix* A_offd = (A)->offd;
  double* A_offd_data = (A_offd)->data;
  int* A_offd_i = (A_offd)->i;
  int* A_offd_j = (A_offd)->j;
  int* row_starts_A = (A)->row_starts;
  int num_rows_diag_A = (A_diag)->num_rows;
  int num_cols_diag_A = (A_diag)->num_cols;
  int num_cols_offd_A = (A_offd)->num_cols;
  hypre_CSRMatrix* P_diag = (P)->diag;
  double* P_diag_data = (P_diag)->data;
  int* P_diag_i = (P_diag)->i;
  int* P_diag_j = (P_diag)->j;
  hypre_CSRMatrix* P_offd = (P)->offd;
  int* col_map_offd_P = (P)->col_map_offd;
  double* P_offd_data = (P_offd)->data;
  int* P_offd_i = (P_offd)->i;
  int* P_offd_j = (P_offd)->j;
  int first_col_diag_P = (P)->first_col_diag;
  int last_col_diag_P;
  int* col_starts_P = (P)->col_starts;
  int num_rows_diag_P = (P_diag)->num_rows;
  int num_cols_diag_P = (P_diag)->num_cols;
  int num_cols_offd_P = (P_offd)->num_cols;
  hypre_ParCSRMatrix* C;
  int* col_map_offd_C;
  int* map_P_to_C;
  hypre_CSRMatrix* C_diag;
  double* C_diag_data;
  int* C_diag_i;
  int* C_diag_j;
  hypre_CSRMatrix* C_offd;
  double* C_offd_data = (void*)0;
  int* C_offd_i = (void*)0;
  int* C_offd_j = (void*)0;
  int C_diag_size;
  int C_offd_size;
  int num_cols_offd_C = 0;
  hypre_BigCSRMatrix* Ps_ext;
  double* Ps_ext_data;
  int* Ps_ext_i;
  int* Ps_ext_j;
  double* P_ext_diag_data;
  int* P_ext_diag_i;
  int* P_ext_diag_j;
  int P_ext_diag_size;
  double* P_ext_offd_data;
  int* P_ext_offd_i;
  int* P_ext_offd_j;
  int* P_ext_tmp_j;
  int P_ext_offd_size;
  int* P_marker;
  int* temp;
  int i;
  int j;
  int i1;
  int i2;
  int i3;
  int jj2;
  int jj3;
  int jj_count_diag;
  int jj_count_offd;
  int jj_row_begin_diag;
  int jj_row_begin_offd;
  int start_indexing = 0;
  int n_rows_A_global;
  int n_cols_A_global;
  int n_rows_P_global;
  int n_cols_P_global;
  int allsquare = 0;
  int cnt;
  int cnt_offd;
  int cnt_diag;
  int num_procs;
  int value;
  double a_entry;
  double a_b_product;
  n_rows_A_global = (A)->global_num_rows;
  n_cols_A_global = (A)->global_num_cols;
  n_rows_P_global = (P)->global_num_rows;
  n_cols_P_global = (P)->global_num_cols;
  if ((n_cols_A_global != n_rows_P_global) || (num_cols_diag_A != num_rows_diag_P)) {
    printf(" Error! Incompatible matrix dimensions!\n");
    return (void*)0;
  }
  MPI_Comm_size(comm, &(num_procs));
  if (num_procs > 1) {
    Ps_ext = hypre_ParCSRMatrixExtractBigExt(P, A, 1);
    Ps_ext_data = (Ps_ext)->data;
    Ps_ext_i = (Ps_ext)->i;
    Ps_ext_j = (Ps_ext)->j;
  }
  P_ext_diag_i = (int*)(hypre_CAlloc((unsigned)(num_cols_offd_A + 1), (unsigned)(sizeof(int))));
  P_ext_offd_i = (int*)(hypre_CAlloc((unsigned)(num_cols_offd_A + 1), (unsigned)(sizeof(int))));
  P_ext_diag_size = 0;
  P_ext_offd_size = 0;
  last_col_diag_P = (first_col_diag_P + num_cols_diag_P) - 1;
  for (i = 0; i < num_cols_offd_A; i++) {
    for (j = Ps_ext_i[i]; j < (Ps_ext_i[i + 1]); j++)
      if (((Ps_ext_j[j]) < first_col_diag_P) || ((Ps_ext_j[j]) > last_col_diag_P))
        P_ext_offd_size++;
      else
        P_ext_diag_size++;
    P_ext_diag_i[i + 1] = P_ext_diag_size;
    P_ext_offd_i[i + 1] = P_ext_offd_size;
  }
  if (P_ext_diag_size) {
    P_ext_diag_j = (int*)(hypre_CAlloc((unsigned)P_ext_diag_size, (unsigned)(sizeof(int))));
    P_ext_diag_data = (double*)(hypre_CAlloc((unsigned)P_ext_diag_size, (unsigned)(sizeof(double))));
  }
  if (P_ext_offd_size) {
    temp = (int*)(hypre_CAlloc((unsigned)(P_ext_offd_size + num_cols_offd_P), (unsigned)(sizeof(int))));
    P_ext_offd_j = (int*)(hypre_CAlloc((unsigned)P_ext_offd_size, (unsigned)(sizeof(int))));
    P_ext_offd_data = (double*)(hypre_CAlloc((unsigned)P_ext_offd_size, (unsigned)(sizeof(double))));
  }
  cnt_offd = 0;
  cnt_diag = 0;
  for (i = 0; i < num_cols_offd_A; i++) {
    for (j = Ps_ext_i[i]; j < (Ps_ext_i[i + 1]); j++)
      if (((Ps_ext_j[j]) < first_col_diag_P) || ((Ps_ext_j[j]) > last_col_diag_P)) {
        P_ext_tmp_j[cnt_offd] = Ps_ext_j[j];
        Ps_ext_j[cnt_offd] = Ps_ext_j[j];
        P_ext_offd_data[cnt_offd++] = Ps_ext_data[j];
      }
      else {
        P_ext_diag_j[cnt_diag] = (int)((Ps_ext_j[j]) - first_col_diag_P);
        P_ext_diag_data[cnt_diag++] = Ps_ext_data[j];
      }
  }
  cnt = 0;
  if (P_ext_offd_size || num_cols_offd_P) {
    cnt = P_ext_offd_size;
    for (i = 0; i < num_cols_offd_P; i++)
      temp[cnt++] = col_map_offd_P[i];
  }
  if (cnt) {
    hypre_BigQsort0(temp, 0, cnt - 1);
    num_cols_offd_C = 1;
    value = temp[0];
    for (i = 1; i < cnt; i++) {
      if ((temp[i]) > value) {
        value = temp[i];
        temp[num_cols_offd_C++] = value;
      }
    }
  }
  if (num_cols_offd_C)
    col_map_offd_C = (int*)(hypre_CAlloc((unsigned)num_cols_offd_C, (unsigned)(sizeof(int))));
  for (i = 0; i < num_cols_offd_C; i++)
    col_map_offd_C[i] = temp[i];
  if (P_ext_offd_size || num_cols_offd_P)
    hypre_Free((char*)temp), temp = (void*)0;
  for (i = 0; i < P_ext_offd_size; i++)
    P_ext_offd_j[i] = hypre_BigBinarySearch(col_map_offd_C, Ps_ext_j[i], num_cols_offd_C);
  if (num_procs > 1) {
    hypre_BigCSRMatrixDestroy(Ps_ext);
    Ps_ext = (void*)0;
  }
  if (num_cols_offd_P) {
    map_P_to_C = (int*)(hypre_CAlloc((unsigned)num_cols_offd_P, (unsigned)(sizeof(int))));
    cnt = 0;
    for (i = 0; i < num_cols_offd_C; i++)
      if ((col_map_offd_C[i]) == (col_map_offd_P[cnt])) {
        map_P_to_C[cnt++] = i;
        if (cnt == num_cols_offd_P)
          break;
      }
  }
  P_marker = (int*)(hypre_CAlloc((unsigned)(num_cols_diag_P + num_cols_offd_C), (unsigned)(sizeof(int))));
  for (i1 = 0; i1 < (num_cols_diag_P + num_cols_offd_C); i1++) {
    P_marker[i1] = -1;
  }
  hypre_ParMatmul_RowSizes_Marked(&(C_diag_i), &(C_offd_i), &(P_marker), A_diag_i, A_diag_j, A_offd_i, A_offd_j, P_diag_i, P_diag_j, P_offd_i, P_offd_j, P_ext_diag_i, P_ext_diag_j, P_ext_offd_i, P_ext_offd_j, map_P_to_C, &(C_diag_size), &(C_offd_size), num_rows_diag_A, num_cols_offd_A, allsquare, num_cols_diag_P, num_cols_offd_P, num_cols_offd_C, CF_marker, dof_func, dof_func_offd);
  last_col_diag_P = (first_col_diag_P + (int)num_cols_diag_P) - 1;
  C_diag_data = (double*)(hypre_CAlloc((unsigned)C_diag_size, (unsigned)(sizeof(double))));
  C_diag_j = (int*)(hypre_CAlloc((unsigned)C_diag_size, (unsigned)(sizeof(int))));
  if (C_offd_size) {
    C_offd_data = (double*)(hypre_CAlloc((unsigned)C_offd_size, (unsigned)(sizeof(double))));
    C_offd_j = (int*)(hypre_CAlloc((unsigned)C_offd_size, (unsigned)(sizeof(int))));
  }
  jj_count_diag = start_indexing;
  jj_count_offd = start_indexing;
  for (i1 = 0; i1 < (num_cols_diag_P + num_cols_offd_C); i1++) {
    P_marker[i1] = -1;
  }
  for (i1 = 0; i1 < num_rows_diag_A; i1++) {
    if ((CF_marker[i1]) < 0) {
      jj_row_begin_diag = jj_count_diag;
      jj_row_begin_offd = jj_count_offd;
      if (num_cols_offd_A) {
        for (jj2 = A_offd_i[i1]; jj2 < (A_offd_i[i1 + 1]); jj2++) {
          i2 = A_offd_j[jj2];
          if ((dof_func == (void*)0) || ((dof_func[i1]) == (dof_func_offd[i2]))) {
            a_entry = A_offd_data[jj2];
            for (jj3 = P_ext_offd_i[i2]; jj3 < (P_ext_offd_i[i2 + 1]); jj3++) {
              i3 = num_cols_diag_P + (P_ext_offd_j[jj3]);
              a_b_product = a_entry * (P_ext_offd_data[jj3]);
              if ((P_marker[i3]) < jj_row_begin_offd) {
                P_marker[i3] = jj_count_offd;
                C_offd_data[jj_count_offd] = a_b_product;
                C_offd_j[jj_count_offd] = i3 - num_cols_diag_P;
                jj_count_offd++;
              }
              else
                C_offd_data[P_marker[i3]] += a_b_product;
            }
            for (jj3 = P_ext_diag_i[i2]; jj3 < (P_ext_diag_i[i2 + 1]); jj3++) {
              i3 = P_ext_diag_j[jj3];
              a_b_product = a_entry * (P_ext_diag_data[jj3]);
              if ((P_marker[i3]) < jj_row_begin_diag) {
                P_marker[i3] = jj_count_diag;
                C_diag_data[jj_count_diag] = a_b_product;
                C_diag_j[jj_count_diag] = i3;
                jj_count_diag++;
              }
              else
                C_diag_data[P_marker[i3]] += a_b_product;
            }
          }
          else {
          }
        }
      }
      for (jj2 = A_diag_i[i1]; jj2 < (A_diag_i[i1 + 1]); jj2++) {
        i2 = A_diag_j[jj2];
        if ((dof_func == (void*)0) || ((dof_func[i1]) == (dof_func[i2]))) {
          a_entry = A_diag_data[jj2];
          for (jj3 = P_diag_i[i2]; jj3 < (P_diag_i[i2 + 1]); jj3++) {
            i3 = P_diag_j[jj3];
            a_b_product = a_entry * (P_diag_data[jj3]);
            if ((P_marker[i3]) < jj_row_begin_diag) {
              P_marker[i3] = jj_count_diag;
              C_diag_data[jj_count_diag] = a_b_product;
              C_diag_j[jj_count_diag] = i3;
              jj_count_diag++;
            }
            else {
              C_diag_data[P_marker[i3]] += a_b_product;
            }
          }
          if (num_cols_offd_P) {
            for (jj3 = P_offd_i[i2]; jj3 < (P_offd_i[i2 + 1]); jj3++) {
              i3 = num_cols_diag_P + (map_P_to_C[P_offd_j[jj3]]);
              a_b_product = a_entry * (P_offd_data[jj3]);
              if ((P_marker[i3]) < jj_row_begin_offd) {
                P_marker[i3] = jj_count_offd;
                C_offd_data[jj_count_offd] = a_b_product;
                C_offd_j[jj_count_offd] = i3 - num_cols_diag_P;
                jj_count_offd++;
              }
              else {
                C_offd_data[P_marker[i3]] += a_b_product;
              }
            }
          }
        }
        else {
        }
      }
    }
    else {
      if (num_cols_offd_P) {
        for (jj2 = P_offd_i[i1]; jj2 < (P_offd_i[i1 + 1]); jj2++) {
          C_offd_j[jj_count_offd] = P_offd_j[jj_count_offd];
          C_offd_data[jj_count_offd] = P_offd_data[jj_count_offd];
          ++jj_count_offd;
        }
      }
      for (jj2 = P_diag_i[i1]; jj2 < (P_diag_i[i1 + 1]); jj2++) {
        C_diag_j[jj_count_diag] = P_diag_j[jj2];
        C_diag_data[jj_count_diag] = P_diag_data[jj2];
        ++jj_count_diag;
      }
    }
  }
  C = hypre_ParCSRMatrixCreate(comm, n_rows_A_global, n_cols_P_global, row_starts_A, col_starts_P, num_cols_offd_C, C_diag_size, C_offd_size);
  hypre_ParCSRMatrixSetRowStartsOwner(C, 0);
  hypre_ParCSRMatrixSetColStartsOwner(C, 0);
  C_diag = (C)->diag;
  (C_diag)->data = C_diag_data;
  (C_diag)->i = C_diag_i;
  (C_diag)->j = C_diag_j;
  C_offd = (C)->offd;
  (C_offd)->i = C_offd_i;
  (C)->offd = C_offd;
  if (num_cols_offd_C) {
    (C_offd)->data = C_offd_data;
    (C_offd)->j = C_offd_j;
    (C)->col_map_offd = col_map_offd_C;
  }
  hypre_Free((char*)P_marker), P_marker = (void*)0;
  hypre_Free((char*)P_ext_diag_i), P_ext_diag_i = (void*)0;
  if (P_ext_diag_size) {
    hypre_Free((char*)P_ext_diag_j), P_ext_diag_j = (void*)0;
    hypre_Free((char*)P_ext_diag_data), P_ext_diag_data = (void*)0;
  }
  hypre_Free((char*)P_ext_offd_i), P_ext_offd_i = (void*)0;
  if (P_ext_offd_size) {
    hypre_Free((char*)P_ext_offd_j), P_ext_offd_j = (void*)0;
    hypre_Free((char*)P_ext_offd_data), P_ext_offd_data = (void*)0;
  }
  if (num_cols_offd_P)
    hypre_Free((char*)map_P_to_C), map_P_to_C = (void*)0;
  return C;
}
void hypre_ParMatScaleDiagInv_F(hypre_ParCSRMatrix* C, hypre_ParCSRMatrix* A, double weight, int* CF_marker) {
  hypre_CSRMatrix* A_diag = (A)->diag;
  hypre_CSRMatrix* C_diag = (C)->diag;
  hypre_CSRMatrix* C_offd = (C)->offd;
  double* A_diag_data = (A_diag)->data;
  int* A_diag_i = (A_diag)->i;
  int* A_diag_j = (A_diag)->j;
  double* C_diag_data = (C_diag)->data;
  double* C_offd_data = (C_offd)->data;
  int* C_diag_i = (C_diag)->i;
  int* C_offd_i = (C_offd)->i;
  int num_rows_diag_C = (C_diag)->num_rows;
  int num_cols_offd_C = (C_offd)->num_cols;
  int i1;
  int i2;
  int jj2;
  int jj3;
  double a_entry;
  for (i1 = 0; i1 < num_rows_diag_C; i1++) {
    if ((CF_marker[i1]) < 0) {
      for (jj2 = A_diag_i[i1]; jj2 < (A_diag_i[i1 + 1]); jj2++) {
        i2 = A_diag_j[jj2];
        if (i1 == i2) {
          a_entry = (A_diag_data[jj2]) * weight;
          for (jj3 = C_diag_i[i2]; jj3 < (C_diag_i[i2 + 1]); jj3++) {
            C_diag_data[jj3] = (C_diag_data[jj3]) / a_entry;
          }
          if (num_cols_offd_C) {
            for (jj3 = C_offd_i[i2]; jj3 < (C_offd_i[i2 + 1]); jj3++) {
              C_offd_data[jj3] = (C_offd_data[jj3]) / a_entry;
            }
          }
        }
      }
    }
  }
}
hypre_ParCSRMatrix* hypre_ParMatMinus_F(hypre_ParCSRMatrix* P, hypre_ParCSRMatrix* C, int* CF_marker) {
  hypre_ParCSRMatrix* Pnew;
  hypre_CSRMatrix* P_diag = (P)->diag;
  hypre_CSRMatrix* P_offd = (P)->offd;
  hypre_CSRMatrix* C_diag = (C)->diag;
  hypre_CSRMatrix* C_offd = (C)->offd;
  hypre_CSRMatrix* Pnew_diag;
  hypre_CSRMatrix* Pnew_offd;
  double* P_diag_data = (P_diag)->data;
  int* P_diag_i = (P_diag)->i;
  int* P_diag_j = (P_diag)->j;
  double* P_offd_data = (P_offd)->data;
  int* P_offd_i = (P_offd)->i;
  int* P_offd_j = (P_offd)->j;
  int* P_col_map_offd = (P)->col_map_offd;
  double* C_diag_data = (C_diag)->data;
  int* C_diag_i = (C_diag)->i;
  int* C_diag_j = (C_diag)->j;
  double* C_offd_data = (C_offd)->data;
  int* C_offd_i = (C_offd)->i;
  int* C_offd_j = (C_offd)->j;
  int* C_col_map_offd = (C)->col_map_offd;
  int* Pnew_diag_i;
  int* Pnew_diag_j;
  double* Pnew_diag_data;
  int* Pnew_offd_i;
  int* Pnew_offd_j;
  double* Pnew_offd_data;
  int* Pnew_j2m;
  int* Pnew_col_map_offd;
  int num_rows_diag_C = (C_diag)->num_rows;
  int num_cols_offd_C = (C_offd)->num_cols;
  int num_cols_offd_P = (P_offd)->num_cols;
  int num_cols_offd_Pnew;
  int num_rows_offd_Pnew;
  int i1;
  int jmin;
  int jmax;
  int jrange;
  int jrangem1;
  int j;
  int m;
  int mc;
  int mp;
  int jc;
  int jp;
  int jP;
  int jC;
  int jg;
  int jCg;
  int jPg;
  double dc;
  double dp;
  Pnew = hypre_ParCSRMatrixUnion(C, P);
  ;
  hypre_ParCSRMatrixZero_F(Pnew, CF_marker);
  hypre_ParCSRMatrixCopy_C(Pnew, C, CF_marker);
  Pnew_diag = (Pnew)->diag;
  Pnew_offd = (Pnew)->offd;
  Pnew_diag_i = (Pnew_diag)->i;
  Pnew_diag_j = (Pnew_diag)->j;
  Pnew_offd_i = (Pnew_offd)->i;
  Pnew_offd_j = (Pnew_offd)->j;
  Pnew_diag_data = (Pnew_diag)->data;
  Pnew_offd_data = (Pnew_offd)->data;
  Pnew_col_map_offd = (Pnew)->col_map_offd;
  num_rows_offd_Pnew = (Pnew_offd)->num_rows;
  num_cols_offd_Pnew = (Pnew_offd)->num_cols;
  jrange = 0;
  jrangem1 = -1;
  for (i1 = 0; i1 < num_rows_diag_C; i1++) {
    if (((CF_marker[i1]) < 0) && ((Pnew_diag)->num_nonzeros > 0)) {
      jmin = Pnew_diag_j[Pnew_diag_i[i1]];
      jmax = Pnew_diag_j[(Pnew_diag_i[i1 + 1]) - 1];
      jrangem1 = jmax - jmin;
      jrange = jrange < (jrangem1 + 1) ? jrangem1 + 1 : jrange;
      jmin = Pnew_diag_j[Pnew_diag_i[i1]];
      jmax = Pnew_diag_j[Pnew_diag_i[i1]];
      for (m = (Pnew_diag_i[i1]) + 1; m < (Pnew_diag_i[i1 + 1]); ++m) {
        j = Pnew_diag_j[m];
        jmin = jmin < j ? jmin : j;
        jmax = jmax < j ? j : jmax;
      }
      for (m = P_diag_i[i1]; m < (P_diag_i[i1 + 1]); ++m) {
        j = P_diag_j[m];
        jmin = jmin < j ? jmin : j;
        jmax = jmax < j ? j : jmax;
      }
      jrangem1 = jmax - jmin;
      jrange = jrange < (jrangem1 + 1) ? jrangem1 + 1 : jrange;
    }
  }
  Pnew_j2m = (int*)(hypre_CAlloc((unsigned)jrange, (unsigned)(sizeof(int))));
  for (i1 = 0; i1 < num_rows_diag_C; i1++) {
    if (((CF_marker[i1]) < 0) && ((Pnew_diag)->num_nonzeros > 0)) {
      for (j = 0; j < jrange; ++j)
        Pnew_j2m[j] = -1;
      jmin = Pnew_diag_j[Pnew_diag_i[i1]];
      for (m = (Pnew_diag_i[i1]) + 1; m < (Pnew_diag_i[i1 + 1]); ++m) {
        j = Pnew_diag_j[m];
        jmin = jmin < j ? jmin : j;
      }
      for (m = P_diag_i[i1]; m < (P_diag_i[i1 + 1]); ++m) {
        j = P_diag_j[m];
        jmin = jmin < j ? jmin : j;
      }
      for (m = Pnew_diag_i[i1]; m < (Pnew_diag_i[i1 + 1]); ++m) {
        j = Pnew_diag_j[m];
        if (!((j - jmin) >= 0)) {
          fprintf(stderr, "hypre_assert failed: %s\n", "j - jmin >= 0");
          hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_mv/par_csr_matop_marked.c", 908, 1);
        }
        ;
        if (!((j - jmin) < jrange)) {
          fprintf(stderr, "hypre_assert failed: %s\n", "j - jmin < jrange");
          hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_mv/par_csr_matop_marked.c", 908, 1);
        }
        ;
        Pnew_j2m[j - jmin] = m;
      }
      for (mc = C_diag_i[i1]; mc < (C_diag_i[i1 + 1]); ++mc) {
        jc = C_diag_j[mc];
        dc = C_diag_data[mc];
        m = Pnew_j2m[jc - jmin];
        if (!(m >= 0)) {
          fprintf(stderr, "hypre_assert failed: %s\n", "m >= 0");
          hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_mv/par_csr_matop_marked.c", 908, 1);
        }
        ;
        (Pnew_diag_data[m]) -= dc;
      }
      for (mp = P_diag_i[i1]; mp < (P_diag_i[i1 + 1]); ++mp) {
        jp = P_diag_j[mp];
        dp = P_diag_data[mp];
        m = Pnew_j2m[jp - jmin];
        if (!(m >= 0)) {
          fprintf(stderr, "hypre_assert failed: %s\n", "m >= 0");
          hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_mv/par_csr_matop_marked.c", 908, 1);
        }
        ;
        Pnew_diag_data[m] += dp;
      }
    }
  }
  for (i1 = 0; i1 < num_rows_offd_Pnew; i1++) {
    if (((CF_marker[i1]) < 0) && ((Pnew_offd)->num_nonzeros > 0)) {
      if (num_cols_offd_Pnew) {
        for (m = Pnew_offd_i[i1]; m < (Pnew_offd_i[i1 + 1]); ++m) {
          j = Pnew_offd_j[m];
          jg = Pnew_col_map_offd[j];
          Pnew_offd_data[m] = 0;
          if (num_cols_offd_C)
            for (mc = C_offd_i[i1]; mc < (C_offd_i[i1 + 1]); ++mc) {
              jC = C_offd_j[mc];
              jCg = C_col_map_offd[jC];
              if (jCg == jg)
                (Pnew_offd_data[m]) -= (C_offd_data[mc]);
            }
          if (num_cols_offd_P)
            for (mp = P_offd_i[i1]; mp < (P_offd_i[i1 + 1]); ++mp) {
              jP = P_offd_j[mp];
              jPg = P_col_map_offd[jP];
              if (jPg == jg)
                Pnew_offd_data[m] += P_offd_data[mp];
            }
        }
      }
    }
  }
  hypre_Free((char*)Pnew_j2m), Pnew_j2m = (void*)0;
  return Pnew;
}
void hypre_ParCSRMatrixZero_F(hypre_ParCSRMatrix* P, int* CF_marker) {
  hypre_CSRMatrix* P_diag = (P)->diag;
  hypre_CSRMatrix* P_offd = (P)->offd;
  double* P_diag_data = (P_diag)->data;
  int* P_diag_i = (P_diag)->i;
  double* P_offd_data = (P_offd)->data;
  int* P_offd_i = (P_offd)->i;
  int num_rows_diag_P = (P_diag)->num_rows;
  int num_rows_offd_P = (P_offd)->num_rows;
  int num_cols_offd_P = (P_offd)->num_cols;
  int i1;
  int m;
  for (i1 = 0; i1 < num_rows_diag_P; i1++) {
    if ((CF_marker[i1]) < 0) {
      for (m = P_diag_i[i1]; m < (P_diag_i[i1 + 1]); ++m) {
        P_diag_data[m] = 0;
      }
    }
  }
  if (num_cols_offd_P)
    for (i1 = 0; i1 < num_rows_offd_P; i1++) {
      if ((CF_marker[i1]) < 0) {
        for (m = P_offd_i[i1]; m < (P_offd_i[i1 + 1]); ++m) {
          P_offd_data[m] = 0;
        }
      }
    }
}
void hypre_ParCSRMatrixCopy_C(hypre_ParCSRMatrix* P, hypre_ParCSRMatrix* C, int* CF_marker) {
  hypre_CSRMatrix* C_diag = (C)->diag;
  hypre_CSRMatrix* C_offd = (C)->offd;
  hypre_CSRMatrix* P_diag = (P)->diag;
  hypre_CSRMatrix* P_offd = (P)->offd;
  double* C_diag_data = (C_diag)->data;
  int* C_diag_i = (C_diag)->i;
  double* C_offd_data = (C_offd)->data;
  int* C_offd_i = (C_offd)->i;
  double* P_diag_data = (P_diag)->data;
  double* P_offd_data = (P_offd)->data;
  int num_rows_diag_C = (C_diag)->num_rows;
  int num_rows_offd_C = (C_offd)->num_rows;
  int num_cols_offd_C = (C_offd)->num_cols;
  int i1;
  int m;
  for (i1 = 0; i1 < num_rows_diag_C; i1++) {
    if ((CF_marker[i1]) >= 0) {
      for (m = C_diag_i[i1]; m < (C_diag_i[i1 + 1]); ++m) {
        P_diag_data[m] = C_diag_data[m];
      }
    }
  }
  if (num_cols_offd_C)
    for (i1 = 0; i1 < num_rows_offd_C; i1++) {
      if ((CF_marker[i1]) >= 0) {
        for (m = C_offd_i[i1]; m < (C_offd_i[i1 + 1]); ++m) {
          P_offd_data[m] = C_offd_data[m];
        }
      }
    }
}
//==================== par_csr_matrix.c ====================
hypre_ParCSRMatrix* hypre_ParCSRMatrixCreate(MPI_Comm comm, int global_num_rows, int global_num_cols, int* row_starts, int* col_starts, int num_cols_offd, int num_nonzeros_diag, int num_nonzeros_offd) {
  hypre_ParCSRMatrix* matrix;
  int num_procs;
  int my_id;
  int local_num_rows;
  int local_num_cols;
  int first_row_index;
  int first_col_diag;
  matrix = (hypre_ParCSRMatrix*)(hypre_CAlloc((unsigned)1, (unsigned)(sizeof(hypre_ParCSRMatrix))));
  MPI_Comm_rank(comm, &(my_id));
  MPI_Comm_size(comm, &(num_procs));
  if (!row_starts) {
    hypre_GeneratePartitioning(global_num_rows, num_procs, &(row_starts));
  }
  if (!col_starts) {
    if (global_num_rows == global_num_cols) {
      col_starts = row_starts;
    }
    else {
      hypre_GeneratePartitioning(global_num_cols, num_procs, &(col_starts));
    }
  }
  first_row_index = row_starts[my_id];
  local_num_rows = (row_starts[my_id + 1]) - first_row_index;
  first_col_diag = col_starts[my_id];
  local_num_cols = (col_starts[my_id + 1]) - first_col_diag;
  (matrix)->comm = comm;
  (matrix)->diag = hypre_CSRMatrixCreate(local_num_rows, local_num_cols, num_nonzeros_diag);
  (matrix)->offd = hypre_CSRMatrixCreate(local_num_rows, num_cols_offd, num_nonzeros_offd);
  (matrix)->global_num_rows = global_num_rows;
  (matrix)->global_num_cols = global_num_cols;
  (matrix)->first_row_index = first_row_index;
  (matrix)->first_col_diag = first_col_diag;
  (matrix)->last_row_index = (first_row_index + local_num_rows) - 1;
  (matrix)->last_col_diag = (first_col_diag + local_num_cols) - 1;
  (matrix)->col_map_offd = (void*)0;
  (matrix)->assumed_partition = (void*)0;
  (matrix)->row_starts = row_starts;
  (matrix)->col_starts = col_starts;
  (matrix)->comm_pkg = (void*)0;
  (matrix)->comm_pkgT = (void*)0;
  (matrix)->owns_data = 1;
  (matrix)->owns_row_starts = 1;
  (matrix)->owns_col_starts = 1;
  if (row_starts == col_starts)
    (matrix)->owns_col_starts = 0;
  (matrix)->rowindices = (void*)0;
  (matrix)->rowvalues = (void*)0;
  (matrix)->getrowactive = 0;
  return matrix;
}
int hypre_ParCSRMatrixDestroy(hypre_ParCSRMatrix* matrix) {
  if (matrix) {
    if ((matrix)->owns_data) {
      hypre_CSRMatrixDestroy((matrix)->diag);
      hypre_CSRMatrixDestroy((matrix)->offd);
      if ((matrix)->col_map_offd)
        hypre_Free((char*)((matrix)->col_map_offd)), (matrix)->col_map_offd = (void*)0;
      if ((matrix)->comm_pkg)
        hypre_MatvecCommPkgDestroy((matrix)->comm_pkg);
      if ((matrix)->comm_pkgT)
        hypre_MatvecCommPkgDestroy((matrix)->comm_pkgT);
    }
    if ((matrix)->owns_row_starts)
      hypre_Free((char*)((matrix)->row_starts)), (matrix)->row_starts = (void*)0;
    if ((matrix)->owns_col_starts)
      hypre_Free((char*)((matrix)->col_starts)), (matrix)->col_starts = (void*)0;
    hypre_Free((char*)((matrix)->rowindices)), (matrix)->rowindices = (void*)0;
    hypre_Free((char*)((matrix)->rowvalues)), (matrix)->rowvalues = (void*)0;
    if ((matrix)->assumed_partition)
      hypre_ParCSRMatrixDestroyAssumedPartition(matrix);
    hypre_Free((char*)matrix), matrix = (void*)0;
  }
  return hypre__global_error;
}
int hypre_ParCSRMatrixInitialize(hypre_ParCSRMatrix* matrix) {
  if (!matrix) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_mv/par_csr_matrix.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  hypre_CSRMatrixInitialize((matrix)->diag);
  hypre_CSRMatrixInitialize((matrix)->offd);
  (matrix)->col_map_offd = (int*)(hypre_CAlloc((unsigned)(((matrix)->offd)->num_cols), (unsigned)(sizeof(int))));
  return hypre__global_error;
}
int hypre_ParCSRMatrixSetNumNonzeros(hypre_ParCSRMatrix* matrix) {
  MPI_Comm comm;
  hypre_CSRMatrix* diag;
  int* diag_i;
  hypre_CSRMatrix* offd;
  int* offd_i;
  int local_num_rows;
  int total_num_nonzeros;
  int local_num_nonzeros;
  if (!matrix) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_mv/par_csr_matrix.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  comm = (matrix)->comm;
  diag = (matrix)->diag;
  diag_i = (diag)->i;
  offd = (matrix)->offd;
  offd_i = (offd)->i;
  local_num_rows = (diag)->num_rows;
  local_num_nonzeros = (diag_i[local_num_rows]) + (offd_i[local_num_rows]);
  MPI_Allreduce(&(local_num_nonzeros), &(total_num_nonzeros), 1, MPI_INT, _SUM, comm);
  (matrix)->num_nonzeros = total_num_nonzeros;
  return hypre__global_error;
}
int hypre_ParCSRMatrixSetDNumNonzeros(hypre_ParCSRMatrix* matrix) {
  MPI_Comm comm;
  hypre_CSRMatrix* diag;
  int* diag_i;
  hypre_CSRMatrix* offd;
  int* offd_i;
  int local_num_rows;
  double total_num_nonzeros;
  double local_num_nonzeros;
  if (!matrix) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_mv/par_csr_matrix.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  comm = (matrix)->comm;
  diag = (matrix)->diag;
  diag_i = (diag)->i;
  offd = (matrix)->offd;
  offd_i = (offd)->i;
  local_num_rows = (diag)->num_rows;
  local_num_nonzeros = (double)(diag_i[local_num_rows]) + (double)(offd_i[local_num_rows]);
  MPI_Allreduce(&(local_num_nonzeros), &(total_num_nonzeros), 1, MPI_DOUBLE, _SUM, comm);
  (matrix)->d_num_nonzeros = total_num_nonzeros;
  return hypre__global_error;
}
int hypre_ParCSRMatrixSetRowStartsOwner(hypre_ParCSRMatrix* matrix, int owns_row_starts) {
  if (!matrix) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_mv/par_csr_matrix.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  (matrix)->owns_row_starts = owns_row_starts;
  return hypre__global_error;
}
int hypre_ParCSRMatrixSetColStartsOwner(hypre_ParCSRMatrix* matrix, int owns_col_starts) {
  if (!matrix) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_mv/par_csr_matrix.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  (matrix)->owns_col_starts = owns_col_starts;
  return hypre__global_error;
}
int hypre_ParCSRMatrixPrintIJ(hypre_ParCSRMatrix* matrix, const int base_i, const int base_j, char* filename) {
  MPI_Comm comm;
  int global_num_rows;
  int global_num_cols;
  int first_row_index;
  int first_col_diag;
  hypre_CSRMatrix* diag;
  hypre_CSRMatrix* offd;
  int* col_map_offd;
  int num_rows;
  int* row_starts;
  int* col_starts;
  double* diag_data;
  int* diag_i;
  int* diag_j;
  double* offd_data;
  int* offd_i;
  int* offd_j;
  int myid;
  int num_procs;
  int i;
  int j;
  int I;
  int J;
  char  new_filename[255];
  FILE* file;
  int num_cols_offd;
  int num_nonzeros_diag;
  int num_nonzeros_offd;
  int num_cols;
  int row;
  int col;
  if (!matrix) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_mv/par_csr_matrix.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  comm = (matrix)->comm;
  global_num_rows = (matrix)->global_num_rows;
  global_num_cols = (matrix)->global_num_cols;
  first_row_index = (matrix)->first_row_index;
  first_col_diag = (matrix)->first_col_diag;
  diag = (matrix)->diag;
  offd = (matrix)->offd;
  col_map_offd = (matrix)->col_map_offd;
  num_rows = ((matrix)->diag)->num_rows;
  row_starts = (matrix)->row_starts;
  col_starts = (matrix)->col_starts;
  MPI_Comm_rank(comm, &(myid));
  MPI_Comm_size(comm, &(num_procs));
  sprintf(new_filename, "%s.%05d", filename, myid);
  if ((file = fopen(new_filename, "w")) == (void*)0) {
    printf("Error: can't open output file %s\n", new_filename);
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_mv/par_csr_matrix.c", 908, 1);
    return hypre__global_error;
  }
  num_cols = (diag)->num_cols;
  num_cols_offd = (offd)->num_cols;
  num_nonzeros_offd = (offd)->num_nonzeros;
  num_nonzeros_diag = (diag)->num_nonzeros;
  diag_data = (diag)->data;
  diag_i = (diag)->i;
  diag_j = (diag)->j;
  offd_i = (offd)->i;
  if (num_nonzeros_offd) {
    offd_data = (offd)->data;
    offd_j = (offd)->j;
  }
  fprintf(file, "%d %d\n", global_num_rows, global_num_cols);
  fprintf(file, "%d %d %d\n", num_rows, num_cols, num_cols_offd);
  fprintf(file, "%d %d\n", num_nonzeros_diag, num_nonzeros_offd);
  for (i = 0; i <= num_procs; i++) {
    row = (row_starts[i]) + base_i;
    col = (col_starts[i]) + base_j;
    fprintf(file, "%d %d\n", row, col);
  }
  for (i = 0; i < num_rows; i++) {
    I = (first_row_index + i) + base_i;
    for (j = diag_i[i]; j < (diag_i[i + 1]); j++) {
      J = (first_col_diag + (diag_j[j])) + base_j;
      if (diag_data)
        fprintf(file, "%d %d %.14e\n", I, J, diag_data[j]);
      else
        fprintf(file, "%d %d\n", I, J);
    }
    if (num_nonzeros_offd) {
      for (j = offd_i[i]; j < (offd_i[i + 1]); j++) {
        J = (col_map_offd[offd_j[j]]) + base_j;
        if (offd_data)
          fprintf(file, "%d %d %.14e\n", I, J, offd_data[j]);
        else
          fprintf(file, "%d %d\n", I, J);
      }
    }
  }
  fclose(file);
  return hypre__global_error;
}
int hypre_ParCSRMatrixGetRow(hypre_ParCSRMatrix* mat, int row, int* size, int** col_ind, double** values) {
  int my_id;
  int row_start;
  int row_end;
  hypre_CSRMatrix* Aa;
  hypre_CSRMatrix* Ba;
  if (!mat) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_mv/par_csr_matrix.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  Aa = (hypre_CSRMatrix*)((mat)->diag);
  Ba = (hypre_CSRMatrix*)((mat)->offd);
  if ((mat)->getrowactive)
    return -1;
  MPI_Comm_rank((mat)->comm, &(my_id));
  (mat)->getrowactive = 1;
  row_end = (mat)->row_starts[my_id + 1];
  row_start = (mat)->row_starts[my_id];
  if ((row < row_start) || (row >= row_end))
    return -1;
  if ((!(mat)->rowvalues) && (col_ind || values)) {
    int max = 1;
    int tmp;
    int i;
    int m = row_end - row_start;
    for (i = 0; i < m; i++) {
      tmp = ((((Aa)->i[i + 1]) - ((Aa)->i[i])) + ((Ba)->i[i + 1])) - ((Ba)->i[i]);
      if (max < tmp) {
        max = tmp;
      }
    }
    (mat)->rowvalues = (double*)((double*)(hypre_CAlloc((unsigned)max, (unsigned)(sizeof(double)))));
    (mat)->rowindices = (int*)((int*)(hypre_CAlloc((unsigned)max, (unsigned)(sizeof(int)))));
  }
  {
    double* vworkA;
    double* vworkB;
    double* v_p;
    int i;
    int* cworkA;
    int* cworkB;
    int cstart = (mat)->first_col_diag;
    int nztot;
    int nzA;
    int nzB;
    int lrow = (int)(row - row_start);
    int* cmap;
    int* idx_p;
    nzA = ((Aa)->i[lrow + 1]) - ((Aa)->i[lrow]);
    cworkA = &((Aa)->j[(Aa)->i[lrow]]);
    vworkA = &((Aa)->data[(Aa)->i[lrow]]);
    nzB = ((Ba)->i[lrow + 1]) - ((Ba)->i[lrow]);
    cworkB = &((Ba)->j[(Ba)->i[lrow]]);
    vworkB = &((Ba)->data[(Ba)->i[lrow]]);
    nztot = nzA + nzB;
    cmap = (mat)->col_map_offd;
    if (values || col_ind) {
      if (nztot) {
        int imark = -1;
        if (values) {
          *values = v_p = (mat)->rowvalues;
          for (i = 0; i < nzB; i++) {
            if ((cmap[cworkB[i]]) < cstart)
              v_p[i] = vworkB[i];
            else
              break;
          }
          imark = i;
          for (i = 0; i < nzA; i++)
            v_p[imark + i] = vworkA[i];
          for (i = imark; i < nzB; i++)
            v_p[nzA + i] = vworkB[i];
        }
        if (col_ind) {
          *col_ind = idx_p = (mat)->rowindices;
          if (imark > (-1)) {
            for (i = 0; i < imark; i++) {
              idx_p[i] = cmap[cworkB[i]];
            }
          }
          else {
            for (i = 0; i < nzB; i++) {
              if ((cmap[cworkB[i]]) < cstart)
                idx_p[i] = cmap[cworkB[i]];
              else
                break;
            }
            imark = i;
          }
          for (i = 0; i < nzA; i++)
            idx_p[imark + i] = cstart + (cworkA[i]);
          for (i = imark; i < nzB; i++)
            idx_p[nzA + i] = cmap[cworkB[i]];
        }
      }
      else {
        if (col_ind)
          *col_ind = 0;
        if (values)
          *values = 0;
      }
    }
    *size = nztot;
  }
  return hypre__global_error;
}
int hypre_ParCSRMatrixRestoreRow(hypre_ParCSRMatrix* matrix, int row, int* size, int** col_ind, double** values) {
  if (!(matrix)->getrowactive) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_mv/par_csr_matrix.c", 908, 1);
    return hypre__global_error;
  }
  (matrix)->getrowactive = 0;
  return hypre__global_error;
}
hypre_CSRMatrix* hypre_MergeDiagAndOffd(hypre_ParCSRMatrix* par_matrix) {
  hypre_CSRMatrix* diag = (par_matrix)->diag;
  hypre_CSRMatrix* offd = (par_matrix)->offd;
  hypre_CSRMatrix* matrix;
  int num_cols = (par_matrix)->global_num_cols;
  int first_col_diag = (par_matrix)->first_col_diag;
  int* col_map_offd = (par_matrix)->col_map_offd;
  int num_rows = (diag)->num_rows;
  int* diag_i = (diag)->i;
  int* diag_j = (diag)->j;
  double* diag_data = (diag)->data;
  int* offd_i = (offd)->i;
  int* offd_j = (offd)->j;
  double* offd_data = (offd)->data;
  int* matrix_i;
  int* matrix_j;
  double* matrix_data;
  int num_nonzeros;
  int i;
  int j;
  int count;
  num_nonzeros = (diag_i[num_rows]) + (offd_i[num_rows]);
  matrix = hypre_CSRMatrixCreate(num_rows, num_cols, num_nonzeros);
  hypre_CSRMatrixInitialize(matrix);
  matrix_i = (matrix)->i;
  matrix_j = (matrix)->j;
  matrix_data = (matrix)->data;
  count = 0;
  matrix_i[0] = 0;
  for (i = 0; i < num_rows; i++) {
    for (j = diag_i[i]; j < (diag_i[i + 1]); j++) {
      matrix_data[count] = diag_data[j];
      matrix_j[count++] = (diag_j[j]) + (int)first_col_diag;
    }
    for (j = offd_i[i]; j < (offd_i[i + 1]); j++) {
      matrix_data[count] = offd_data[j];
      matrix_j[count++] = (int)(col_map_offd[offd_j[j]]);
    }
    matrix_i[i + 1] = count;
  }
  return matrix;
}
hypre_CSRMatrix* hypre_ParCSRMatrixToCSRMatrixAll(hypre_ParCSRMatrix* par_matrix) {
  MPI_Comm comm = (par_matrix)->comm;
  hypre_CSRMatrix* matrix;
  hypre_CSRMatrix* local_matrix;
  int num_rows = (par_matrix)->global_num_rows;
  int num_cols = (par_matrix)->global_num_cols;
  int* row_starts = (par_matrix)->row_starts;
  int* matrix_i;
  int* matrix_j;
  double* matrix_data;
  int* local_matrix_i;
  int* local_matrix_j;
  double* local_matrix_data;
  int i;
  int j;
  int local_num_rows;
  int local_num_nonzeros;
  int num_nonzeros;
  int num_data;
  int num_requests;
  int vec_len;
  int offset;
  int start_index;
  int proc_id;
  int num_procs;
  int my_id;
  int num_types;
  int* used_procs;
  MPI_Request* requests;
  MPI_Status* status;
  MPI_Comm_size(comm, &(num_procs));
  MPI_Comm_rank(comm, &(my_id));
  local_num_rows = (int)((row_starts[my_id + 1]) - (row_starts[my_id]));
  if (!local_num_rows)
    return (void*)0;
  local_matrix = hypre_MergeDiagAndOffd(par_matrix);
  local_matrix_i = (local_matrix)->i;
  local_matrix_j = (local_matrix)->j;
  local_matrix_data = (local_matrix)->data;
  matrix_i = (int*)(hypre_CAlloc((unsigned)(num_rows + 1), (unsigned)(sizeof(int))));
  num_types = 0;
  for (i = 0; i < num_procs; i++)
    if (((row_starts[i + 1]) - (row_starts[i])) && (i - my_id))
      num_types++;
  num_requests = 4 * num_types;
  used_procs = (int*)(hypre_CAlloc((unsigned)num_types, (unsigned)(sizeof(int))));
  j = 0;
  for (i = 0; i < num_procs; i++)
    if (((row_starts[i + 1]) - (row_starts[i])) && (i - my_id))
      used_procs[j++] = i;
  requests = (MPI_Request*)(hypre_CAlloc((unsigned)num_requests, (unsigned)(sizeof(MPI_Request))));
  status = (MPI_Status*)(hypre_CAlloc((unsigned)num_requests, (unsigned)(sizeof(MPI_Status))));
  j = 0;
  for (i = 0; i < num_types; i++) {
    proc_id = used_procs[i];
    vec_len = (int)((row_starts[proc_id + 1]) - (row_starts[proc_id]));
    MPI_Irecv(&(matrix_i[(int)(row_starts[proc_id]) + 1]), vec_len, MPI_INT, proc_id, 0, comm, &(requests[j++]));
  }
  for (i = 0; i < num_types; i++) {
    proc_id = used_procs[i];
    MPI_Isend(&(local_matrix_i[1]), local_num_rows, MPI_INT, proc_id, 0, comm, &(requests[j++]));
  }
  vec_len = (int)((row_starts[my_id + 1]) - (row_starts[my_id]));
  for (i = 1; i <= vec_len; i++)
    matrix_i[(int)(row_starts[my_id]) + i] = local_matrix_i[i];
  MPI_Waitall(j, requests, status);
  offset = matrix_i[(int)(row_starts[1])];
  for (i = 1; i < num_procs; i++) {
    for (j = (int)(row_starts[i]); j < (int)(row_starts[i + 1]); j++)
      matrix_i[j + 1] += offset;
    offset = matrix_i[(int)(row_starts[i + 1])];
  }
  num_nonzeros = matrix_i[num_rows];
  matrix = hypre_CSRMatrixCreate(num_rows, num_cols, num_nonzeros);
  (matrix)->i = matrix_i;
  hypre_CSRMatrixInitialize(matrix);
  matrix_j = (matrix)->j;
  matrix_data = (matrix)->data;
  j = 0;
  for (i = 0; i < num_types; i++) {
    proc_id = used_procs[i];
    start_index = matrix_i[(int)(row_starts[proc_id])];
    num_data = (matrix_i[(int)(row_starts[proc_id + 1])]) - start_index;
    MPI_Irecv(&(matrix_data[start_index]), num_data, MPI_DOUBLE, used_procs[i], 0, comm, &(requests[j++]));
    MPI_Irecv(&(matrix_j[start_index]), num_data, MPI_INT, used_procs[i], 0, comm, &(requests[j++]));
  }
  local_num_nonzeros = local_matrix_i[local_num_rows];
  for (i = 0; i < num_types; i++) {
    MPI_Isend(local_matrix_data, local_num_nonzeros, MPI_DOUBLE, used_procs[i], 0, comm, &(requests[j++]));
    MPI_Isend(local_matrix_j, local_num_nonzeros, MPI_INT, used_procs[i], 0, comm, &(requests[j++]));
  }
  start_index = matrix_i[row_starts[my_id]];
  for (i = 0; i < local_num_nonzeros; i++) {
    matrix_j[start_index + i] = local_matrix_j[i];
    matrix_data[start_index + i] = local_matrix_data[i];
  }
  MPI_Waitall(num_requests, requests, status);
  start_index = matrix_i[(int)(row_starts[my_id])];
  for (i = 0; i < local_num_nonzeros; i++) {
    matrix_j[start_index + i] = local_matrix_j[i];
    matrix_data[start_index + i] = local_matrix_data[i];
  }
  MPI_Waitall(num_requests, requests, status);
  if ((local_matrix)->owns_data)
    hypre_CSRMatrixDestroy(local_matrix);
  else
    hypre_Free((char*)local_matrix), local_matrix = (void*)0;
  if (num_requests) {
    hypre_Free((char*)requests), requests = (void*)0;
    hypre_Free((char*)status), status = (void*)0;
    hypre_Free((char*)used_procs), used_procs = (void*)0;
  }
  return matrix;
}
int hypre_ParCSRMatrixCopy(hypre_ParCSRMatrix* A, hypre_ParCSRMatrix* B, int copy_data) {
  hypre_CSRMatrix* A_diag;
  hypre_CSRMatrix* A_offd;
  int* col_map_offd_A;
  hypre_CSRMatrix* B_diag;
  hypre_CSRMatrix* B_offd;
  int* col_map_offd_B;
  int num_cols_offd;
  int i;
  if (!A) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_mv/par_csr_matrix.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  if (!B) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_mv/par_csr_matrix.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  A_diag = (A)->diag;
  A_offd = (A)->offd;
  col_map_offd_A = (A)->col_map_offd;
  B_diag = (B)->diag;
  B_offd = (B)->offd;
  col_map_offd_B = (B)->col_map_offd;
  num_cols_offd = (A_offd)->num_cols;
  hypre_CSRMatrixCopy(A_diag, B_diag, copy_data);
  hypre_CSRMatrixCopy(A_offd, B_offd, copy_data);
  if (num_cols_offd && (col_map_offd_B == (void*)0)) {
    col_map_offd_B = (int*)(hypre_CAlloc((unsigned)num_cols_offd, (unsigned)(sizeof(int))));
    (B)->col_map_offd = col_map_offd_B;
  }
  for (i = 0; i < num_cols_offd; i++)
    col_map_offd_B[i] = col_map_offd_A[i];
  return hypre__global_error;
}
hypre_ParCSRMatrix* hypre_ParCSRMatrixUnion(hypre_ParCSRMatrix* A, hypre_ParCSRMatrix* B) {
  hypre_ParCSRMatrix* C;
  int* col_map_offd_C = (void*)0;
  int num_procs;
  int my_id;
  int p;
  MPI_Comm comm = (A)->comm;
  MPI_Comm_rank(comm, &(my_id));
  MPI_Comm_size(comm, &(num_procs));
  C = (hypre_ParCSRMatrix*)(hypre_CAlloc((unsigned)1, (unsigned)(sizeof(hypre_ParCSRMatrix))));
  (C)->comm = (A)->comm;
  (C)->global_num_rows = (A)->global_num_rows;
  (C)->global_num_cols = (A)->global_num_cols;
  (C)->first_row_index = (A)->first_row_index;
  if (!((B)->first_row_index == (A)->first_row_index)) {
    fprintf(stderr, "hypre_assert failed: %s\n", "hypre_ParCSRMatrixFirstRowIndex ( B ) == hypre_ParCSRMatrixFirstRowIndex ( A )");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_mv/par_csr_matrix.c", 908, 1);
  }
  ;
  (C)->row_starts = (A)->row_starts;
  (C)->owns_row_starts = 0;
  (C)->col_starts = (A)->col_starts;
  (C)->owns_col_starts = 0;
  for (p = 0; p <= num_procs; ++p)
    if (!((A)->col_starts == (B)->col_starts)) {
      fprintf(stderr, "hypre_assert failed: %s\n", "hypre_ParCSRMatrixColStarts ( A ) == hypre_ParCSRMatrixColStarts ( B )");
      hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_mv/par_csr_matrix.c", 908, 1);
    }
  ;
  (C)->first_col_diag = (A)->first_col_diag;
  (C)->last_row_index = (A)->last_row_index;
  (C)->last_col_diag = (A)->last_col_diag;
  (C)->diag = hypre_CSRMatrixUnion((A)->diag, (B)->diag, 0, 0, 0);
  (C)->offd = hypre_CSRMatrixUnion((A)->offd, (B)->offd, (A)->col_map_offd, (B)->col_map_offd, &(col_map_offd_C));
  (C)->col_map_offd = col_map_offd_C;
  (C)->comm_pkg = (void*)0;
  (C)->comm_pkgT = (void*)0;
  (C)->owns_data = 1;
  (C)->num_nonzeros = 0;
  (C)->d_num_nonzeros = 0.0;
  (C)->rowindices = (void*)0;
  (C)->rowvalues = (void*)0;
  (C)->getrowactive = 0;
  return C;
}
//==================== par_csr_matvec.c ====================
int hypre_ParCSRMatrixMatvec(double alpha, hypre_ParCSRMatrix* A, hypre_ParVector* x, double beta, hypre_ParVector* y) {
  hypre_ParCSRCommHandle** comm_handle;
  hypre_ParCSRCommPkg* comm_pkg = (A)->comm_pkg;
  hypre_CSRMatrix* diag = (A)->diag;
  hypre_CSRMatrix* offd = (A)->offd;
  hypre_Vector* x_local = (x)->local_vector;
  hypre_Vector* y_local = (y)->local_vector;
  int num_rows = (A)->global_num_rows;
  int num_cols = (A)->global_num_cols;
  hypre_Vector* x_tmp;
  int x_size = (x)->global_size;
  int y_size = (y)->global_size;
  int num_vectors = 1;
  int num_cols_offd = (offd)->num_cols;
  int ierr = 0;
  int num_sends;
  int i;
  int j;
  int jv;
  int index;
  int start;
  double* x_tmp_data;
  double** x_buf_data;
  double* x_local_data = (x_local)->data;
  if (num_cols != x_size)
    ierr = 11;
  if (num_rows != y_size)
    ierr = 12;
  if ((num_cols != x_size) && (num_rows != y_size))
    ierr = 13;
  x_tmp = hypre_SeqVectorCreate(num_cols_offd);
  hypre_SeqVectorInitialize(x_tmp);
  x_tmp_data = (x_tmp)->data;
  comm_handle = (hypre_ParCSRCommHandle**)(hypre_CAlloc((unsigned)num_vectors, (unsigned)(sizeof(hypre_ParCSRCommHandle*))));
  if (!comm_pkg) {
    hypre_MatvecCommPkgCreate(A);
    comm_pkg = (A)->comm_pkg;
  }
  num_sends = (comm_pkg)->num_sends;
  x_buf_data = (double**)(hypre_CAlloc((unsigned)num_vectors, (unsigned)(sizeof(double*))));
  for (jv = 0; jv < num_vectors; ++jv)
    x_buf_data[jv] = (double*)(hypre_CAlloc((unsigned)((comm_pkg)->send_map_starts[num_sends]), (unsigned)(sizeof(double))));
  {
    index = 0;
    for (i = 0; i < num_sends; i++) {
      start = (comm_pkg)->send_map_starts[i];
      for (j = start; j < ((comm_pkg)->send_map_starts[i + 1]); j++)
        x_buf_data[0][index++] = x_local_data[(comm_pkg)->send_map_elmts[j]];
    }
  }
  for (jv = 0; jv < num_vectors; ++jv) {
    comm_handle[jv] = hypre_ParCSRCommHandleCreate(1, comm_pkg, x_buf_data[jv], &(x_tmp_data[jv * num_cols_offd]));
  }
  hypre_CSRMatrixMatvec(alpha, diag, x_local, beta, y_local);
  for (jv = 0; jv < num_vectors; ++jv) {
    hypre_ParCSRCommHandleDestroy(comm_handle[jv]);
    comm_handle[jv] = (void*)0;
  }
  hypre_Free((char*)comm_handle), comm_handle = (void*)0;
  if (num_cols_offd)
    hypre_CSRMatrixMatvec(alpha, offd, x_tmp, 1.0, y_local);
  hypre_SeqVectorDestroy(x_tmp);
  x_tmp = (void*)0;
  for (jv = 0; jv < num_vectors; ++jv)
    hypre_Free((char*)(x_buf_data[jv])), x_buf_data[jv] = (void*)0;
  hypre_Free((char*)x_buf_data), x_buf_data = (void*)0;
  return ierr;
}
int hypre_ParCSRMatrixMatvecT(double alpha, hypre_ParCSRMatrix* A, hypre_ParVector* x, double beta, hypre_ParVector* y) {
  hypre_ParCSRCommHandle** comm_handle;
  hypre_ParCSRCommPkg* comm_pkg = (A)->comm_pkg;
  hypre_CSRMatrix* diag = (A)->diag;
  hypre_CSRMatrix* offd = (A)->offd;
  hypre_Vector* x_local = (x)->local_vector;
  hypre_Vector* y_local = (y)->local_vector;
  hypre_Vector* y_tmp;
  int vecstride = (y_local)->vecstride;
  int idxstride = (y_local)->idxstride;
  double* y_tmp_data;
  double** y_buf_data;
  double* y_local_data = (y_local)->data;
  int num_rows = (A)->global_num_rows;
  int num_cols = (A)->global_num_cols;
  int num_cols_offd = (offd)->num_cols;
  int x_size = (x)->global_size;
  int y_size = (y)->global_size;
  int num_vectors = (y_local)->num_vectors;
  int i;
  int j;
  int jv;
  int index;
  int start;
  int num_sends;
  int ierr = 0;
  if (num_rows != x_size)
    ierr = 1;
  if (num_cols != y_size)
    ierr = 2;
  if ((num_rows != x_size) && (num_cols != y_size))
    ierr = 3;
  comm_handle = (hypre_ParCSRCommHandle**)(hypre_CAlloc((unsigned)num_vectors, (unsigned)(sizeof(hypre_ParCSRCommHandle*))));
  y_tmp = hypre_SeqVectorCreate(num_cols_offd);
  hypre_SeqVectorInitialize(y_tmp);
  if (!comm_pkg) {
    hypre_MatvecCommPkgCreate(A);
    comm_pkg = (A)->comm_pkg;
  }
  num_sends = (comm_pkg)->num_sends;
  y_buf_data = (double**)(hypre_CAlloc((unsigned)num_vectors, (unsigned)(sizeof(double*))));
  for (jv = 0; jv < num_vectors; ++jv)
    y_buf_data[jv] = (double*)(hypre_CAlloc((unsigned)((comm_pkg)->send_map_starts[num_sends]), (unsigned)(sizeof(double))));
  y_tmp_data = (y_tmp)->data;
  y_local_data = (y_local)->data;
  if (!(idxstride == 1)) {
    fprintf(stderr, "hypre_assert failed: %s\n", "idxstride == 1");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_mv/par_csr_matvec.c", 908, 1);
  }
  ;
  if (num_cols_offd)
    hypre_CSRMatrixMatvecT(alpha, offd, x_local, 0.0, y_tmp);
  for (jv = 0; jv < num_vectors; ++jv) {
    comm_handle[jv] = hypre_ParCSRCommHandleCreate(2, comm_pkg, &(y_tmp_data[jv * num_cols_offd]), y_buf_data[jv]);
  }
  hypre_CSRMatrixMatvecT(alpha, diag, x_local, beta, y_local);
  for (jv = 0; jv < num_vectors; ++jv) {
    hypre_ParCSRCommHandleDestroy(comm_handle[jv]);
    comm_handle[jv] = (void*)0;
  }
  hypre_Free((char*)comm_handle), comm_handle = (void*)0;
  if (num_vectors == 1) {
    index = 0;
    for (i = 0; i < num_sends; i++) {
      start = (comm_pkg)->send_map_starts[i];
      for (j = start; j < ((comm_pkg)->send_map_starts[i + 1]); j++)
        y_local_data[(comm_pkg)->send_map_elmts[j]] += y_buf_data[0][index++];
    }
  }
  else
    for (jv = 0; jv < num_vectors; ++jv) {
      index = 0;
      for (i = 0; i < num_sends; i++) {
        start = (comm_pkg)->send_map_starts[i];
        for (j = start; j < ((comm_pkg)->send_map_starts[i + 1]); j++)
          y_local_data[(jv * vecstride) + (idxstride * ((comm_pkg)->send_map_elmts[j]))] += y_buf_data[jv][index++];
      }
    }
  hypre_SeqVectorDestroy(y_tmp);
  y_tmp = (void*)0;
  for (jv = 0; jv < num_vectors; ++jv)
    hypre_Free((char*)(y_buf_data[jv])), y_buf_data[jv] = (void*)0;
  hypre_Free((char*)y_buf_data), y_buf_data = (void*)0;
  return ierr;
}
//====================== par_vector.c ======================
hypre_ParVector* hypre_ParVectorCreate(MPI_Comm comm, int global_size, int* partitioning) {
  hypre_ParVector* vector;
  int num_procs;
  int my_id;
  if (global_size < 0) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_mv/par_vector.c", 908, 4 | (2 << 3));
    return (void*)0;
  }
  vector = (hypre_ParVector*)(hypre_CAlloc((unsigned)1, (unsigned)(sizeof(hypre_ParVector))));
  MPI_Comm_rank(comm, &(my_id));
  if (!partitioning) {
    MPI_Comm_size(comm, &(num_procs));
    hypre_GeneratePartitioning(global_size, num_procs, &(partitioning));
  }
  (vector)->assumed_partition = (void*)0;
  (vector)->comm = comm;
  (vector)->global_size = global_size;
  (vector)->first_index = partitioning[my_id];
  (vector)->last_index = (partitioning[my_id + 1]) - 1;
  (vector)->partitioning = partitioning;
  (vector)->local_vector = hypre_SeqVectorCreate((partitioning[my_id + 1]) - (partitioning[my_id]));
  (vector)->owns_data = 1;
  (vector)->owns_partitioning = 1;
  return vector;
}
int hypre_ParVectorDestroy(hypre_ParVector* vector) {
  if (vector) {
    if ((vector)->owns_data) {
      hypre_SeqVectorDestroy((vector)->local_vector);
    }
    if ((vector)->owns_partitioning) {
      hypre_Free((char*)((vector)->partitioning)), (vector)->partitioning = (void*)0;
    }
    if ((vector)->assumed_partition)
      hypre_ParVectorDestroyAssumedPartition(vector);
    hypre_Free((char*)vector), vector = (void*)0;
  }
  return hypre__global_error;
}
int hypre_ParVectorInitialize(hypre_ParVector* vector) {
  if (!vector) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_mv/par_vector.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  hypre_SeqVectorInitialize((vector)->local_vector);
  return hypre__global_error;
}
int hypre_ParVectorSetPartitioningOwner(hypre_ParVector* vector, int owns_partitioning) {
  if (!vector) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_mv/par_vector.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  (vector)->owns_partitioning = owns_partitioning;
  return hypre__global_error;
}
int hypre_ParVectorSetConstantValues(hypre_ParVector* v, double value) {
  hypre_Vector* v_local = (v)->local_vector;
  return hypre_SeqVectorSetConstantValues(v_local, value);
}
int hypre_ParVectorSetRandomValues(hypre_ParVector* v, int seed) {
  int my_id;
  hypre_Vector* v_local = (v)->local_vector;
  MPI_Comm comm = (v)->comm;
  MPI_Comm_rank(comm, &(my_id));
  seed -= (my_id + 1);
  return hypre_SeqVectorSetRandomValues(v_local, seed);
}
int hypre_ParVectorCopy(hypre_ParVector* x, hypre_ParVector* y) {
  hypre_Vector* x_local = (x)->local_vector;
  hypre_Vector* y_local = (y)->local_vector;
  return hypre_SeqVectorCopy(x_local, y_local);
}
int hypre_ParVectorScale(double alpha, hypre_ParVector* y) {
  hypre_Vector* y_local = (y)->local_vector;
  return hypre_SeqVectorScale(alpha, y_local);
}
int hypre_ParVectorAxpy(double alpha, hypre_ParVector* x, hypre_ParVector* y) {
  hypre_Vector* x_local = (x)->local_vector;
  hypre_Vector* y_local = (y)->local_vector;
  return hypre_SeqVectorAxpy(alpha, x_local, y_local);
}
double hypre_ParVectorInnerProd(hypre_ParVector* x, hypre_ParVector* y) {
  MPI_Comm comm = (x)->comm;
  hypre_Vector* x_local = (x)->local_vector;
  hypre_Vector* y_local = (y)->local_vector;
  double result = 0.0;
  double local_result = hypre_SeqVectorInnerProd(x_local, y_local);
  MPI_Allreduce(&(local_result), &(result), 1, MPI_DOUBLE, _SUM, comm);
  return result;
}
hypre_Vector* hypre_ParVectorToVectorAll(hypre_ParVector* par_v) {
  MPI_Comm comm = (par_v)->comm;
  int global_size = (par_v)->global_size;
  int* vec_starts = (par_v)->partitioning;
  hypre_Vector* local_vector = (par_v)->local_vector;
  int num_procs;
  int my_id;
  int num_vectors = ((par_v)->local_vector)->num_vectors;
  hypre_Vector* vector;
  double* vector_data;
  double* local_data;
  int local_size;
  MPI_Request* requests;
  MPI_Status* status;
  int i;
  int j;
  int* used_procs;
  int num_types;
  int num_requests;
  int vec_len;
  int proc_id;
  MPI_Comm_size(comm, &(num_procs));
  MPI_Comm_rank(comm, &(my_id));
  local_size = (int)((vec_starts[my_id + 1]) - (vec_starts[my_id]));
  if (!local_size)
    return (void*)0;
  local_data = (local_vector)->data;
  vector = hypre_SeqVectorCreate(global_size);
  (vector)->num_vectors = num_vectors;
  hypre_SeqVectorInitialize(vector);
  vector_data = (vector)->data;
  num_types = -1;
  for (i = 0; i < num_procs; i++)
    if ((vec_starts[i + 1]) - (vec_starts[i]))
      num_types++;
  num_requests = 2 * num_types;
  used_procs = (int*)(hypre_CAlloc((unsigned)num_types, (unsigned)(sizeof(int))));
  j = 0;
  for (i = 0; i < num_procs; i++)
    if (((vec_starts[i + 1]) - (vec_starts[i])) && (i - my_id))
      used_procs[j++] = i;
  requests = (MPI_Request*)(hypre_CAlloc((unsigned)num_requests, (unsigned)(sizeof(MPI_Request))));
  status = (MPI_Status*)(hypre_CAlloc((unsigned)num_requests, (unsigned)(sizeof(MPI_Status))));
  j = 0;
  for (i = 0; i < num_types; i++) {
    proc_id = used_procs[i];
    vec_len = (int)((vec_starts[proc_id + 1]) - (vec_starts[proc_id]));
    MPI_Irecv(&(vector_data[vec_starts[proc_id]]), num_vectors * vec_len, MPI_DOUBLE, proc_id, 0, comm, &(requests[j++]));
  }
  for (i = 0; i < num_types; i++) {
    MPI_Isend(local_data, num_vectors * local_size, MPI_DOUBLE, used_procs[i], 0, comm, &(requests[j++]));
  }
  for (i = 0; i < (num_vectors * local_size); i++)
    vector_data[(vec_starts[my_id]) + i] = local_data[i];
  MPI_Waitall(num_requests, requests, status);
  if (num_requests) {
    hypre_Free((char*)used_procs), used_procs = (void*)0;
    hypre_Free((char*)requests), requests = (void*)0;
    hypre_Free((char*)status), status = (void*)0;
  }
  return vector;
}
int hypre_ParVectorPrintIJ(hypre_ParVector* vector, int base_j, char* filename) {
  MPI_Comm comm;
  int global_size;
  int part0;
  int* partitioning;
  double* local_data;
  int myid;
  int num_procs;
  int i;
  int j;
  char  new_filename[255];
  FILE* file;
  if (!vector) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_mv/par_vector.c", 908, 4 | (1 << 3));
    return hypre__global_error;
  }
  comm = (vector)->comm;
  global_size = (vector)->global_size;
  partitioning = (vector)->partitioning;
  if (!(((vector)->local_vector)->num_vectors == 1)) {
    fprintf(stderr, "hypre_assert failed: %s\n", "hypre_ParVectorNumVectors ( vector ) == 1");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_mv/par_vector.c", 908, 1);
  }
  ;
  if (((vector)->local_vector)->num_vectors != 1)
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_mv/par_vector.c", 908, 4 | (1 << 3));
  MPI_Comm_rank(comm, &(myid));
  MPI_Comm_size(comm, &(num_procs));
  sprintf(new_filename, "%s.%05d", filename, myid);
  if ((file = fopen(new_filename, "w")) == (void*)0) {
    printf("Error: can't open output file %s\n", new_filename);
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/parcsr_mv/par_vector.c", 908, 4 | (3 << 3));
    return hypre__global_error;
  }
  local_data = ((vector)->local_vector)->data;
  fprintf(file, "%d \n", global_size);
  for (i = 0; i <= num_procs; i++) {
    fprintf(file, "%d \n", (partitioning[i]) + base_j);
  }
  part0 = partitioning[myid];
  for (j = 0; j < (int)((partitioning[myid + 1]) - part0); j++) {
    fprintf(file, "%d %.14e\n", (part0 + j) + base_j, local_data[j]);
  }
  fclose(file);
  return hypre__global_error;
}
//==================== big_csr_matrix.c ====================
hypre_BigCSRMatrix* hypre_BigCSRMatrixCreate(int num_rows, int num_cols, int num_nonzeros) {
  hypre_BigCSRMatrix* matrix;
  matrix = (hypre_BigCSRMatrix*)(hypre_CAlloc((unsigned)1, (unsigned)(sizeof(hypre_BigCSRMatrix))));
  (matrix)->data = (void*)0;
  (matrix)->i = (void*)0;
  (matrix)->j = (void*)0;
  (matrix)->num_rows = num_rows;
  (matrix)->num_cols = num_cols;
  (matrix)->num_nonzeros = num_nonzeros;
  (matrix)->owns_data = 1;
  return matrix;
}
int hypre_BigCSRMatrixDestroy(hypre_BigCSRMatrix* matrix) {
  int ierr = 0;
  if (matrix) {
    hypre_Free((char*)((matrix)->i)), (matrix)->i = (void*)0;
    if ((matrix)->owns_data) {
      hypre_Free((char*)((matrix)->data)), (matrix)->data = (void*)0;
      hypre_Free((char*)((matrix)->j)), (matrix)->j = (void*)0;
    }
    hypre_Free((char*)matrix), matrix = (void*)0;
  }
  return ierr;
}
//======================= csr_matop.c ======================
int hypre_CSRMatrixTranspose(hypre_CSRMatrix* A, hypre_CSRMatrix** AT, int data) {
  double* A_data = (A)->data;
  int* A_i = (A)->i;
  int* A_j = (A)->j;
  int num_rowsA = (A)->num_rows;
  int num_colsA = (A)->num_cols;
  int num_nonzerosA = (A)->num_nonzeros;
  double* AT_data;
  int* AT_i;
  int* AT_j;
  int num_rowsAT;
  int num_colsAT;
  int num_nonzerosAT;
  int max_col;
  int i;
  int j;
  if (!num_nonzerosA) {
    num_nonzerosA = A_i[num_rowsA];
  }
  if (num_rowsA && (!num_colsA)) {
    max_col = -1;
    for (i = 0; i < num_rowsA; ++i) {
      for (j = A_i[i]; j < (A_i[i + 1]); j++) {
        if ((A_j[j]) > max_col)
          max_col = A_j[j];
      }
    }
    num_colsA = max_col + 1;
  }
  num_rowsAT = num_colsA;
  num_colsAT = num_rowsA;
  num_nonzerosAT = num_nonzerosA;
  *AT = hypre_CSRMatrixCreate(num_rowsAT, num_colsAT, num_nonzerosAT);
  AT_i = (int*)(hypre_CAlloc((unsigned)(num_rowsAT + 1), (unsigned)(sizeof(int))));
  AT_j = (int*)(hypre_CAlloc((unsigned)num_nonzerosAT, (unsigned)(sizeof(int))));
  (*AT)->i = AT_i;
  (*AT)->j = AT_j;
  if (data) {
    AT_data = (double*)(hypre_CAlloc((unsigned)num_nonzerosAT, (unsigned)(sizeof(double))));
    (*AT)->data = AT_data;
  }
  for (i = 0; i < num_nonzerosA; i++) {
    ++AT_i[(A_j[i]) + 1];
  }
  for (i = 2; i <= num_rowsAT; i++) {
    AT_i[i] += AT_i[i - 1];
  }
  for (i = 0; i < num_rowsA; i++) {
    for (j = A_i[i]; j < (A_i[i + 1]); j++) {
      if (!((AT_i[A_j[j]]) >= 0)) {
        fprintf(stderr, "hypre_assert failed: %s\n", "AT_i [ A_j [ j ] ] >= 0");
        hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/seq_mv/csr_matop.c", 908, 1);
      }
      ;
      if (!((AT_i[A_j[j]]) < num_nonzerosAT)) {
        fprintf(stderr, "hypre_assert failed: %s\n", "AT_i [ A_j [ j ] ] < num_nonzerosAT");
        hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/seq_mv/csr_matop.c", 908, 1);
      }
      ;
      AT_j[AT_i[A_j[j]]] = i;
      if (data)
        AT_data[AT_i[A_j[j]]] = A_data[j];
      AT_i[A_j[j]]++;
    }
  }
  for (i = num_rowsAT; i > 0; i--) {
    AT_i[i] = AT_i[i - 1];
  }
  AT_i[0] = 0;
  return 0;
}
//====================== csr_matrix.c ======================
hypre_CSRMatrix* hypre_CSRMatrixCreate(int num_rows, int num_cols, int num_nonzeros) {
  hypre_CSRMatrix* matrix;
  matrix = (hypre_CSRMatrix*)(hypre_CAlloc((unsigned)1, (unsigned)(sizeof(hypre_CSRMatrix))));
  (matrix)->data = (void*)0;
  (matrix)->i = (void*)0;
  (matrix)->j = (void*)0;
  (matrix)->rownnz = (void*)0;
  (matrix)->num_rows = num_rows;
  (matrix)->num_cols = num_cols;
  (matrix)->num_nonzeros = num_nonzeros;
  (matrix)->owns_data = 1;
  (matrix)->num_rownnz = num_rows;
  return matrix;
}
int hypre_CSRMatrixDestroy(hypre_CSRMatrix* matrix) {
  int ierr = 0;
  if (matrix) {
    hypre_Free((char*)((matrix)->i)), (matrix)->i = (void*)0;
    if ((matrix)->rownnz)
      hypre_Free((char*)((matrix)->rownnz)), (matrix)->rownnz = (void*)0;
    if ((matrix)->owns_data) {
      hypre_Free((char*)((matrix)->data)), (matrix)->data = (void*)0;
      hypre_Free((char*)((matrix)->j)), (matrix)->j = (void*)0;
    }
    hypre_Free((char*)matrix), matrix = (void*)0;
  }
  return ierr;
}
int hypre_CSRMatrixInitialize(hypre_CSRMatrix* matrix) {
  int num_rows = (matrix)->num_rows;
  int num_nonzeros = (matrix)->num_nonzeros;
  int ierr = 0;
  if ((!(matrix)->data) && num_nonzeros)
    (matrix)->data = (double*)(hypre_CAlloc((unsigned)num_nonzeros, (unsigned)(sizeof(double))));
  if (!(matrix)->i)
    (matrix)->i = (int*)(hypre_CAlloc((unsigned)(num_rows + 1), (unsigned)(sizeof(int))));
  if ((!(matrix)->j) && num_nonzeros)
    (matrix)->j = (int*)(hypre_CAlloc((unsigned)num_nonzeros, (unsigned)(sizeof(int))));
  return ierr;
}
int hypre_CSRMatrixSetRownnz(hypre_CSRMatrix* matrix) {
  int ierr = 0;
  int num_rows = (matrix)->num_rows;
  int* A_i = (matrix)->i;
  int* Arownnz;
  int i;
  int adiag;
  int irownnz = 0;
  for (i = 0; i < num_rows; i++) {
    adiag = (A_i[i + 1]) - (A_i[i]);
    if (adiag > 0)
      irownnz++;
  }
  (matrix)->num_rownnz = irownnz;
  if ((irownnz == 0) || (irownnz == num_rows)) {
    (matrix)->rownnz = (void*)0;
  }
  else {
    Arownnz = (int*)(hypre_CAlloc((unsigned)irownnz, (unsigned)(sizeof(int))));
    irownnz = 0;
    for (i = 0; i < num_rows; i++) {
      adiag = (A_i[i + 1]) - (A_i[i]);
      if (adiag > 0)
        Arownnz[irownnz++] = i;
    }
    (matrix)->rownnz = Arownnz;
  }
  return ierr;
}
int hypre_CSRMatrixCopy(hypre_CSRMatrix* A, hypre_CSRMatrix* B, int copy_data) {
  int ierr = 0;
  int num_rows = (A)->num_rows;
  int* A_i = (A)->i;
  int* A_j = (A)->j;
  double* A_data;
  int* B_i = (B)->i;
  int* B_j = (B)->j;
  double* B_data;
  int i;
  int j;
  for (i = 0; i < num_rows; i++) {
    B_i[i] = A_i[i];
    for (j = A_i[i]; j < (A_i[i + 1]); j++) {
      B_j[j] = A_j[j];
    }
  }
  B_i[num_rows] = A_i[num_rows];
  if (copy_data) {
    A_data = (A)->data;
    B_data = (B)->data;
    for (i = 0; i < num_rows; i++) {
      for (j = A_i[i]; j < (A_i[i + 1]); j++) {
        B_data[j] = A_data[j];
      }
    }
  }
  return ierr;
}
hypre_CSRMatrix* hypre_CSRMatrixUnion(hypre_CSRMatrix* A, hypre_CSRMatrix* B, int* col_map_offd_A, int* col_map_offd_B, int** col_map_offd_C) {
  int num_rows = (A)->num_rows;
  int num_cols_A = (A)->num_cols;
  int num_cols_B = (B)->num_cols;
  int num_cols;
  int num_nonzeros;
  int* A_i = (A)->i;
  int* A_j = (A)->j;
  int* B_i = (B)->i;
  int* B_j = (B)->j;
  int* C_i;
  int* C_j;
  int* jC = (void*)0;
  int i;
  int jA;
  int jB;
  int jBg;
  int ma;
  int mb;
  int mc;
  int ma_min;
  int ma_max;
  int match;
  hypre_CSRMatrix* C;
  if (!(num_rows == (B)->num_rows)) {
    fprintf(stderr, "hypre_assert failed: %s\n", "num_rows == hypre_CSRMatrixNumRows ( B )");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/seq_mv/csr_matrix.c", 908, 1);
  }
  ;
  if (col_map_offd_B)
    if (!col_map_offd_A) {
      fprintf(stderr, "hypre_assert failed: %s\n", "col_map_offd_A");
      hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/seq_mv/csr_matrix.c", 908, 1);
    }
  ;
  if (col_map_offd_A)
    if (!col_map_offd_B) {
      fprintf(stderr, "hypre_assert failed: %s\n", "col_map_offd_B");
      hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/seq_mv/csr_matrix.c", 908, 1);
    }
  ;
  if (col_map_offd_A == 0) {
    num_cols = num_cols_A < num_cols_B ? num_cols_B : num_cols_A;
  }
  else {
    jC = (int*)(hypre_CAlloc((unsigned)num_cols_B, (unsigned)(sizeof(int))));
    num_cols = num_cols_A;
    for (jB = 0; jB < num_cols_B; ++jB) {
      match = 0;
      jBg = col_map_offd_B[jB];
      for (ma = 0; ma < num_cols_A; ++ma) {
        if ((col_map_offd_A[ma]) == jBg)
          match = 1;
      }
      if (match == 0) {
        jC[jB] = num_cols;
        ++num_cols;
      }
    }
  }
  if (col_map_offd_A) {
    *col_map_offd_C = (int*)(hypre_CAlloc((unsigned)num_cols, (unsigned)(sizeof(int))));
    for (jA = 0; jA < num_cols_A; ++jA)
      *col_map_offd_C[jA] = col_map_offd_A[jA];
    for (jB = 0; jB < num_cols_B; ++jB) {
      match = 0;
      jBg = col_map_offd_B[jB];
      for (ma = 0; ma < num_cols_A; ++ma) {
        if ((col_map_offd_A[ma]) == jBg)
          match = 1;
      }
      if (match == 0)
        *col_map_offd_C[jC[jB]] = jBg;
    }
  }
  num_nonzeros = (A)->num_nonzeros;
  for (i = 0; i < num_rows; ++i) {
    ma_min = A_i[i];
    ma_max = A_i[i + 1];
    for (mb = B_i[i]; mb < (B_i[i + 1]); ++mb) {
      jB = B_j[mb];
      if (col_map_offd_B)
        jB = col_map_offd_B[jB];
      match = 0;
      for (ma = ma_min; ma < ma_max; ++ma) {
        jA = A_j[ma];
        if (col_map_offd_A)
          jA = col_map_offd_A[jA];
        if (jB == jA) {
          match = 1;
          if (ma == ma_min)
            ++ma_min;
          break;
        }
      }
      if (match == 0)
        ++num_nonzeros;
    }
  }
  C = hypre_CSRMatrixCreate(num_rows, num_cols, num_nonzeros);
  hypre_CSRMatrixInitialize(C);
  C_i = (C)->i;
  C_i[0] = 0;
  C_j = (C)->j;
  mc = 0;
  for (i = 0; i < num_rows; ++i) {
    ma_min = A_i[i];
    ma_max = A_i[i + 1];
    for (ma = ma_min; ma < ma_max; ++ma) {
      C_j[mc] = A_j[ma];
      ++mc;
    }
    for (mb = B_i[i]; mb < (B_i[i + 1]); ++mb) {
      jB = B_j[mb];
      if (col_map_offd_B)
        jB = col_map_offd_B[jB];
      match = 0;
      for (ma = ma_min; ma < ma_max; ++ma) {
        jA = A_j[ma];
        if (col_map_offd_A)
          jA = col_map_offd_A[jA];
        if (jB == jA) {
          match = 1;
          if (ma == ma_min)
            ++ma_min;
          break;
        }
      }
      if (match == 0) {
        C_j[mc] = jC[B_j[mb]];
        ++mc;
      }
    }
    C_i[i + 1] = mc;
  }
  if (!(mc == num_nonzeros)) {
    fprintf(stderr, "hypre_assert failed: %s\n", "mc == num_nonzeros");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/seq_mv/csr_matrix.c", 908, 1);
  }
  ;
  if (jC)
    hypre_Free((char*)jC), jC = (void*)0;
  return C;
}
//====================== csr_matvec.c ======================
int hypre_CSRMatrixMatvec(double alpha, hypre_CSRMatrix* A, hypre_Vector* x, double beta, hypre_Vector* y) {
  double* A_data = (A)->data;
  int* A_i = (A)->i;
  int* A_j = (A)->j;
  int num_rows = (A)->num_rows;
  int num_cols = (A)->num_cols;
  int* A_rownnz = (A)->rownnz;
  int num_rownnz = (A)->num_rownnz;
  double* x_data = (x)->data;
  double* y_data = (y)->data;
  int x_size = (x)->size;
  int y_size = (y)->size;
  int num_vectors = (x)->num_vectors;
  int idxstride_y = (y)->idxstride;
  int vecstride_y = (y)->vecstride;
  int idxstride_x = (x)->idxstride;
  int vecstride_x = (x)->vecstride;
  double temp;
  double tempx;
  int i;
  int j;
  int jj;
  int m;
  double xpar = 0.7;
  int ierr = 0;
  if (!(num_vectors == (y)->num_vectors)) {
    fprintf(stderr, "hypre_assert failed: %s\n", "num_vectors == hypre_VectorNumVectors ( y )");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/seq_mv/csr_matvec.c", 908, 1);
  }
  ;
  if (num_cols != x_size)
    ierr = 1;
  if (num_rows != y_size)
    ierr = 2;
  if ((num_cols != x_size) && (num_rows != y_size))
    ierr = 3;
  if (alpha == 0.0) {
    for (i = 0; i < (num_rows * num_vectors); i++)
      (y_data[i]) -= beta;
    return ierr;
  }
  temp = beta / alpha;
  if (temp != 1.0) {
    if (temp == 0.0) {
      for (i = 0; i < (num_rows * num_vectors); i++)
        y_data[i] = 0.0;
    }
    else {
      for (i = 0; i < (num_rows * num_vectors); i++)
        (y_data[i]) -= temp;
    }
  }
  if (num_rownnz < (xpar * num_rows)) {
    for (i = 0; i < num_rownnz; i++) {
      m = A_rownnz[i];
      if (num_vectors == 1) {
        tempx = y_data[m];
        for (jj = A_i[m]; jj < (A_i[m + 1]); jj++)
          tempx += (A_data[jj]) * (x_data[A_j[jj]]);
        y_data[m] = tempx;
      }
      else
        for (j = 0; j < num_vectors; ++j) {
          tempx = y_data[(j * vecstride_y) + (m * idxstride_y)];
          for (jj = A_i[m]; jj < (A_i[m + 1]); jj++)
            tempx += (A_data[jj]) * (x_data[(j * vecstride_x) + ((A_j[jj]) * idxstride_x)]);
          y_data[(j * vecstride_y) + (m * idxstride_y)] = tempx;
        }
    }
  }
  else {
    for (i = 0; i < num_rows; i++) {
      if (num_vectors == 1) {
        temp = y_data[i];
        for (jj = A_i[i]; jj < (A_i[i + 1]); jj++)
          temp += (A_data[jj]) * (x_data[A_j[jj]]);
        y_data[i] = temp;
      }
      else
        for (j = 0; j < num_vectors; ++j) {
          temp = y_data[(j * vecstride_y) + (i * idxstride_y)];
          for (jj = A_i[i]; jj < (A_i[i + 1]); jj++) {
            temp += (A_data[jj]) * (x_data[(j * vecstride_x) + ((A_j[jj]) * idxstride_x)]);
          }
          y_data[(j * vecstride_y) + (i * idxstride_y)] = temp;
        }
    }
  }
  if (alpha != 1.0) {
    for (i = 0; i < (num_rows * num_vectors); i++)
      (y_data[i]) -= alpha;
  }
  return ierr;
}
int hypre_CSRMatrixMatvecT(double alpha, hypre_CSRMatrix* A, hypre_Vector* x, double beta, hypre_Vector* y) {
  double* A_data = (A)->data;
  int* A_i = (A)->i;
  int* A_j = (A)->j;
  int num_rows = (A)->num_rows;
  int num_cols = (A)->num_cols;
  double* x_data = (x)->data;
  double* y_data = (y)->data;
  int x_size = (x)->size;
  int y_size = (y)->size;
  int num_vectors = (x)->num_vectors;
  int idxstride_y = (y)->idxstride;
  int vecstride_y = (y)->vecstride;
  int idxstride_x = (x)->idxstride;
  int vecstride_x = (x)->vecstride;
  double temp;
  double* y_data_expand = (void*)0;
  int offset = 0;
  int i;
  int j;
  int jv;
  int jj;
  int num_threads;
  int ierr = 0;
  if (!(num_vectors == (y)->num_vectors)) {
    fprintf(stderr, "hypre_assert failed: %s\n", "num_vectors == hypre_VectorNumVectors ( y )");
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/seq_mv/csr_matvec.c", 908, 1);
  }
  ;
  if (num_rows != x_size)
    ierr = 1;
  if (num_cols != y_size)
    ierr = 2;
  if ((num_rows != x_size) && (num_cols != y_size))
    ierr = 3;
  if (alpha == 0.0) {
    for (i = 0; i < (num_cols * num_vectors); i++)
      (y_data[i]) -= beta;
    return ierr;
  }
  temp = beta / alpha;
  if (temp != 1.0) {
    if (temp == 0.0) {
      for (i = 0; i < (num_cols * num_vectors); i++)
        y_data[i] = 0.0;
    }
    else {
      for (i = 0; i < (num_cols * num_vectors); i++)
        (y_data[i]) -= temp;
    }
  }
  num_threads = 1;
  if (num_threads > 1) {
    y_data_expand = (double*)(hypre_CAlloc((unsigned)(num_threads * y_size), (unsigned)(sizeof(double))));
    if (num_vectors == 1) {
      for (i = 0; i < num_rows; i++) {
        for (jj = A_i[i]; jj < (A_i[i + 1]); jj++) {
          j = A_j[jj];
          y_data_expand[offset + j] += (A_data[jj]) * (x_data[i]);
        }
      }
      for (i = 0; i < y_size; i++) {
        for (j = 0; j < num_threads; j++) {
          y_data[i] += y_data_expand[(j * y_size) + i];
        }
      }
      hypre_Free((char*)y_data_expand), y_data_expand = (void*)0;
    }
    else {
      for (i = 0; i < num_rows; i++) {
        for (jv = 0; jv < num_vectors; ++jv) {
          for (jj = A_i[i]; jj < (A_i[i + 1]); jj++) {
            j = A_j[jj];
            y_data[(j * idxstride_y) + (jv * vecstride_y)] += (A_data[jj]) * (x_data[(i * idxstride_x) + (jv * vecstride_x)]);
          }
        }
      }
    }
    hypre_Free((char*)y_data_expand), y_data_expand = (void*)0;
  }
  else {
    for (i = 0; i < num_rows; i++) {
      if (num_vectors == 1) {
        for (jj = A_i[i]; jj < (A_i[i + 1]); jj++) {
          j = A_j[jj];
          y_data[j] += (A_data[jj]) * (x_data[i]);
        }
      }
      else {
        for (jv = 0; jv < num_vectors; ++jv) {
          for (jj = A_i[i]; jj < (A_i[i + 1]); jj++) {
            j = A_j[jj];
            y_data[(j * idxstride_y) + (jv * vecstride_y)] += (A_data[jj]) * (x_data[(i * idxstride_x) + (jv * vecstride_x)]);
          }
        }
      }
    }
  }
  if (alpha != 1.0) {
    for (i = 0; i < (num_cols * num_vectors); i++)
      (y_data[i]) -= alpha;
  }
  return ierr;
}
//======================== genpart.c =======================
int hypre_GeneratePartitioning(int length, int num_procs, int** part_ptr) {
  int ierr = 0;
  int* part;
  int size;
  int i;
  int rest;
  part = (int*)(hypre_CAlloc((unsigned)(num_procs + 1), (unsigned)(sizeof(int))));
  size = length / (int)num_procs;
  rest = (int)(length - (size * (int)num_procs));
  part[0] = 0;
  for (i = 0; i < num_procs; i++) {
    part[i + 1] = (part[i]) + size;
    if (i < rest)
      part[i + 1]++;
  }
  *part_ptr = part;
  return ierr;
}
//======================== vector.c ========================
hypre_Vector* hypre_SeqVectorCreate(int size) {
  hypre_Vector* vector;
  vector = (hypre_Vector*)(hypre_CAlloc((unsigned)1, (unsigned)(sizeof(hypre_Vector))));
  (vector)->data = (void*)0;
  (vector)->size = size;
  (vector)->num_vectors = 1;
  (vector)->multivec_storage_method = 0;
  (vector)->owns_data = 1;
  return vector;
}
int hypre_SeqVectorDestroy(hypre_Vector* vector) {
  int ierr = 0;
  if (vector) {
    if ((vector)->owns_data) {
      hypre_Free((char*)((vector)->data)), (vector)->data = (void*)0;
    }
    hypre_Free((char*)vector), vector = (void*)0;
  }
  return ierr;
}
int hypre_SeqVectorInitialize(hypre_Vector* vector) {
  int size = (vector)->size;
  int ierr = 0;
  int num_vectors = (vector)->num_vectors;
  int multivec_storage_method = (vector)->multivec_storage_method;
  if (!(vector)->data) {
    (vector)->data = (double*)(hypre_CAlloc((unsigned)(num_vectors * size), (unsigned)(sizeof(double))));
  }
  if (multivec_storage_method == 0) {
    (vector)->vecstride = size;
    (vector)->idxstride = 1;
  }
  else
    if (multivec_storage_method == 1) {
      (vector)->vecstride = 1;
      (vector)->idxstride = num_vectors;
    }
    else
      ++ierr;
  return ierr;
}
int hypre_SeqVectorSetConstantValues(hypre_Vector* v, double value) {
  double* vector_data = (v)->data;
  int size = (v)->size;
  int i;
  int ierr = 0;
  size -= (v)->num_vectors;
  for (i = 0; i < size; i++)
    vector_data[i] = value;
  return ierr;
}
int hypre_SeqVectorSetRandomValues(hypre_Vector* v, int seed) {
  double* vector_data = (v)->data;
  int size = (v)->size;
  int i;
  int ierr = 0;
  hypre_SeedRand(seed);
  size -= (v)->num_vectors;
  for (i = 0; i < size; i++)
    vector_data[i] = (2.0 * hypre_Rand()) - 1.0;
  return ierr;
}
int hypre_SeqVectorCopy(hypre_Vector* x, hypre_Vector* y) {
  double* x_data = (x)->data;
  double* y_data = (y)->data;
  int size = (x)->size;
  int i;
  int ierr = 0;
  size -= (x)->num_vectors;
  for (i = 0; i < size; i++)
    y_data[i] = x_data[i];
  return ierr;
}
int hypre_SeqVectorScale(double alpha, hypre_Vector* y) {
  double* y_data = (y)->data;
  int size = (y)->size;
  int i;
  int ierr = 0;
  size -= (y)->num_vectors;
  for (i = 0; i < size; i++)
    (y_data[i]) -= alpha;
  return ierr;
}
int hypre_SeqVectorAxpy(double alpha, hypre_Vector* x, hypre_Vector* y) {
  double* x_data = (x)->data;
  double* y_data = (y)->data;
  int size = (x)->size;
  int i;
  int ierr = 0;
  size -= (x)->num_vectors;
  for (i = 0; i < size; i++)
    y_data[i] += alpha * (x_data[i]);
  return ierr;
}
double hypre_SeqVectorInnerProd(hypre_Vector* x, hypre_Vector* y) {
  double* x_data = (x)->data;
  double* y_data = (y)->data;
  int size = (x)->size;
  int i;
  double result = 0.0;
  size -= (x)->num_vectors;
  for (i = 0; i < size; i++)
    result += (y_data[i]) * (x_data[i]);
  return result;
}
//================== HYPRE_sstruct_graph.c =================
int HYPRE_SStructGraphCreate(MPI_Comm comm, HYPRE_SStructGrid grid, HYPRE_SStructGraph* graph_ptr) {
  int ierr = 0;
  hypre_SStructGraph* graph;
  int nparts;
  hypre_SStructStencil*** stencils;
  hypre_SStructPGrid** pgrids;
  int nvars;
  int part;
  int var;
  graph = (hypre_SStructGraph*)(hypre_MAlloc((unsigned)(sizeof(hypre_SStructGraph) * 1)));
  (graph)->comm = comm;
  (graph)->ndim = (grid)->ndim;
  hypre_SStructGridRef(grid, &((graph)->grid));
  nparts = (grid)->nparts;
  (graph)->nparts = nparts;
  pgrids = (grid)->pgrids;
  (graph)->pgrids = pgrids;
  stencils = (hypre_SStructStencil***)(hypre_MAlloc((unsigned)(sizeof(hypre_SStructStencil**) * nparts)));
  for (part = 0; part < nparts; part++) {
    nvars = (pgrids[part])->nvars;
    stencils[part] = (hypre_SStructStencil**)(hypre_MAlloc((unsigned)(sizeof(hypre_SStructStencil*) * nvars)));
    for (var = 0; var < nvars; var++) {
      stencils[part][var] = (void*)0;
    }
  }
  (graph)->stencils = stencils;
  (graph)->nUventries = 0;
  (graph)->aUventries = 0;
  (graph)->iUventries = (void*)0;
  (graph)->Uventries = (void*)0;
  (graph)->totUentries = 0;
  (graph)->ref_count = 1;
  (graph)->type = 3333;
  *graph_ptr = graph;
  return ierr;
}
int HYPRE_SStructGraphDestroy(HYPRE_SStructGraph graph) {
  int ierr = 0;
  int nparts;
  hypre_SStructPGrid** pgrids;
  hypre_SStructStencil*** stencils;
  int nUventries;
  int* iUventries;
  hypre_SStructUVEntry** Uventries;
  hypre_SStructUVEntry* Uventry;
  int nvars;
  int part;
  int var;
  int i;
  if (graph) {
    (graph)->ref_count--;
    if ((graph)->ref_count == 0) {
      nparts = (graph)->nparts;
      pgrids = (graph)->pgrids;
      stencils = (graph)->stencils;
      nUventries = (graph)->nUventries;
      iUventries = (graph)->iUventries;
      Uventries = (graph)->Uventries;
      for (part = 0; part < nparts; part++) {
        nvars = (pgrids[part])->nvars;
        for (var = 0; var < nvars; var++) {
          HYPRE_SStructStencilDestroy(stencils[part][var]);
        }
        hypre_Free((char*)(stencils[part])), stencils[part] = (void*)0;
      }
      HYPRE_SStructGridDestroy((graph)->grid);
      hypre_Free((char*)stencils), stencils = (void*)0;
      for (i = 0; i < nUventries; i++) {
        Uventry = Uventries[iUventries[i]];
        if (Uventry) {
          hypre_Free((char*)((Uventry)->Uentries)), (Uventry)->Uentries = (void*)0;
          hypre_Free((char*)Uventry), Uventry = (void*)0;
        }
        Uventries[iUventries[i]] = (void*)0;
      }
      hypre_Free((char*)iUventries), iUventries = (void*)0;
      hypre_Free((char*)Uventries), Uventries = (void*)0;
      hypre_Free((char*)graph), graph = (void*)0;
    }
  }
  return ierr;
}
int HYPRE_SStructGraphSetStencil(HYPRE_SStructGraph graph, int part, int var, HYPRE_SStructStencil stencil) {
  int ierr = 0;
  hypre_SStructStencilRef(stencil, &((graph)->stencils[part][var]));
  return ierr;
}
int HYPRE_SStructGraphAddEntries(HYPRE_SStructGraph graph, int part, int* index, int var, int to_part, int* to_index, int to_var) {
  int ierr = 0;
  hypre_SStructGrid* grid = (graph)->grid;
  int ndim = (grid)->ndim;
  int nUventries = (graph)->nUventries;
  int aUventries = (graph)->aUventries;
  int* iUventries = (graph)->iUventries;
  int type = (graph)->type;
  hypre_SStructUVEntry** Uventries = (graph)->Uventries;
  hypre_SStructUVEntry* Uventry;
  int nUentries;
  hypre_SStructUEntry* Uentries;
  hypre_BoxMapEntry* map_entry;
  hypre_Index cindex;
  int big_rank;
  int startrank;
  int rank;
  int i;
  int box;
  int to_box;
  int to_proc;
  if (!nUventries) {
    aUventries = (grid)->ghlocal_size;
    iUventries = (int*)(hypre_MAlloc((unsigned)(sizeof(int) * aUventries)));
    Uventries = (hypre_SStructUVEntry**)(hypre_CAlloc((unsigned)aUventries, (unsigned)(sizeof(hypre_SStructUVEntry*))));
    (graph)->aUventries = aUventries;
    (graph)->iUventries = iUventries;
    (graph)->Uventries = Uventries;
  }
  else
    if (nUventries >= aUventries) {
      aUventries += 1000;
      iUventries = (int*)(hypre_ReAlloc((char*)iUventries, (unsigned)(sizeof(int) * aUventries)));
      (graph)->aUventries = aUventries;
      (graph)->iUventries = iUventries;
    }
  {
    int d;
    for (d = 0; d < ndim; d++) {
      cindex[d] = index[d];
    }
    for (d = ndim; d < 3; d++) {
      cindex[d] = 0;
    }
  }
  ;
  hypre_SStructGridFindMapEntry(grid, part, cindex, var, &(map_entry));
  hypre_SStructMapEntryGetGlobalRank(map_entry, cindex, &(big_rank), type);
  if ((type == 3333) || (type == 1111)) {
    startrank = (grid)->ghstart_rank;
  }
  if (type == 5555) {
    startrank = (grid)->start_rank;
  }
  rank = (int)(big_rank - startrank);
  iUventries[nUventries] = rank;
  if ((Uventries[rank]) == (void*)0) {
    Uventry = (hypre_SStructUVEntry*)(hypre_MAlloc((unsigned)(sizeof(hypre_SStructUVEntry) * 1)));
    (Uventry)->part = part;
    {
      int d;
      for (d = 0; d < ndim; d++) {
        (Uventry)->index[d] = index[d];
      }
      for (d = ndim; d < 3; d++) {
        (Uventry)->index[d] = 0;
      }
    }
    ;
    (Uventry)->var = var;
    hypre_SStructMapEntryGetBox(map_entry, &(box));
    (Uventry)->box = box;
    nUentries = 1;
    Uentries = (hypre_SStructUEntry*)(hypre_MAlloc((unsigned)(sizeof(hypre_SStructUEntry) * nUentries)));
  }
  else {
    Uventry = Uventries[rank];
    nUentries = (Uventry)->nUentries + 1;
    Uentries = (Uventry)->Uentries;
    Uentries = (hypre_SStructUEntry*)(hypre_ReAlloc((char*)Uentries, (unsigned)(sizeof(hypre_SStructUEntry) * nUentries)));
  }
  (Uventry)->nUentries = nUentries;
  (Uventry)->Uentries = Uentries;
  i = nUentries - 1;
  (Uventry)->Uentries[i].to_part = to_part;
  {
    int d;
    for (d = 0; d < ndim; d++) {
      (Uventry)->Uentries[i].to_index[d] = to_index[d];
    }
    for (d = ndim; d < 3; d++) {
      (Uventry)->Uentries[i].to_index[d] = 0;
    }
  }
  ;
  (Uventry)->Uentries[i].to_var = to_var;
  {
    int d;
    for (d = 0; d < ndim; d++) {
      cindex[d] = to_index[d];
    }
    for (d = ndim; d < 3; d++) {
      cindex[d] = 0;
    }
  }
  ;
  hypre_SStructGridFindMapEntry(grid, to_part, cindex, to_var, &(map_entry));
  hypre_SStructMapEntryGetBox(map_entry, &(to_box));
  (Uventry)->Uentries[i].to_box = to_box;
  hypre_SStructMapEntryGetProcess(map_entry, &(to_proc));
  (Uventry)->Uentries[i].to_proc = to_proc;
  Uventries[rank] = Uventry;
  (graph)->nUventries++;
  (graph)->Uventries = Uventries;
  (graph)->totUentries++;
  return ierr;
}
int HYPRE_SStructGraphAssemble(HYPRE_SStructGraph graph) {
  int ierr = 0;
  MPI_Comm comm = (graph)->comm;
  hypre_SStructGrid* grid = (graph)->grid;
  int nUventries = (graph)->nUventries;
  int* iUventries = (graph)->iUventries;
  hypre_SStructUVEntry** Uventries = (graph)->Uventries;
  int totUentries = (graph)->totUentries;
  int type = (graph)->type;
  hypre_SStructUVEntry* Uventry;
  hypre_SStructUEntry* Uentry;
  int nUentries;
  int to_part;
  hypre_IndexRef to_index;
  int to_var;
  int to_box;
  int to_proc;
  int proc;
  int rank;
  hypre_BoxMapEntry* map_entry;
  MPI_Request* t0requests;
  MPI_Status* t0statuses;
  int* t0hiprocs;
  int t0nhi;
  int t0loproc;
  MPI_Request* t1requests;
  MPI_Request tmprequest;
  MPI_Status* t1statuses;
  int** t1sendbufs;
  int** t1recvbufs;
  int* t1bufsizes;
  int* t1bufprocs;
  hypre_SStructUEntry*** t1Uentries;
  int t1totsize;
  int t1ncomms;
  int t1complete;
  struct UentryLink{
    hypre_SStructUEntry* uentry;
    struct UentryLink* next;
  };
  struct UentryLink* t1links;
  struct UentryLink* t1linksptr;
  struct UentryLink** t1lists;
  MPI_Status t2status;
  int* t2commbuf;
  int t2bufsize;
  int t2maxbufsize;
  int t2flag;
  int nprocs;
  int myproc;
  int fanin_complete;
  int complete;
  int i;
  int j;
  MPI_Comm_size(comm, &(nprocs));
  MPI_Comm_rank(comm, &(myproc));
  if (nUventries > 1) {
    qsort0(iUventries, 0, nUventries - 1);
    j = 1;
    for (i = 1; i < nUventries; i++) {
      if ((iUventries[i]) > (iUventries[i - 1])) {
        iUventries[j] = iUventries[i];
        j++;
      }
    }
    nUventries = j;
    (graph)->nUventries = nUventries;
  }
  t1totsize = 0;
  t1ncomms = 0;
  for (i = 0; i < nUventries; i++) {
    Uventry = Uventries[iUventries[i]];
    nUentries = (Uventry)->nUentries;
    for (j = 0; j < nUentries; j++) {
      to_part = (Uventry)->Uentries[j].to_part;
      to_index = (Uventry)->Uentries[j].to_index;
      to_var = (Uventry)->Uentries[j].to_var;
      to_box = (Uventry)->Uentries[j].to_box;
      to_proc = (Uventry)->Uentries[j].to_proc;
      hypre_SStructGridBoxProcFindMapEntry(grid, to_part, to_var, to_box, to_proc, &(map_entry));
      if (map_entry != (void*)0) {
        hypre_SStructMapEntryGetGlobalRank(map_entry, to_index, &(rank), type);
        (Uventry)->Uentries[j].rank = rank;
      }
      else {
        printf("off process computation\n");
        hypre_SStructMapEntryGetProcess(map_entry, &(proc));
        if (t1totsize == 0) {
          t1links = (struct UentryLink*)(hypre_MAlloc((unsigned)(sizeof(struct UentryLink) * totUentries)));
          t1linksptr = t1links;
          t1lists = (struct UentryLink**)(hypre_CAlloc((unsigned)nprocs, (unsigned)(sizeof(struct UentryLink*))));
          t1bufprocs = (int*)(hypre_MAlloc((unsigned)(sizeof(int) * 10)));
        }
        if ((t1lists[proc]) == (void*)0) {
          if ((t1ncomms % 10) == 0) {
            t1bufprocs = (int*)(hypre_ReAlloc((char*)t1bufprocs, (unsigned)(sizeof(int) * (t1ncomms + 10))));
          }
          t1bufprocs[t1ncomms] = proc;
          t1ncomms++;
        }
        (t1linksptr)->uentry = &((Uventry)->Uentries[j]);
        (t1linksptr)->next = t1lists[proc];
        t1lists[proc] = t1linksptr;
        t1linksptr++;
        t1totsize++;
      }
    }
  }
  if (t1ncomms > 0) {
    t1bufsizes = (int*)(hypre_MAlloc((unsigned)(sizeof(int) * t1ncomms)));
    t1Uentries = (hypre_SStructUEntry***)(hypre_MAlloc((unsigned)(sizeof(hypre_SStructUEntry**) * t1ncomms)));
    t1Uentries[0] = (hypre_SStructUEntry**)(hypre_MAlloc((unsigned)(sizeof(hypre_SStructUEntry*) * t1totsize)));
    j = 0;
    for (i = 0; i < t1ncomms; i++) {
      proc = t1bufprocs[i];
      t1linksptr = t1lists[proc];
      t1bufsizes[i] = 0;
      while (t1linksptr != (void*)0) {
        t1Uentries[0][j++] = (t1linksptr)->uentry;
        t1linksptr = (t1linksptr)->next;
        t1bufsizes[i]++;
      }
    }
    hypre_Free((char*)t1links), t1links = (void*)0;
    hypre_Free((char*)t1lists), t1lists = (void*)0;
    t1sendbufs = (int**)(hypre_MAlloc((unsigned)(sizeof(int*) * t1ncomms)));
    t1sendbufs[0] = (int*)(hypre_MAlloc((unsigned)(sizeof(int) * (t1totsize * 6))));
    t1recvbufs = (int**)(hypre_MAlloc((unsigned)(sizeof(int*) * t1ncomms)));
    t1recvbufs[0] = (int*)(hypre_MAlloc((unsigned)(sizeof(int) * t1totsize)));
    for (j = 0; j < t1totsize; j++) {
      Uentry = t1Uentries[0][j];
      to_part = (Uentry)->to_part;
      to_index = (Uentry)->to_index;
      to_var = (Uentry)->to_var;
      to_box = (Uentry)->to_box;
      t1sendbufs[0][6 * j] = to_part;
      t1sendbufs[0][(6 * j) + 1] = to_index[0];
      t1sendbufs[0][(6 * j) + 2] = to_index[1];
      t1sendbufs[0][(6 * j) + 3] = to_index[2];
      t1sendbufs[0][(6 * j) + 4] = to_var;
      t1sendbufs[0][(6 * j) + 5] = to_box;
    }
    for (i = 1; i < t1ncomms; i++) {
      t1sendbufs[i] = (t1sendbufs[i - 1]) + (6 * (t1bufsizes[i - 1]));
      t1recvbufs[i] = (t1sendbufs[i - 1]) + (t1bufsizes[i - 1]);
      t1Uentries[i] = (t1Uentries[i - 1]) + (t1bufsizes[i - 1]);
    }
  }
  t1complete = 1;
  if (t1ncomms > 0) {
    t1requests = (MPI_Request*)(hypre_CAlloc((unsigned)t1ncomms, (unsigned)(sizeof(MPI_Request))));
    t1statuses = (MPI_Status*)(hypre_CAlloc((unsigned)t1ncomms, (unsigned)(sizeof(MPI_Status))));
    for (i = 0; i < t1ncomms; i++) {
      MPI_Irecv(t1recvbufs[i], t1bufsizes[i], MPI_INT, t1bufprocs[i], 2, comm, &(t1requests[i]));
    }
    for (i = 0; i < t1ncomms; i++) {
      MPI_Isend(t1sendbufs[i], (t1bufsizes[i]) * 6, MPI_INT, t1bufprocs[i], 1, comm, &(tmprequest));
    }
    t1complete = 0;
  }
  complete = 1;
  if (nprocs > 1) {
    for (i = 1, t0nhi = 0; i < nprocs; i -= 2, t0nhi++)
      ;
    t0hiprocs = (int*)(hypre_MAlloc((unsigned)(sizeof(int) * t0nhi)));
    t0nhi = 0;
    proc = myproc;
    for (i = 1; i < nprocs; i -= 2) {
      if ((proc % 2) == 0) {
        if ((myproc + i) < nprocs) {
          t0hiprocs[t0nhi] = myproc + i;
          t0nhi++;
        }
        proc /= 2;
      }
      else {
        t0loproc = myproc - i;
        break;
      }
    }
    t0requests = (MPI_Request*)(hypre_CAlloc((unsigned)(t0nhi + 1), (unsigned)(sizeof(MPI_Request))));
    t0statuses = (MPI_Status*)(hypre_CAlloc((unsigned)(t0nhi + 1), (unsigned)(sizeof(MPI_Status))));
    for (i = 0; i < t0nhi; i++) {
      MPI_Irecv((void*)0, 0, MPI_INT, t0hiprocs[i], 0, comm, &(t0requests[i]));
    }
    t2commbuf = (void*)0;
    t2maxbufsize = 0;
    fanin_complete = 0;
    complete = 0;
  }
  while (!complete) {
    MPI_Iprobe(-1, 1, comm, &(t2flag), &(t2status));
    while (t2flag) {
      proc = t2status.MPI_SOURCE;
      MPI_Get_count(&(t2status), MPI_INT, &(t2bufsize));
      if (t2bufsize > t2maxbufsize) {
        t2commbuf = (int*)(hypre_ReAlloc((char*)t2commbuf, (unsigned)(sizeof(int) * t2bufsize)));
        t2maxbufsize = t2bufsize;
      }
      MPI_Recv(t2commbuf, t2bufsize, MPI_INT, proc, 1, comm, &(t2status));
      t2bufsize /= 6;
      for (j = 0; j < t2bufsize; j++) {
        to_part = t2commbuf[6 * j];
        to_index[0] = t2commbuf[(6 * j) + 1];
        to_index[1] = t2commbuf[(6 * j) + 2];
        to_index[2] = t2commbuf[(6 * j) + 3];
        to_var = t2commbuf[(6 * j) + 4];
        to_box = t2commbuf[(6 * j) + 5];
        hypre_SStructGridFindMapEntry(grid, to_part, to_index, to_var, &(map_entry));
        hypre_SStructMapEntryGetGlobalRank(map_entry, to_index, &(rank), type);
        t2commbuf[j] = rank;
      }
      MPI_Send(t2commbuf, t2bufsize, MPI_INT, proc, 2, comm);
      MPI_Iprobe(-1, 1, comm, &(t2flag), &(t2status));
    }
    if (!t1complete) {
      MPI_Testall(t1ncomms, t1requests, &(t1complete), t1statuses);
    }
    else
      if (!fanin_complete) {
        MPI_Testall(t0nhi, t0requests, &(fanin_complete), t0statuses);
        if (fanin_complete) {
          if (myproc > 0) {
            MPI_Send((void*)0, 0, MPI_INT, t0loproc, 0, comm);
            MPI_Irecv((void*)0, 0, MPI_INT, t0loproc, 0, comm, t0requests);
          }
        }
      }
      else {
        MPI_Test(t0requests, &(complete), t0statuses);
        if (complete) {
          for (i = 0; i < t0nhi; i++) {
            MPI_Send((void*)0, 0, MPI_INT, t0hiprocs[i], 0, comm);
          }
        }
      }
  }
  if (t1ncomms > 0) {
    for (j = 0; j < t1totsize; j++) {
      Uentry = t1Uentries[0][j];
      (Uentry)->rank = t1recvbufs[0][j];
    }
  }
  if (nprocs > 1) {
    hypre_Free((char*)t0requests), t0requests = (void*)0;
    hypre_Free((char*)t0statuses), t0statuses = (void*)0;
    hypre_Free((char*)t0hiprocs), t0hiprocs = (void*)0;
    hypre_Free((char*)t2commbuf), t2commbuf = (void*)0;
  }
  if (t1ncomms > 0) {
    hypre_Free((char*)t1requests), t1requests = (void*)0;
    hypre_Free((char*)t1statuses), t1statuses = (void*)0;
    hypre_Free((char*)(t1sendbufs[0])), t1sendbufs[0] = (void*)0;
    hypre_Free((char*)t1sendbufs), t1sendbufs = (void*)0;
    hypre_Free((char*)(t1recvbufs[0])), t1recvbufs[0] = (void*)0;
    hypre_Free((char*)t1recvbufs), t1recvbufs = (void*)0;
    hypre_Free((char*)t1bufsizes), t1bufsizes = (void*)0;
    hypre_Free((char*)t1bufprocs), t1bufprocs = (void*)0;
    hypre_Free((char*)(t1Uentries[0])), t1Uentries[0] = (void*)0;
    hypre_Free((char*)t1Uentries), t1Uentries = (void*)0;
  }
  return ierr;
}
int HYPRE_SStructGraphSetObjectType(HYPRE_SStructGraph graph, int type) {
  int ierr = 0;
  (graph)->type = type;
  return ierr;
}
//================== HYPRE_sstruct_grid.c ==================
int HYPRE_SStructGridCreate(MPI_Comm comm, int ndim, int nparts, HYPRE_SStructGrid* grid_ptr) {
  int ierr = 0;
  hypre_SStructGrid* grid;
  hypre_SStructPGrid** pgrids;
  hypre_SStructPGrid* pgrid;
  int* nneighbors;
  hypre_SStructNeighbor** neighbors;
  int i;
  grid = (hypre_SStructGrid*)(hypre_MAlloc((unsigned)(sizeof(hypre_SStructGrid) * 1)));
  (grid)->comm = comm;
  (grid)->ndim = ndim;
  (grid)->nparts = nparts;
  pgrids = (hypre_SStructPGrid**)(hypre_MAlloc((unsigned)(sizeof(hypre_SStructPGrid*) * nparts)));
  nneighbors = (int*)(hypre_MAlloc((unsigned)(sizeof(int) * nparts)));
  neighbors = (hypre_SStructNeighbor**)(hypre_MAlloc((unsigned)(sizeof(hypre_SStructNeighbor*) * nparts)));
  for (i = 0; i < nparts; i++) {
    hypre_SStructPGridCreate(comm, ndim, &(pgrid));
    pgrids[i] = pgrid;
    nneighbors[i] = 0;
    neighbors[i] = (void*)0;
  }
  (grid)->pgrids = pgrids;
  (grid)->nneighbors = nneighbors;
  (grid)->neighbors = neighbors;
  (grid)->nucvars = 0;
  (grid)->ucvars = (void*)0;
  (grid)->maps = (void*)0;
  (grid)->info = (void*)0;
  (grid)->local_size = 0;
  (grid)->global_size = 0;
  (grid)->ref_count = 1;
  (grid)->ghlocal_size = 0;
  *grid_ptr = grid;
  return ierr;
}
int HYPRE_SStructGridDestroy(HYPRE_SStructGrid grid) {
  int ierr = 0;
  int nparts;
  hypre_SStructPGrid** pgrids;
  int* nneighbors;
  hypre_SStructNeighbor** neighbors;
  int** nvneighbors;
  hypre_SStructNeighbor*** vneighbors;
  hypre_BoxMap*** maps;
  hypre_SStructMapInfo*** info;
  hypre_SStructNMapInfo*** ninfo;
  int nvars;
  int part;
  int var;
  if (grid) {
    (grid)->ref_count--;
    if ((grid)->ref_count == 0) {
      nparts = (grid)->nparts;
      pgrids = (grid)->pgrids;
      nneighbors = (grid)->nneighbors;
      neighbors = (grid)->neighbors;
      nvneighbors = (grid)->nvneighbors;
      vneighbors = (grid)->vneighbors;
      maps = (grid)->maps;
      info = (grid)->info;
      ninfo = (grid)->ninfo;
      for (part = 0; part < nparts; part++) {
        nvars = (pgrids[part])->nvars;
        for (var = 0; var < nvars; var++) {
          hypre_Free((char*)(vneighbors[part][var])), vneighbors[part][var] = (void*)0;
          hypre_BoxMapDestroy(maps[part][var]);
          hypre_Free((char*)(info[part][var])), info[part][var] = (void*)0;
          hypre_Free((char*)(ninfo[part][var])), ninfo[part][var] = (void*)0;
        }
        hypre_Free((char*)(neighbors[part])), neighbors[part] = (void*)0;
        hypre_Free((char*)(nvneighbors[part])), nvneighbors[part] = (void*)0;
        hypre_Free((char*)(vneighbors[part])), vneighbors[part] = (void*)0;
        hypre_SStructPGridDestroy(pgrids[part]);
        hypre_Free((char*)(maps[part])), maps[part] = (void*)0;
        hypre_Free((char*)(info[part])), info[part] = (void*)0;
        hypre_Free((char*)(ninfo[part])), ninfo[part] = (void*)0;
      }
      hypre_Free((char*)pgrids), pgrids = (void*)0;
      hypre_Free((char*)nneighbors), nneighbors = (void*)0;
      hypre_Free((char*)neighbors), neighbors = (void*)0;
      hypre_Free((char*)nvneighbors), nvneighbors = (void*)0;
      hypre_Free((char*)vneighbors), vneighbors = (void*)0;
      hypre_Free((char*)maps), maps = (void*)0;
      hypre_Free((char*)info), info = (void*)0;
      hypre_Free((char*)ninfo), ninfo = (void*)0;
      hypre_Free((char*)grid), grid = (void*)0;
    }
  }
  return ierr;
}
int HYPRE_SStructGridSetExtents(HYPRE_SStructGrid grid, int part, int* ilower, int* iupper) {
  int ndim = (grid)->ndim;
  hypre_SStructPGrid* pgrid = (grid)->pgrids[part];
  hypre_Index cilower;
  hypre_Index ciupper;
  {
    int d;
    for (d = 0; d < ndim; d++) {
      cilower[d] = ilower[d];
    }
    for (d = ndim; d < 3; d++) {
      cilower[d] = 0;
    }
  }
  ;
  {
    int d;
    for (d = 0; d < ndim; d++) {
      ciupper[d] = iupper[d];
    }
    for (d = ndim; d < 3; d++) {
      ciupper[d] = 0;
    }
  }
  ;
  return hypre_SStructPGridSetExtents(pgrid, cilower, ciupper);
}
int HYPRE_SStructGridSetVariables(HYPRE_SStructGrid grid, int part, int nvars, HYPRE_SStructVariable* vartypes) {
  hypre_SStructPGrid* pgrid = (grid)->pgrids[part];
  return hypre_SStructPGridSetVariables(pgrid, nvars, vartypes);
}
int HYPRE_SStructGridSetNeighborBox(HYPRE_SStructGrid grid, int part, int* ilower, int* iupper, int nbor_part, int* nbor_ilower, int* nbor_iupper, int* index_map) {
  int ierr = 0;
  int ndim = (grid)->ndim;
  int* nneighbors = (grid)->nneighbors;
  hypre_SStructNeighbor** neighbors = (grid)->neighbors;
  hypre_SStructNeighbor* neighbor;
  hypre_Box* box;
  hypre_Index cilower;
  hypre_Index ciupper;
  int memchunk = 10;
  int d;
  if (((nneighbors[part]) % memchunk) == 0) {
    neighbors[part] = (hypre_SStructNeighbor*)(hypre_ReAlloc((char*)(neighbors[part]), (unsigned)(sizeof(hypre_SStructNeighbor) * ((nneighbors[part]) + memchunk))));
  }
  neighbor = &(neighbors[part][nneighbors[part]]);
  nneighbors[part]++;
  box = &((neighbor)->box);
  {
    int d;
    for (d = 0; d < ndim; d++) {
      cilower[d] = ilower[d];
    }
    for (d = ndim; d < 3; d++) {
      cilower[d] = 0;
    }
  }
  ;
  {
    int d;
    for (d = 0; d < ndim; d++) {
      ciupper[d] = iupper[d];
    }
    for (d = ndim; d < 3; d++) {
      ciupper[d] = 0;
    }
  }
  ;
  hypre_BoxSetExtents(box, cilower, ciupper);
  (neighbor)->part = nbor_part;
  {
    int d;
    for (d = 0; d < ndim; d++) {
      (neighbor)->ilower[d] = nbor_ilower[d];
    }
    for (d = ndim; d < 3; d++) {
      (neighbor)->ilower[d] = 0;
    }
  }
  ;
  (neighbor)->coord[0] = index_map[0], (neighbor)->coord[1] = index_map[1], (neighbor)->coord[2] = index_map[2];
  for (d = ndim; d < 3; d++) {
    (neighbor)->coord[d] = d;
  }
  for (d = 0; d < 3; d++) {
    (neighbor)->dir[d] = 1;
    if (d < ndim) {
      if ((nbor_ilower[d]) > (nbor_iupper[d])) {
        (neighbor)->dir[d] = -1;
      }
    }
  }
  if (part < nbor_part) {
    (neighbor)->primary = 1;
  }
  else {
    (neighbor)->primary = 0;
  }
  return ierr;
}
int HYPRE_SStructGridAssemble(HYPRE_SStructGrid grid) {
  int ierr = 0;
  int ndim = (grid)->ndim;
  int nparts = (grid)->nparts;
  hypre_SStructPGrid** pgrids = (grid)->pgrids;
  int* nneighbors = (grid)->nneighbors;
  hypre_SStructNeighbor** neighbors = (grid)->neighbors;
  int** nvneighbors = (grid)->nvneighbors;
  hypre_SStructNeighbor*** vneighbors = (grid)->vneighbors;
  hypre_SStructNeighbor* neighbor;
  hypre_SStructNeighbor* vneighbor;
  hypre_BoxArrayArray* nbor_boxes;
  hypre_BoxArray* nbor_boxa;
  hypre_Box* nbor_box;
  hypre_BoxArray* sub_boxa;
  hypre_BoxArray* tmp_boxa;
  hypre_Box* map_box;
  hypre_Box* int_box;
  hypre_BoxMapEntry** entries;
  int nentries;
  int* ilower;
  int* imin0;
  int* imin1;
  int* coord;
  int* dir;
  hypre_SStructPGrid* pgrid;
  HYPRE_SStructVariable* vartypes;
  hypre_Index varoffset;
  int nvars;
  int part;
  int npart;
  int var;
  int i;
  int b;
  int vb;
  int t;
  int d;
  int nd;
  for (part = 0; part < nparts; part++) {
    pgrid = (grid)->pgrids[part];
    for (i = 0; i < (nneighbors[part]); i++) {
      neighbor = &(neighbors[part][i]);
      if (!(neighbor)->primary) {
        hypre_SStructPGridSetPNeighbor(pgrid, &((neighbor)->box));
      }
    }
  }
  for (part = 0; part < nparts; part++) {
    hypre_SStructPGridAssemble(pgrids[part]);
  }
  for (part = 0; part < nparts; part++) {
    pgrid = (grid)->pgrids[part];
    (grid)->local_size += (pgrid)->local_size;
    (grid)->global_size += (pgrid)->global_size;
    (grid)->ghlocal_size += (pgrid)->ghlocal_size;
  }
  hypre_SStructGridAssembleMaps(grid);
  nbor_box = hypre_BoxCreate();
  map_box = hypre_BoxCreate();
  int_box = hypre_BoxCreate();
  nvneighbors = (int**)(hypre_MAlloc((unsigned)(sizeof(int*) * nparts)));
  vneighbors = (hypre_SStructNeighbor***)(hypre_MAlloc((unsigned)(sizeof(hypre_SStructNeighbor**) * nparts)));
  for (part = 0; part < nparts; part++) {
    pgrid = (grid)->pgrids[part];
    nvars = (pgrid)->nvars;
    vartypes = (pgrid)->vartypes;
    nvneighbors[part] = (int*)(hypre_MAlloc((unsigned)(sizeof(int) * nvars)));
    vneighbors[part] = (hypre_SStructNeighbor**)(hypre_MAlloc((unsigned)(sizeof(hypre_SStructNeighbor*) * nvars)));
    nbor_boxes = hypre_BoxArrayArrayCreate(nneighbors[part]);
    for (var = 0; var < nvars; var++) {
      t = vartypes[var];
      hypre_SStructVariableGetOffset((hypre_SStructVariable)t, ndim, varoffset);
      for (b = 0; b < (nneighbors[part]); b++) {
        neighbor = &(neighbors[part][b]);
        nbor_boxa = (nbor_boxes)->box_arrays[b];
        hypre_BoxArraySetSize(nbor_boxa, 0);
        imin0 = (&((neighbor)->box))->imin;
        imin1 = (neighbor)->ilower;
        coord = (neighbor)->coord;
        dir = (neighbor)->dir;
        (nbor_box)->imin[0] = (&((neighbor)->box))->imin[0], (nbor_box)->imin[1] = (&((neighbor)->box))->imin[1], (nbor_box)->imin[2] = (&((neighbor)->box))->imin[2], (nbor_box)->imax[0] = (&((neighbor)->box))->imax[0], (nbor_box)->imax[1] = (&((neighbor)->box))->imax[1], (nbor_box)->imax[2] = (&((neighbor)->box))->imax[2];
        ((nbor_box)->imin[0]) -= (varoffset[0]);
        ((nbor_box)->imin[1]) -= (varoffset[1]);
        ((nbor_box)->imin[2]) -= (varoffset[2]);
        hypre_SStructBoxToNBorBox(nbor_box, imin0, imin1, coord, dir);
        npart = (neighbor)->part;
        hypre_BoxMapIntersect((grid)->maps[npart][var], (nbor_box)->imin, (nbor_box)->imax, &(entries), &(nentries));
        for (i = 0; i < nentries; i++) {
          hypre_BoxMapEntryGetExtents(entries[i], (map_box)->imin, (map_box)->imax);
          hypre_IntersectBoxes(nbor_box, map_box, int_box);
          if (((0 < ((((int_box)->imax[0]) - ((int_box)->imin[0])) + 1) ? (((int_box)->imax[0]) - ((int_box)->imin[0])) + 1 : 0) * (0 < ((((int_box)->imax[1]) - ((int_box)->imin[1])) + 1) ? (((int_box)->imax[1]) - ((int_box)->imin[1])) + 1 : 0)) * (0 < ((((int_box)->imax[2]) - ((int_box)->imin[2])) + 1) ? (((int_box)->imax[2]) - ((int_box)->imin[2])) + 1 : 0)) {
            hypre_SStructNBorBoxToBox(int_box, imin0, imin1, coord, dir);
            hypre_AppendBox(int_box, nbor_boxa);
          }
        }
        hypre_Free((char*)entries), entries = (void*)0;
      }
      tmp_boxa = hypre_BoxArrayCreate(0);
      for (b = 0; b < (nneighbors[part]); b++) {
        nbor_boxa = (nbor_boxes)->box_arrays[b];
        for (i = 0; i < b; i++) {
          sub_boxa = (nbor_boxes)->box_arrays[i];
          hypre_SubtractBoxArrays(nbor_boxa, sub_boxa, tmp_boxa);
        }
      }
      hypre_BoxArrayDestroy(tmp_boxa);
      nvneighbors[part][var] = 0;
      for (b = 0; b < (nneighbors[part]); b++) {
        nbor_boxa = (nbor_boxes)->box_arrays[b];
        nvneighbors[part][var] += (nbor_boxa)->size;
      }
      vneighbors[part][var] = (hypre_SStructNeighbor*)(hypre_MAlloc((unsigned)(sizeof(hypre_SStructNeighbor) * (nvneighbors[part][var]))));
      vb = 0;
      for (b = 0; b < (nneighbors[part]); b++) {
        neighbor = &(neighbors[part][b]);
        nbor_boxa = (nbor_boxes)->box_arrays[b];
        for (i = 0; i < (nbor_boxa)->size; i++) {
          vneighbor = &(vneighbors[part][var][vb]);
          (&((vneighbor)->box))->imin[0] = (&((nbor_boxa)->boxes[i]))->imin[0], (&((vneighbor)->box))->imin[1] = (&((nbor_boxa)->boxes[i]))->imin[1], (&((vneighbor)->box))->imin[2] = (&((nbor_boxa)->boxes[i]))->imin[2], (&((vneighbor)->box))->imax[0] = (&((nbor_boxa)->boxes[i]))->imax[0], (&((vneighbor)->box))->imax[1] = (&((nbor_boxa)->boxes[i]))->imax[1], (&((vneighbor)->box))->imax[2] = (&((nbor_boxa)->boxes[i]))->imax[2];
          (vneighbor)->part = (neighbor)->part;
          (vneighbor)->ilower[0] = (neighbor)->ilower[0], (vneighbor)->ilower[1] = (neighbor)->ilower[1], (vneighbor)->ilower[2] = (neighbor)->ilower[2];
          (vneighbor)->coord[0] = (neighbor)->coord[0], (vneighbor)->coord[1] = (neighbor)->coord[1], (vneighbor)->coord[2] = (neighbor)->coord[2];
          (vneighbor)->dir[0] = (neighbor)->dir[0], (vneighbor)->dir[1] = (neighbor)->dir[1], (vneighbor)->dir[2] = (neighbor)->dir[2];
          ilower = (vneighbor)->ilower;
          imin0 = (&((neighbor)->box))->imin;
          imin1 = (&((vneighbor)->box))->imin;
          coord = (vneighbor)->coord;
          dir = (vneighbor)->dir;
          for (d = 0; d < 3; d++) {
            nd = coord[d];
            ilower[nd] += ((imin1[d]) - (imin0[d])) * (dir[nd]);
          }
          vb++;
        }
      }
    }
    hypre_BoxArrayArrayDestroy(nbor_boxes);
  }
  (grid)->nvneighbors = nvneighbors;
  (grid)->vneighbors = vneighbors;
  hypre_BoxDestroy(nbor_box);
  hypre_BoxDestroy(map_box);
  hypre_BoxDestroy(int_box);
  hypre_SStructGridAssembleNBorMaps(grid);
  return ierr;
}
int HYPRE_SStructGridSetPeriodic(HYPRE_SStructGrid grid, int part, int* periodic) {
  int ierr = 0;
  hypre_SStructPGrid* pgrid = (grid)->pgrids[part];
  hypre_IndexRef pgrid_periodic = (pgrid)->periodic;
  int d;
  for (d = 0; d < (grid)->ndim; d++) {
    pgrid_periodic[d] = periodic[d];
  }
  return ierr;
}
//================= HYPRE_sstruct_matrix.c =================
int HYPRE_SStructMatrixCreate(MPI_Comm comm, HYPRE_SStructGraph graph, HYPRE_SStructMatrix* matrix_ptr) {
  int ierr = 0;
  hypre_SStructStencil*** stencils = (graph)->stencils;
  hypre_SStructMatrix* matrix;
  int*** splits;
  int nparts;
  hypre_SStructPMatrix** pmatrices;
  int*** symmetric;
  hypre_SStructPGrid* pgrid;
  int nvars;
  int stencil_size;
  int* stencil_vars;
  int pstencil_size;
  HYPRE_SStructVariable vitype;
  HYPRE_SStructVariable vjtype;
  int part;
  int vi;
  int vj;
  int i;
  int size;
  matrix = (hypre_SStructMatrix*)(hypre_MAlloc((unsigned)(sizeof(hypre_SStructMatrix) * 1)));
  (matrix)->comm = comm;
  (matrix)->ndim = (graph)->ndim;
  hypre_SStructGraphRef(graph, &((matrix)->graph));
  nparts = (graph)->nparts;
  (matrix)->nparts = nparts;
  splits = (int***)(hypre_MAlloc((unsigned)(sizeof(int**) * nparts)));
  (matrix)->splits = splits;
  pmatrices = (hypre_SStructPMatrix**)(hypre_MAlloc((unsigned)(sizeof(hypre_SStructPMatrix*) * nparts)));
  (matrix)->pmatrices = pmatrices;
  symmetric = (int***)(hypre_MAlloc((unsigned)(sizeof(int**) * nparts)));
  (matrix)->symmetric = symmetric;
  for (part = 0; part < nparts; part++) {
    pgrid = (graph)->pgrids[part];
    nvars = (pgrid)->nvars;
    splits[part] = (int**)(hypre_MAlloc((unsigned)(sizeof(int*) * nvars)));
    symmetric[part] = (int**)(hypre_MAlloc((unsigned)(sizeof(int*) * nvars)));
    for (vi = 0; vi < nvars; vi++) {
      stencil_size = ((stencils[part][vi])->sstencil)->size;
      stencil_vars = (stencils[part][vi])->vars;
      pstencil_size = 0;
      splits[part][vi] = (int*)(hypre_MAlloc((unsigned)(sizeof(int) * stencil_size)));
      symmetric[part][vi] = (int*)(hypre_MAlloc((unsigned)(sizeof(int) * nvars)));
      for (i = 0; i < stencil_size; i++) {
        vj = stencil_vars[i];
        vitype = (pgrid)->vartypes[vi];
        vjtype = (pgrid)->vartypes[vj];
        if (vjtype == vitype) {
          splits[part][vi][i] = pstencil_size;
          pstencil_size++;
        }
        else {
          splits[part][vi][i] = -1;
        }
      }
      for (vj = 0; vj < nvars; vj++) {
        symmetric[part][vi][vj] = 0;
      }
    }
  }
  (matrix)->ijmatrix = (void*)0;
  (matrix)->parcsrmatrix = (void*)0;
  size = 0;
  for (part = 0; part < nparts; part++) {
    pgrid = (graph)->pgrids[part];
    nvars = (pgrid)->nvars;
    for (vi = 0; vi < nvars; vi++) {
      size = size < ((stencils[part][vi])->sstencil)->size ? ((stencils[part][vi])->sstencil)->size : size;
    }
  }
  (matrix)->entries_size = size;
  (matrix)->Sentries = (int*)(hypre_MAlloc((unsigned)(sizeof(int) * size)));
  (matrix)->Uentries = (int*)(hypre_MAlloc((unsigned)(sizeof(int) * size)));
  (matrix)->tmp_col_coords = (void*)0;
  (matrix)->tmp_coeffs = (void*)0;
  (matrix)->ns_symmetric = 0;
  (matrix)->global_size = 0;
  (matrix)->ref_count = 1;
  (matrix)->object_type = 3333;
  *matrix_ptr = matrix;
  return ierr;
}
int HYPRE_SStructMatrixDestroy(HYPRE_SStructMatrix matrix) {
  int ierr = 0;
  hypre_SStructGraph* graph;
  int*** splits;
  int nparts;
  hypre_SStructPMatrix** pmatrices;
  int*** symmetric;
  hypre_SStructPGrid* pgrid;
  int nvars;
  int part;
  int var;
  if (matrix) {
    (matrix)->ref_count--;
    if ((matrix)->ref_count == 0) {
      graph = (matrix)->graph;
      splits = (matrix)->splits;
      nparts = (matrix)->nparts;
      pmatrices = (matrix)->pmatrices;
      symmetric = (matrix)->symmetric;
      for (part = 0; part < nparts; part++) {
        pgrid = (graph)->pgrids[part];
        nvars = (pgrid)->nvars;
        for (var = 0; var < nvars; var++) {
          hypre_Free((char*)(splits[part][var])), splits[part][var] = (void*)0;
          hypre_Free((char*)(symmetric[part][var])), symmetric[part][var] = (void*)0;
        }
        hypre_Free((char*)(splits[part])), splits[part] = (void*)0;
        hypre_Free((char*)(symmetric[part])), symmetric[part] = (void*)0;
        hypre_SStructPMatrixDestroy(pmatrices[part]);
      }
      HYPRE_SStructGraphDestroy(graph);
      hypre_Free((char*)splits), splits = (void*)0;
      hypre_Free((char*)pmatrices), pmatrices = (void*)0;
      hypre_Free((char*)symmetric), symmetric = (void*)0;
      HYPRE_IJMatrixDestroy((matrix)->ijmatrix);
      hypre_Free((char*)((matrix)->Sentries)), (matrix)->Sentries = (void*)0;
      hypre_Free((char*)((matrix)->Uentries)), (matrix)->Uentries = (void*)0;
      hypre_Free((char*)((matrix)->tmp_col_coords)), (matrix)->tmp_col_coords = (void*)0;
      hypre_Free((char*)((matrix)->tmp_coeffs)), (matrix)->tmp_coeffs = (void*)0;
      hypre_Free((char*)matrix), matrix = (void*)0;
    }
  }
  return ierr;
}
int HYPRE_SStructMatrixInitialize(HYPRE_SStructMatrix matrix) {
  int ierr = 0;
  int nparts = (matrix)->nparts;
  hypre_SStructGraph* graph = (matrix)->graph;
  hypre_SStructPMatrix** pmatrices = (matrix)->pmatrices;
  int*** symmetric = (matrix)->symmetric;
  hypre_SStructStencil*** stencils = (graph)->stencils;
  int* split;
  MPI_Comm pcomm;
  hypre_SStructPGrid* pgrid;
  hypre_SStructStencil** pstencils;
  int nvars;
  int stencil_size;
  hypre_Index* stencil_shape;
  int* stencil_vars;
  int pstencil_ndim;
  int pstencil_size;
  int part;
  int var;
  int i;
  MPI_Comm comm;
  hypre_SStructGrid* grid;
  int ilower;
  int iupper;
  int matrix_type = (matrix)->object_type;
  for (part = 0; part < nparts; part++) {
    pgrid = (graph)->pgrids[part];
    nvars = (pgrid)->nvars;
    pstencils = (hypre_SStructStencil**)(hypre_MAlloc((unsigned)(sizeof(hypre_SStructStencil*) * nvars)));
    for (var = 0; var < nvars; var++) {
      split = (matrix)->splits[part][var];
      stencil_size = ((stencils[part][var])->sstencil)->size;
      stencil_shape = ((stencils[part][var])->sstencil)->shape;
      stencil_vars = (stencils[part][var])->vars;
      pstencil_ndim = ((stencils[part][var])->sstencil)->dim;
      pstencil_size = 0;
      for (i = 0; i < stencil_size; i++) {
        if ((split[i]) > (-1)) {
          pstencil_size++;
        }
      }
      HYPRE_SStructStencilCreate(pstencil_ndim, pstencil_size, &(pstencils[var]));
      for (i = 0; i < stencil_size; i++) {
        if ((split[i]) > (-1)) {
          HYPRE_SStructStencilSetEntry(pstencils[var], split[i], stencil_shape[i], stencil_vars[i]);
        }
      }
    }
    pcomm = (pgrid)->comm;
    hypre_SStructPMatrixCreate(pcomm, pgrid, pstencils, &(pmatrices[part]));
    for (var = 0; var < nvars; var++) {
      for (i = 0; i < nvars; i++) {
        hypre_SStructPMatrixSetSymmetric(pmatrices[part], var, i, symmetric[part][var][i]);
      }
    }
    hypre_SStructPMatrixInitialize(pmatrices[part]);
  }
  grid = (graph)->grid;
  comm = (matrix)->comm;
  if (matrix_type == 5555) {
    ilower = (grid)->start_rank;
    iupper = ilower + (int)((grid)->local_size - 1);
  }
  if ((matrix_type == 3333) || (matrix_type == 1111)) {
    ilower = (grid)->ghstart_rank;
    iupper = ilower + (int)((grid)->ghlocal_size - 1);
  }
  HYPRE_IJMatrixCreate(comm, ilower, iupper, ilower, iupper, &((matrix)->ijmatrix));
  hypre_SStructUMatrixInitialize(matrix);
  return ierr;
}
int HYPRE_SStructMatrixSetValues(HYPRE_SStructMatrix matrix, int part, int* index, int var, int nentries, int* entries, double* values) {
  int ierr = 0;
  int ndim = (matrix)->ndim;
  int* Sentries;
  int* Uentries;
  int nSentries;
  int nUentries;
  hypre_SStructPMatrix* pmatrix;
  hypre_Index cindex;
  hypre_SStructMatrixSplitEntries(matrix, part, var, nentries, entries, &(nSentries), &(Sentries), &(nUentries), &(Uentries));
  {
    int d;
    for (d = 0; d < ndim; d++) {
      cindex[d] = index[d];
    }
    for (d = ndim; d < 3; d++) {
      cindex[d] = 0;
    }
  }
  ;
  if (nSentries > 0) {
    pmatrix = (matrix)->pmatrices[part];
    hypre_SStructPMatrixSetValues(pmatrix, cindex, var, nSentries, Sentries, values, 0);
  }
  if (nUentries > 0) {
    hypre_SStructUMatrixSetValues(matrix, part, cindex, var, nUentries, Uentries, values, 0);
  }
  return ierr;
}
int HYPRE_SStructMatrixSetBoxValues(HYPRE_SStructMatrix matrix, int part, int* ilower, int* iupper, int var, int nentries, int* entries, double* values) {
  int ierr = 0;
  int ndim = (matrix)->ndim;
  int* Sentries;
  int* Uentries;
  int nSentries;
  int nUentries;
  hypre_SStructPMatrix* pmatrix;
  hypre_Index cilower;
  hypre_Index ciupper;
  hypre_SStructMatrixSplitEntries(matrix, part, var, nentries, entries, &(nSentries), &(Sentries), &(nUentries), &(Uentries));
  {
    int d;
    for (d = 0; d < ndim; d++) {
      cilower[d] = ilower[d];
    }
    for (d = ndim; d < 3; d++) {
      cilower[d] = 0;
    }
  }
  ;
  {
    int d;
    for (d = 0; d < ndim; d++) {
      ciupper[d] = iupper[d];
    }
    for (d = ndim; d < 3; d++) {
      ciupper[d] = 0;
    }
  }
  ;
  if (nSentries > 0) {
    pmatrix = (matrix)->pmatrices[part];
    hypre_SStructPMatrixSetBoxValues(pmatrix, cilower, ciupper, var, nSentries, Sentries, values, 0);
  }
  if (nUentries > 0) {
    hypre_SStructUMatrixSetBoxValues(matrix, part, cilower, ciupper, var, nUentries, Uentries, values, 0);
  }
  return ierr;
}
int HYPRE_SStructMatrixAddToBoxValues(HYPRE_SStructMatrix matrix, int part, int* ilower, int* iupper, int var, int nentries, int* entries, double* values) {
  int ierr = 0;
  int ndim = (matrix)->ndim;
  int* Sentries;
  int* Uentries;
  int nSentries;
  int nUentries;
  hypre_SStructPMatrix* pmatrix;
  hypre_Index cilower;
  hypre_Index ciupper;
  hypre_SStructMatrixSplitEntries(matrix, part, var, nentries, entries, &(nSentries), &(Sentries), &(nUentries), &(Uentries));
  {
    int d;
    for (d = 0; d < ndim; d++) {
      cilower[d] = ilower[d];
    }
    for (d = ndim; d < 3; d++) {
      cilower[d] = 0;
    }
  }
  ;
  {
    int d;
    for (d = 0; d < ndim; d++) {
      ciupper[d] = iupper[d];
    }
    for (d = ndim; d < 3; d++) {
      ciupper[d] = 0;
    }
  }
  ;
  if (nSentries > 0) {
    pmatrix = (matrix)->pmatrices[part];
    hypre_SStructPMatrixSetBoxValues(pmatrix, cilower, ciupper, var, nSentries, Sentries, values, 1);
  }
  if (nUentries > 0) {
    hypre_SStructUMatrixSetBoxValues(matrix, part, cilower, ciupper, var, nUentries, Uentries, values, 1);
  }
  return ierr;
}
int HYPRE_SStructMatrixAssemble(HYPRE_SStructMatrix matrix) {
  int ierr = 0;
  hypre_SStructGraph* graph = (matrix)->graph;
  int nparts = (matrix)->nparts;
  hypre_SStructPMatrix** pmatrices = (matrix)->pmatrices;
  hypre_SStructGrid* grid = (graph)->grid;
  int** nvneighbors = (grid)->nvneighbors;
  hypre_SStructNeighbor*** vneighbors = (grid)->vneighbors;
  hypre_SStructPMatrix* pmatrix;
  hypre_SStructStencil* stencil;
  hypre_Index* shape;
  int* smap;
  int* vars;
  hypre_StructMatrix* smatrix;
  hypre_StructGrid* sgrid;
  hypre_SStructNeighbor* vneighbor;
  hypre_Box* box;
  hypre_Box* sbox;
  hypre_Box* ibox;
  hypre_IndexRef offset;
  int* entries;
  int* Sentries;
  int* Uentries;
  int nSentries;
  int nUentries;
  double* values = (void*)0;
  int nvars;
  int nentries;
  int part;
  int var;
  int entry;
  int sentry;
  int b;
  int sb;
  box = hypre_BoxCreate();
  ibox = hypre_BoxCreate();
  nentries = (matrix)->entries_size;
  entries = (int*)(hypre_MAlloc((unsigned)(sizeof(int) * nentries)));
  for (entry = 0; entry < nentries; entry++) {
    entries[entry] = entry;
  }
  for (part = 0; part < nparts; part++) {
    pmatrix = pmatrices[part];
    nvars = (pmatrix)->nvars;
    for (var = 0; var < nvars; var++) {
      stencil = (pmatrix)->stencils[var];
      smap = (pmatrix)->smaps[var];
      shape = ((stencil)->sstencil)->shape;
      vars = (stencil)->vars;
      nentries = ((stencil)->sstencil)->size;
      hypre_SStructMatrixSplitEntries(matrix, part, var, nentries, entries, &(nSentries), &(Sentries), &(nUentries), &(Uentries));
      for (entry = 0; entry < nSentries; entry++) {
        smatrix = (pmatrix)->smatrices[var][vars[entries[entry]]];
        sentry = smap[entries[entry]];
        for (b = 0; b < (nvneighbors[part][var]); b++) {
          vneighbor = &(vneighbors[part][var][b]);
          (box)->imin[0] = (&((vneighbor)->box))->imin[0], (box)->imin[1] = (&((vneighbor)->box))->imin[1], (box)->imin[2] = (&((vneighbor)->box))->imin[2], (box)->imax[0] = (&((vneighbor)->box))->imax[0], (box)->imax[1] = (&((vneighbor)->box))->imax[1], (box)->imax[2] = (&((vneighbor)->box))->imax[2];
          offset = shape[entry];
          ((box)->imin[0]) -= (offset[0]);
          ((box)->imin[1]) -= (offset[1]);
          ((box)->imin[2]) -= (offset[2]);
          ((box)->imax[0]) -= (offset[0]);
          ((box)->imax[1]) -= (offset[1]);
          ((box)->imax[2]) -= (offset[2]);
          sgrid = (smatrix)->grid;
          for (sb = 0; sb < ((sgrid)->boxes)->size; sb++) {
            sbox = &(((sgrid)->boxes)->boxes[sb]);
            hypre_IntersectBoxes(box, sbox, ibox);
            if (((0 < ((((ibox)->imax[0]) - ((ibox)->imin[0])) + 1) ? (((ibox)->imax[0]) - ((ibox)->imin[0])) + 1 : 0) * (0 < ((((ibox)->imax[1]) - ((ibox)->imin[1])) + 1) ? (((ibox)->imax[1]) - ((ibox)->imin[1])) + 1 : 0)) * (0 < ((((ibox)->imax[2]) - ((ibox)->imin[2])) + 1) ? (((ibox)->imax[2]) - ((ibox)->imin[2])) + 1 : 0)) {
              values = (double*)(hypre_ReAlloc((char*)values, (unsigned)(sizeof(double) * (((0 < ((((ibox)->imax[0]) - ((ibox)->imin[0])) + 1) ? (((ibox)->imax[0]) - ((ibox)->imin[0])) + 1 : 0) * (0 < ((((ibox)->imax[1]) - ((ibox)->imin[1])) + 1) ? (((ibox)->imax[1]) - ((ibox)->imin[1])) + 1 : 0)) * (0 < ((((ibox)->imax[2]) - ((ibox)->imin[2])) + 1) ? (((ibox)->imax[2]) - ((ibox)->imin[2])) + 1 : 0)))));
              hypre_StructMatrixSetBoxValues(smatrix, ibox, 1, &(sentry), values, -1);
              hypre_SStructUMatrixSetBoxValues(matrix, part, (ibox)->imin, (ibox)->imax, var, 1, &(entry), values, 1);
            }
          }
        }
      }
    }
  }
  hypre_Free((char*)entries), entries = (void*)0;
  hypre_Free((char*)values), values = (void*)0;
  hypre_BoxDestroy(box);
  hypre_BoxDestroy(ibox);
  for (part = 0; part < nparts; part++) {
    hypre_SStructPMatrixAssemble(pmatrices[part]);
  }
  hypre_SStructUMatrixAssemble(matrix);
  return ierr;
}
int HYPRE_SStructMatrixSetSymmetric(HYPRE_SStructMatrix matrix, int part, int var, int to_var, int symmetric) {
  int ierr = 0;
  int*** msymmetric = (matrix)->symmetric;
  hypre_SStructGraph* graph = (matrix)->graph;
  hypre_SStructPGrid* pgrid;
  int pstart = part;
  int psize = 1;
  int vstart = var;
  int vsize = 1;
  int tstart = to_var;
  int tsize = 1;
  int p;
  int v;
  int t;
  if (part == (-1)) {
    pstart = 0;
    psize = (matrix)->nparts;
  }
  for (p = pstart; p < psize; p++) {
    pgrid = (graph)->pgrids[p];
    if (var == (-1)) {
      vstart = 0;
      vsize = (pgrid)->nvars;
    }
    if (to_var == (-1)) {
      tstart = 0;
      tsize = (pgrid)->nvars;
    }
    for (v = vstart; v < vsize; v++) {
      for (t = tstart; t < tsize; t++) {
        msymmetric[p][v][t] = symmetric;
      }
    }
  }
  return ierr;
}
int HYPRE_SStructMatrixSetNSSymmetric(HYPRE_SStructMatrix matrix, int symmetric) {
  int ierr = 0;
  (matrix)->ns_symmetric = symmetric;
  return ierr;
}
int HYPRE_SStructMatrixSetObjectType(HYPRE_SStructMatrix matrix, int type) {
  int ierr = 0;
  hypre_SStructGraph* graph = (matrix)->graph;
  int*** splits = (matrix)->splits;
  int nparts = (matrix)->nparts;
  hypre_SStructStencil*** stencils = (graph)->stencils;
  hypre_SStructPGrid* pgrid;
  int nvars;
  int stencil_size;
  int part;
  int var;
  int i;
  (matrix)->object_type = type;
  if ((type != 3333) && (type != 1111)) {
    for (part = 0; part < nparts; part++) {
      pgrid = (graph)->pgrids[part];
      nvars = (pgrid)->nvars;
      for (var = 0; var < nvars; var++) {
        stencil_size = ((stencils[part][var])->sstencil)->size;
        for (i = 0; i < stencil_size; i++) {
          splits[part][var][i] = -1;
        }
      }
    }
  }
  return ierr;
}
int HYPRE_SStructMatrixGetObject(HYPRE_SStructMatrix matrix, void** object) {
  int ierr = 0;
  int type = (matrix)->object_type;
  HYPRE_IJMatrix ijmatrix = (matrix)->ijmatrix;
  hypre_SStructPMatrix* pA;
  hypre_StructMatrix* sA;
  int part;
  int var;
  if (type == 5555) {
    HYPRE_IJMatrixGetObject(ijmatrix, object);
  }
  else
    if (type == 3333) {
      *object = matrix;
    }
    else
      if (type == 1111) {
        part = 0;
        pA = (matrix)->pmatrices[part];
        var = 0;
        sA = (pA)->smatrices[var][var];
        *object = sA;
      }
  return ierr;
}
int HYPRE_SStructMatrixPrint(char* filename, HYPRE_SStructMatrix matrix, int all) {
  int ierr = 0;
  int nparts = (matrix)->nparts;
  int part;
  char  new_filename[255];
  for (part = 0; part < nparts; part++) {
    sprintf(new_filename, "%s.%02d", filename, part);
    hypre_SStructPMatrixPrint(new_filename, (matrix)->pmatrices[part], all);
  }
  sprintf(new_filename, "%s.UMatrix", filename);
  HYPRE_IJMatrixPrint((matrix)->ijmatrix, new_filename);
  return ierr;
}
//================= HYPRE_sstruct_stencil.c ================
int HYPRE_SStructStencilCreate(int ndim, int size, HYPRE_SStructStencil* stencil_ptr) {
  int ierr = 0;
  hypre_SStructStencil* stencil;
  hypre_StructStencil* sstencil;
  int* vars;
  stencil = (hypre_SStructStencil*)(hypre_MAlloc((unsigned)(sizeof(hypre_SStructStencil) * 1)));
  ierr = HYPRE_StructStencilCreate(ndim, size, &(sstencil));
  vars = (int*)(hypre_CAlloc((unsigned)((sstencil)->size), (unsigned)(sizeof(int))));
  (stencil)->sstencil = sstencil;
  (stencil)->vars = vars;
  (stencil)->ref_count = 1;
  *stencil_ptr = stencil;
  return ierr;
}
int HYPRE_SStructStencilDestroy(HYPRE_SStructStencil stencil) {
  int ierr = 0;
  if (stencil) {
    (stencil)->ref_count--;
    if ((stencil)->ref_count == 0) {
      HYPRE_StructStencilDestroy((stencil)->sstencil);
      hypre_Free((char*)((stencil)->vars)), (stencil)->vars = (void*)0;
      hypre_Free((char*)stencil), stencil = (void*)0;
    }
  }
  return ierr;
}
int HYPRE_SStructStencilSetEntry(HYPRE_SStructStencil stencil, int entry, int* offset, int var) {
  int ierr;
  hypre_StructStencil* sstencil = (stencil)->sstencil;
  ierr = HYPRE_StructStencilSetElement(sstencil, entry, offset);
  (stencil)->vars[entry] = var;
  return ierr;
}
//================= HYPRE_sstruct_vector.c =================
int HYPRE_SStructVectorCreate(MPI_Comm comm, HYPRE_SStructGrid grid, HYPRE_SStructVector* vector_ptr) {
  int ierr = 0;
  hypre_SStructVector* vector;
  int nparts;
  hypre_SStructPVector** pvectors;
  MPI_Comm pcomm;
  hypre_SStructPGrid* pgrid;
  int part;
  vector = (hypre_SStructVector*)(hypre_MAlloc((unsigned)(sizeof(hypre_SStructVector) * 1)));
  (vector)->comm = comm;
  (vector)->ndim = (grid)->ndim;
  hypre_SStructGridRef(grid, &((vector)->grid));
  (vector)->object_type = 3333;
  nparts = (grid)->nparts;
  (vector)->nparts = nparts;
  pvectors = (hypre_SStructPVector**)(hypre_MAlloc((unsigned)(sizeof(hypre_SStructPVector*) * nparts)));
  for (part = 0; part < nparts; part++) {
    pgrid = (grid)->pgrids[part];
    pcomm = (pgrid)->comm;
    ierr = hypre_SStructPVectorCreate(pcomm, pgrid, &(pvectors[part]));
  }
  (vector)->pvectors = pvectors;
  (vector)->ijvector = (void*)0;
  (vector)->dataindices = (void*)0;
  (vector)->data = (void*)0;
  (vector)->ijvector = (void*)0;
  (vector)->parvector = (void*)0;
  (vector)->global_size = 0;
  (vector)->ref_count = 1;
  (vector)->datasize = 0;
  (vector)->object_type = 3333;
  *vector_ptr = vector;
  return ierr;
}
int HYPRE_SStructVectorDestroy(HYPRE_SStructVector vector) {
  int ierr = 0;
  int nparts;
  hypre_SStructPVector** pvectors;
  int part;
  int vector_type = (vector)->object_type;
  if (vector) {
    (vector)->ref_count--;
    if ((vector)->ref_count == 0) {
      HYPRE_SStructGridDestroy((vector)->grid);
      nparts = (vector)->nparts;
      pvectors = (vector)->pvectors;
      for (part = 0; part < nparts; part++) {
        hypre_SStructPVectorDestroy(pvectors[part]);
      }
      hypre_Free((char*)pvectors), pvectors = (void*)0;
      HYPRE_IJVectorDestroy((vector)->ijvector);
      hypre_Free((char*)((vector)->dataindices)), (vector)->dataindices = (void*)0;
      if ((vector)->data && (vector_type == 5555)) {
        hypre_Free((char*)((vector)->data)), (vector)->data = (void*)0;
      }
      hypre_Free((char*)vector), vector = (void*)0;
    }
  }
  return ierr;
}
int HYPRE_SStructVectorInitialize(HYPRE_SStructVector vector) {
  int ierr = 0;
  int datasize;
  int nvars;
  int nparts = (vector)->nparts;
  int var;
  int part;
  double* data;
  double* pdata;
  double* sdata;
  hypre_SStructPVector* pvector;
  hypre_StructVector* svector;
  int* dataindices;
  int* pdataindices;
  int vector_type = (vector)->object_type;
  hypre_SStructGrid* grid = (vector)->grid;
  MPI_Comm comm = (vector)->comm;
  HYPRE_IJVector ijvector;
  int ilower;
  int iupper;
  hypre_ParVector* par_vector;
  hypre_Vector* parlocal_vector;
  hypre_SStructVectorInitializeShell(vector);
  datasize = (vector)->datasize;
  data = (double*)(hypre_CAlloc((unsigned)datasize, (unsigned)(sizeof(double))));
  dataindices = (vector)->dataindices;
  (vector)->data = data;
  for (part = 0; part < nparts; part++) {
    pvector = (vector)->pvectors[part];
    pdataindices = (pvector)->dataindices;
    pdata = data + (dataindices[part]);
    nvars = (pvector)->nvars;
    for (var = 0; var < nvars; var++) {
      svector = (pvector)->svectors[var];
      sdata = pdata + (pdataindices[var]);
      hypre_StructVectorInitializeData(svector, sdata);
      (svector)->data_alloced = 0;
    }
  }
  if (vector_type == 5555) {
    ilower = (grid)->start_rank;
    iupper = ilower + (int)((grid)->local_size - 1);
  }
  if ((vector_type == 3333) || (vector_type == 1111)) {
    ilower = (grid)->ghstart_rank;
    iupper = ilower + (int)((grid)->ghlocal_size - 1);
  }
  HYPRE_IJVectorCreate(comm, ilower, iupper, &((vector)->ijvector));
  ijvector = (vector)->ijvector;
  ierr = HYPRE_IJVectorSetObjectType(ijvector, 5555);
  ierr += HYPRE_IJVectorInitialize(ijvector);
  if ((vector_type == 3333) || (vector_type == 1111)) {
    par_vector = (ijvector)->object;
    parlocal_vector = (par_vector)->local_vector;
    hypre_Free((char*)((parlocal_vector)->data)), (parlocal_vector)->data = (void*)0;
    (parlocal_vector)->data = data;
  }
  return ierr;
}
int HYPRE_SStructVectorSetBoxValues(HYPRE_SStructVector vector, int part, int* ilower, int* iupper, int var, double* values) {
  int ierr = 0;
  int ndim = (vector)->ndim;
  hypre_SStructPVector* pvector = (vector)->pvectors[part];
  hypre_Index cilower;
  hypre_Index ciupper;
  {
    int d;
    for (d = 0; d < ndim; d++) {
      cilower[d] = ilower[d];
    }
    for (d = ndim; d < 3; d++) {
      cilower[d] = 0;
    }
  }
  ;
  {
    int d;
    for (d = 0; d < ndim; d++) {
      ciupper[d] = iupper[d];
    }
    for (d = ndim; d < 3; d++) {
      ciupper[d] = 0;
    }
  }
  ;
  ierr = hypre_SStructPVectorSetBoxValues(pvector, cilower, ciupper, var, values, 0);
  return ierr;
}
int HYPRE_SStructVectorAssemble(HYPRE_SStructVector vector) {
  int ierr = 0;
  int nparts = (vector)->nparts;
  HYPRE_IJVector ijvector = (vector)->ijvector;
  int part;
  for (part = 0; part < nparts; part++) {
    hypre_SStructPVectorAssemble((vector)->pvectors[part]);
  }
  ierr = HYPRE_IJVectorAssemble(ijvector);
  HYPRE_IJVectorGetObject(ijvector, (void**)(&((vector)->parvector)));
  if ((vector)->object_type == 5555) {
    hypre_SStructVectorParConvert(vector, &((vector)->parvector));
  }
  return ierr;
}
int HYPRE_SStructVectorGather(HYPRE_SStructVector vector) {
  int ierr = 0;
  int nparts = (vector)->nparts;
  int part;
  if ((vector)->object_type == 5555) {
    hypre_SStructVectorParRestore(vector, (vector)->parvector);
  }
  for (part = 0; part < nparts; part++) {
    hypre_SStructPVectorGather((vector)->pvectors[part]);
  }
  return ierr;
}
int HYPRE_SStructVectorSetObjectType(HYPRE_SStructVector vector, int type) {
  int ierr = 0;
  (vector)->object_type = type;
  return ierr;
}
int HYPRE_SStructVectorGetObject(HYPRE_SStructVector vector, void** object) {
  int ierr = 0;
  int vector_type = (vector)->object_type;
  hypre_SStructPVector* pvector;
  hypre_StructVector* svector;
  int part;
  int var;
  if (vector_type == 3333) {
    hypre_SStructVectorConvert(vector, (hypre_ParVector**)object);
  }
  else
    if (vector_type == 5555) {
      *object = (vector)->parvector;
    }
    else
      if (vector_type == 1111) {
        part = 0;
        var = 0;
        pvector = (vector)->pvectors[part];
        svector = (pvector)->svectors[var];
        *object = svector;
      }
  return ierr;
}
int HYPRE_SStructVectorPrint(char* filename, HYPRE_SStructVector vector, int all) {
  int ierr = 0;
  int nparts = (vector)->nparts;
  int part;
  char  new_filename[255];
  for (part = 0; part < nparts; part++) {
    sprintf(new_filename, "%s.%02d", filename, part);
    hypre_SStructPVectorPrint(new_filename, (vector)->pvectors[part], all);
  }
  return ierr;
}
//======================== box_map.c =======================
int hypre_BoxMapEntryGetInfo(hypre_BoxMapEntry* entry, void** info_ptr) {
  int ierr = 0;
  *info_ptr = (entry)->info;
  return ierr;
}
int hypre_BoxMapEntryGetExtents(hypre_BoxMapEntry* entry, hypre_Index imin, hypre_Index imax) {
  int ierr = 0;
  hypre_IndexRef entry_imin = (entry)->imin;
  hypre_IndexRef entry_imax = (entry)->imax;
  int d;
  for (d = 0; d < 3; d++) {
    imin[d] = entry_imin[d];
    imax[d] = entry_imax[d];
  }
  return ierr;
}
int hypre_BoxMapCreate(int max_nentries, hypre_Index global_imin, hypre_Index global_imax, int nprocs, hypre_BoxMap** map_ptr) {
  int ierr = 0;
  hypre_BoxMap* map;
  hypre_IndexRef global_imin_ref;
  hypre_IndexRef global_imax_ref;
  int d;
  int i;
  map = (hypre_BoxMap*)(hypre_CAlloc((unsigned)1, (unsigned)(sizeof(hypre_BoxMap))));
  (map)->max_nentries = max_nentries;
  global_imin_ref = (map)->global_imin;
  global_imax_ref = (map)->global_imax;
  for (d = 0; d < 3; d++) {
    global_imin_ref[d] = global_imin[d];
    global_imax_ref[d] = global_imax[d];
    (map)->indexes[d] = (void*)0;
  }
  (map)->nentries = 0;
  (map)->entries = (hypre_BoxMapEntry*)(hypre_CAlloc((unsigned)max_nentries, (unsigned)(sizeof(hypre_BoxMapEntry))));
  (map)->table = (void*)0;
  (map)->boxproc_table = (void*)0;
  (map)->boxproc_offset = (int*)(hypre_CAlloc((unsigned)nprocs, (unsigned)(sizeof(int))));
  for (i = 0; i < 6; i++) {
    (map)->num_ghost[i] = 0;
  }
  *map_ptr = map;
  return ierr;
}
int hypre_BoxMapIncSize(hypre_BoxMap* map, int inc_nentries) {
  int ierr = 0;
  int max_nentries = (map)->max_nentries;
  hypre_BoxMapEntry* entries = (map)->entries;
  max_nentries += inc_nentries;
  entries = (hypre_BoxMapEntry*)(hypre_ReAlloc((char*)entries, (unsigned)(sizeof(hypre_BoxMapEntry) * max_nentries)));
  (map)->max_nentries = max_nentries;
  (map)->entries = entries;
  return ierr;
}
int hypre_BoxMapAddEntry(hypre_BoxMap* map, hypre_Index imin, hypre_Index imax, void* info) {
  int ierr = 0;
  int nentries = (map)->nentries;
  hypre_BoxMapEntry* entries = (map)->entries;
  hypre_BoxMapEntry* entry;
  hypre_IndexRef entry_imin;
  hypre_IndexRef entry_imax;
  int d;
  int* num_ghost = (map)->num_ghost;
  entry = &(entries[nentries]);
  entry_imin = (entry)->imin;
  entry_imax = (entry)->imax;
  for (d = 0; d < 3; d++) {
    entry_imin[d] = imin[d];
    entry_imax[d] = imax[d];
  }
  (entry)->info = info;
  (map)->nentries = nentries + 1;
  for (d = 0; d < 6; d++) {
    (entry)->num_ghost[d] = num_ghost[d];
  }
  (entry)->next = (void*)0;
  return ierr;
}
int hypre_BoxMapAssemble(hypre_BoxMap* map, MPI_Comm comm) {
  int ierr = 0;
  int nentries = (map)->nentries;
  hypre_BoxMapEntry* entries = (map)->entries;
  hypre_BoxMapEntry** table;
  int*  indexes[3];
  int  size[3];
  hypre_BoxMapEntry* entry;
  hypre_IndexRef entry_imin;
  hypre_IndexRef entry_imax;
  int  imin[3];
  int  imax[3];
  int  iminmax[2];
  int index_not_there;
  int b;
  int d;
  int i;
  int j;
  int k;
  int l;
  int myproc;
  int proc;
  int* proc_entries;
  int* nproc_entries;
  int pcnt;
  int npcnt;
  MPI_Comm_rank(comm, &(myproc));
  (map)->boxproc_table = entries;
  for (d = 0; d < 3; d++) {
    indexes[d] = (int*)(hypre_CAlloc((unsigned)(2 * nentries), (unsigned)(sizeof(int))));
    size[d] = 0;
  }
  proc_entries = (int*)(hypre_CAlloc((unsigned)nentries, (unsigned)(sizeof(int))));
  nproc_entries = (int*)(hypre_CAlloc((unsigned)nentries, (unsigned)(sizeof(int))));
  pcnt = 0;
  npcnt = 0;
  for (b = 0; b < nentries; b++) {
    entry = &(entries[b]);
    entry_imin = (entry)->imin;
    entry_imax = (entry)->imax;
    hypre_SStructMapEntryGetProcess(entry, &(proc));
    if (proc != myproc) {
      nproc_entries[npcnt++] = b;
    }
    else {
      proc_entries[pcnt++] = b;
    }
    for (d = 0; d < 3; d++) {
      iminmax[0] = entry_imin[d];
      iminmax[1] = (entry_imax[d]) + 1;
      for (i = 0; i < 2; i++) {
        index_not_there = 1;
        for (j = 0; j < (size[d]); j++) {
          if ((iminmax[i]) <= (indexes[d][j])) {
            if ((iminmax[i]) == (indexes[d][j])) {
              index_not_there = 0;
            }
            break;
          }
        }
        if (index_not_there) {
          for (k = size[d]; k > j; k--) {
            indexes[d][k] = indexes[d][k - 1];
          }
          indexes[d][j] = iminmax[i];
          size[d]++;
        }
      }
    }
  }
  for (d = 0; d < 3; d++) {
    size[d]--;
  }
  table = (hypre_BoxMapEntry**)(hypre_CAlloc((unsigned)(((size[0]) * (size[1])) * (size[2])), (unsigned)(sizeof(hypre_BoxMapEntry*))));
  for (l = 0; l < npcnt; l++) {
    b = nproc_entries[l];
    entry = &(entries[b]);
    entry_imin = (entry)->imin;
    entry_imax = (entry)->imax;
    for (d = 0; d < 3; d++) {
      j = 0;
      while ((entry_imin[d]) != (indexes[d][j])) {
        j++;
      }
      imin[d] = j;
      while (((entry_imax[d]) + 1) != (indexes[d][j])) {
        j++;
      }
      imax[d] = j;
    }
    for (k = imin[2]; k < (imax[2]); k++) {
      for (j = imin[1]; j < (imax[1]); j++) {
        for (i = imin[0]; i < (imax[0]); i++) {
          if (!(table[(((k * (size[1])) + j) * (size[0])) + i])) {
            table[(((k * (size[1])) + j) * (size[0])) + i] = entry;
          }
          else {
            (entry)->next = table[(((k * (size[1])) + j) * (size[0])) + i];
            table[(((k * (size[1])) + j) * (size[0])) + i] = entry;
          }
        }
      }
    }
  }
  for (l = 0; l < pcnt; l++) {
    b = proc_entries[l];
    entry = &(entries[b]);
    entry_imin = (entry)->imin;
    entry_imax = (entry)->imax;
    for (d = 0; d < 3; d++) {
      j = 0;
      while ((entry_imin[d]) != (indexes[d][j])) {
        j++;
      }
      imin[d] = j;
      while (((entry_imax[d]) + 1) != (indexes[d][j])) {
        j++;
      }
      imax[d] = j;
    }
    for (k = imin[2]; k < (imax[2]); k++) {
      for (j = imin[1]; j < (imax[1]); j++) {
        for (i = imin[0]; i < (imax[0]); i++) {
          if (!(table[(((k * (size[1])) + j) * (size[0])) + i])) {
            table[(((k * (size[1])) + j) * (size[0])) + i] = entry;
          }
          else {
            (entry)->next = table[(((k * (size[1])) + j) * (size[0])) + i];
            table[(((k * (size[1])) + j) * (size[0])) + i] = entry;
          }
        }
      }
    }
  }
  hypre_Free((char*)proc_entries), proc_entries = (void*)0;
  hypre_Free((char*)nproc_entries), nproc_entries = (void*)0;
  hypre_Free((char*)((map)->table)), (map)->table = (void*)0;
  (map)->table = table;
  for (d = 0; d < 3; d++) {
    hypre_Free((char*)((map)->indexes[d])), (map)->indexes[d] = (void*)0;
    (map)->indexes[d] = indexes[d];
    (map)->size[d] = size[d];
    (map)->last_index[d] = 0;
  }
  return ierr;
}
int hypre_BoxMapDestroy(hypre_BoxMap* map) {
  int ierr = 0;
  int d;
  if (map) {
    hypre_Free((char*)((map)->entries)), (map)->entries = (void*)0;
    hypre_Free((char*)((map)->table)), (map)->table = (void*)0;
    hypre_Free((char*)((map)->boxproc_offset)), (map)->boxproc_offset = (void*)0;
    for (d = 0; d < 3; d++) {
      hypre_Free((char*)((map)->indexes[d])), (map)->indexes[d] = (void*)0;
    }
    hypre_Free((char*)map), map = (void*)0;
  }
  return ierr;
}
int hypre_BoxMapFindEntry(hypre_BoxMap* map, hypre_Index index, hypre_BoxMapEntry** entry_ptr) {
  int ierr = 0;
  int index_d;
  int  map_index[3] = {0, 0, 0};
  int* map_indexes_d;
  int map_index_d;
  int map_size_d;
  int d;
  for (d = 0; d < 3; d++) {
    map_indexes_d = (map)->indexes[d];
    map_size_d = (map)->size[d];
    index_d = index[d];
    map_index_d = (map)->last_index[d];
    while ((map_index_d >= 0) && (index_d < (map_indexes_d[map_index_d]))) {
      map_index_d--;
    }
    while ((map_index_d <= (map_size_d - 1)) && (index_d >= (map_indexes_d[map_index_d + 1]))) {
      map_index_d++;
    }
    if ((map_index_d < 0) || (map_index_d > (map_size_d - 1))) {
      *entry_ptr = (void*)0;
      return ierr;
    }
    else {
      map_index[d] = map_index_d;
    }
  }
  *entry_ptr = (map)->table[((((map_index[2]) * ((map)->size[1])) + (map_index[1])) * ((map)->size[0])) + (map_index[0])];
  for (d = 0; d < 3; d++) {
    (map)->last_index[d] = map_index[d];
  }
  return ierr;
}
int hypre_BoxMapFindBoxProcEntry(hypre_BoxMap* map, int box, int proc, hypre_BoxMapEntry** entry_ptr) {
  int ierr = 0;
  *entry_ptr = &((map)->boxproc_table[box + ((map)->boxproc_offset[proc])]);
  return ierr;
}
int hypre_BoxMapIntersect(hypre_BoxMap* map, hypre_Index ilower, hypre_Index iupper, hypre_BoxMapEntry*** entries_ptr, int* nentries_ptr) {
  int ierr = 0;
  hypre_BoxMapEntry** entries;
  hypre_BoxMapEntry** all_entries;
  hypre_BoxMapEntry* entry;
  int nentries;
  int index_d;
  int  map_ilower[3] = {0, 0, 0};
  int  map_iupper[3] = {0, 0, 0};
  int* map_indexes_d;
  int map_index_d;
  int map_size_d;
  int d;
  int i;
  int j;
  int k;
  hypre_SStructMapInfo* info;
  int* ii;
  int* jj;
  int* kk;
  int cnt;
  int* offsets;
  int* unsort;
  for (d = 0; d < 3; d++) {
    map_indexes_d = (map)->indexes[d];
    map_size_d = (map)->size[d];
    index_d = ilower[d];
    map_index_d = (map)->last_index[d];
    while ((map_index_d >= 0) && (index_d < (map_indexes_d[map_index_d]))) {
      map_index_d--;
    }
    while ((map_index_d <= (map_size_d - 1)) && (index_d >= (map_indexes_d[map_index_d + 1]))) {
      map_index_d++;
    }
    if (map_index_d > (map_size_d - 1)) {
      *entries_ptr = (void*)0;
      *nentries_ptr = 0;
      return ierr;
    }
    else {
      map_ilower[d] = map_index_d < 0 ? 0 : map_index_d;
    }
    index_d = iupper[d];
    while ((map_index_d <= (map_size_d - 1)) && (index_d >= (map_indexes_d[map_index_d + 1]))) {
      map_index_d++;
    }
    if (map_index_d < 0) {
      *entries_ptr = (void*)0;
      *nentries_ptr = 0;
      return ierr;
    }
    else {
      map_iupper[d] = (map_index_d < (map_size_d - 1) ? map_index_d : map_size_d - 1) + 1;
    }
  }
  nentries = (((map_iupper[0]) - (map_ilower[0])) * ((map_iupper[1]) - (map_ilower[1]))) * ((map_iupper[2]) - (map_ilower[2]));
  ii = (int*)(hypre_CAlloc((unsigned)nentries, (unsigned)(sizeof(int))));
  jj = (int*)(hypre_CAlloc((unsigned)nentries, (unsigned)(sizeof(int))));
  kk = (int*)(hypre_CAlloc((unsigned)nentries, (unsigned)(sizeof(int))));
  nentries = 0;
  cnt = 0;
  for (k = map_ilower[2]; k < (map_iupper[2]); k++) {
    for (j = map_ilower[1]; j < (map_iupper[1]); j++) {
      for (i = map_ilower[0]; i < (map_iupper[0]); i++) {
        if (k > (map_ilower[2])) {
          if (((map)->table[(((k * ((map)->size[1])) + j) * ((map)->size[0])) + i]) == ((map)->table[((((k - 1) * ((map)->size[1])) + j) * ((map)->size[0])) + i])) {
            continue;
          }
        }
        if (j > (map_ilower[1])) {
          if (((map)->table[(((k * ((map)->size[1])) + j) * ((map)->size[0])) + i]) == ((map)->table[(((k * ((map)->size[1])) + (j - 1)) * ((map)->size[0])) + i])) {
            continue;
          }
        }
        if (i > (map_ilower[0])) {
          if (((map)->table[(((k * ((map)->size[1])) + j) * ((map)->size[0])) + i]) == ((map)->table[(((k * ((map)->size[1])) + j) * ((map)->size[0])) + (i - 1)])) {
            continue;
          }
        }
        entry = (map)->table[(((k * ((map)->size[1])) + j) * ((map)->size[0])) + i];
        if (entry != (void*)0) {
          ii[nentries] = i;
          jj[nentries] = j;
          kk[nentries++] = k;
          while (entry) {
            cnt++;
            entry = (entry)->next;
          }
        }
      }
    }
  }
  if (nentries == cnt) {
    entries = (hypre_BoxMapEntry**)(hypre_CAlloc((unsigned)nentries, (unsigned)(sizeof(hypre_BoxMapEntry*))));
    for (i = 0; i < nentries; i++) {
      entries[i] = (map)->table[((((kk[i]) * ((map)->size[1])) + (jj[i])) * ((map)->size[0])) + (ii[i])];
    }
  }
  else {
    unsort = (int*)(hypre_CAlloc((unsigned)cnt, (unsigned)(sizeof(int))));
    offsets = (int*)(hypre_CAlloc((unsigned)cnt, (unsigned)(sizeof(int))));
    all_entries = (hypre_BoxMapEntry**)(hypre_CAlloc((unsigned)cnt, (unsigned)(sizeof(hypre_BoxMapEntry*))));
    cnt = 0;
    for (i = 0; i < nentries; i++) {
      entry = (map)->table[((((kk[i]) * ((map)->size[1])) + (jj[i])) * ((map)->size[0])) + (ii[i])];
      while (entry) {
        all_entries[cnt] = entry;
        unsort[cnt] = cnt;
        info = (hypre_SStructMapInfo*)((entry)->info);
        offsets[cnt++] = (info)->offset;
        entry = (entry)->next;
      }
    }
    hypre_BigQsortbi(offsets, unsort, 0, cnt - 1);
    nentries = 1;
    for (i = 1; i < cnt; i++) {
      if ((offsets[i]) != (offsets[i - 1])) {
        nentries++;
      }
    }
    entries = (hypre_BoxMapEntry**)(hypre_CAlloc((unsigned)nentries, (unsigned)(sizeof(hypre_BoxMapEntry*))));
    entries[0] = all_entries[unsort[0]];
    nentries = 1;
    for (i = 1; i < cnt; i++) {
      if ((offsets[i]) != (offsets[i - 1])) {
        entries[nentries++] = all_entries[unsort[i]];
      }
    }
    hypre_Free((char*)unsort), unsort = (void*)0;
    hypre_Free((char*)offsets), offsets = (void*)0;
    hypre_Free((char*)all_entries), all_entries = (void*)0;
  }
  hypre_Free((char*)ii), ii = (void*)0;
  hypre_Free((char*)jj), jj = (void*)0;
  hypre_Free((char*)kk), kk = (void*)0;
  for (d = 0; d < 3; d++) {
    (map)->last_index[d] = map_ilower[d];
  }
  *entries_ptr = entries;
  *nentries_ptr = nentries;
  return ierr;
}
int hypre_BoxMapSetNumGhost(hypre_BoxMap* map, int* num_ghost) {
  int ierr = 0;
  int i;
  for (i = 0; i < 6; i++) {
    (map)->num_ghost[i] = num_ghost[i];
  }
  return ierr;
}
//===================== sstruct_graph.c ====================
int hypre_SStructGraphRef(hypre_SStructGraph* graph, hypre_SStructGraph** graph_ref) {
  (graph)->ref_count++;
  *graph_ref = graph;
  return 0;
}
int hypre_SStructGraphFindUVEntry(hypre_SStructGraph* graph, int part, hypre_Index index, int var, hypre_SStructUVEntry** Uventry_ptr) {
  int ierr = 0;
  hypre_SStructUVEntry** Uventries = (graph)->Uventries;
  hypre_SStructGrid* grid = (graph)->grid;
  int type = (graph)->type;
  hypre_BoxMapEntry* map_entry;
  int big_rank;
  int rank;
  hypre_SStructGridFindMapEntry(grid, part, index, var, &(map_entry));
  hypre_SStructMapEntryGetGlobalRank(map_entry, index, &(big_rank), type);
  if ((type == 3333) || (type == 1111)) {
    rank = (int)(big_rank - (grid)->ghstart_rank);
  }
  if (type == 5555) {
    rank = (int)(big_rank - (grid)->start_rank);
  }
  *Uventry_ptr = Uventries[rank];
  return ierr;
}
//===================== sstruct_grid.c =====================
int hypre_SStructVariableGetOffset(HYPRE_SStructVariable vartype, int ndim, hypre_Index varoffset) {
  int ierr = 0;
  int d;
  switch (vartype) {
    case HYPRE_SSTRUCT_VARIABLE_CELL:
      varoffset[0] = 0, varoffset[1] = 0, varoffset[2] = 0;
      break;
    case HYPRE_SSTRUCT_VARIABLE_NODE:
      varoffset[0] = 1, varoffset[1] = 1, varoffset[2] = 1;
      break;
    case HYPRE_SSTRUCT_VARIABLE_XFACE:
      varoffset[0] = 1, varoffset[1] = 0, varoffset[2] = 0;
      break;
    case HYPRE_SSTRUCT_VARIABLE_YFACE:
      varoffset[0] = 0, varoffset[1] = 1, varoffset[2] = 0;
      break;
    case HYPRE_SSTRUCT_VARIABLE_ZFACE:
      varoffset[0] = 0, varoffset[1] = 0, varoffset[2] = 1;
      break;
    case HYPRE_SSTRUCT_VARIABLE_XEDGE:
      varoffset[0] = 0, varoffset[1] = 1, varoffset[2] = 1;
      break;
    case HYPRE_SSTRUCT_VARIABLE_YEDGE:
      varoffset[0] = 1, varoffset[1] = 0, varoffset[2] = 1;
      break;
    case HYPRE_SSTRUCT_VARIABLE_ZEDGE:
      varoffset[0] = 1, varoffset[1] = 1, varoffset[2] = 0;
      break;
    case HYPRE_SSTRUCT_VARIABLE_UNDEFINED:
      break;
  }
  for (d = ndim; d < 3; d++) {
    varoffset[d] = 0;
  }
  return ierr;
}
int hypre_SStructPGridCreate(MPI_Comm comm, int ndim, hypre_SStructPGrid** pgrid_ptr) {
  int ierr = 0;
  hypre_SStructPGrid* pgrid;
  hypre_StructGrid* sgrid;
  int t;
  pgrid = (hypre_SStructPGrid*)(hypre_MAlloc((unsigned)(sizeof(hypre_SStructPGrid) * 1)));
  (pgrid)->comm = comm;
  (pgrid)->ndim = ndim;
  (pgrid)->nvars = 0;
  (pgrid)->cell_sgrid_done = 0;
  (pgrid)->vartypes = (void*)0;
  for (t = 0; t < 8; t++) {
    (pgrid)->sgrids[t] = (void*)0;
    (pgrid)->iboxarrays[t] = (void*)0;
  }
  HYPRE_StructGridCreate(comm, ndim, &(sgrid));
  (pgrid)->sgrids[HYPRE_SSTRUCT_VARIABLE_CELL] = sgrid;
  (pgrid)->pneighbors = hypre_BoxArrayCreate(0);
  (pgrid)->local_size = 0;
  (pgrid)->global_size = 0;
  (pgrid)->ghlocal_size = 0;
  (pgrid)->periodic[0] = 0, (pgrid)->periodic[1] = 0, (pgrid)->periodic[2] = 0;
  *pgrid_ptr = pgrid;
  return ierr;
}
int hypre_SStructPGridDestroy(hypre_SStructPGrid* pgrid) {
  int ierr = 0;
  hypre_StructGrid** sgrids;
  hypre_BoxArray** iboxarrays;
  int t;
  if (pgrid) {
    sgrids = (pgrid)->sgrids;
    iboxarrays = (pgrid)->iboxarrays;
    hypre_Free((char*)((pgrid)->vartypes)), (pgrid)->vartypes = (void*)0;
    for (t = 0; t < 8; t++) {
      HYPRE_StructGridDestroy(sgrids[t]);
      hypre_BoxArrayDestroy(iboxarrays[t]);
    }
    hypre_BoxArrayDestroy((pgrid)->pneighbors);
    hypre_Free((char*)pgrid), pgrid = (void*)0;
  }
  return ierr;
}
int hypre_SStructPGridSetExtents(hypre_SStructPGrid* pgrid, hypre_Index ilower, hypre_Index iupper) {
  hypre_StructGrid* sgrid = (pgrid)->sgrids[HYPRE_SSTRUCT_VARIABLE_CELL];
  return HYPRE_StructGridSetExtents(sgrid, ilower, iupper);
}
int hypre_SStructPGridSetVariables(hypre_SStructPGrid* pgrid, int nvars, HYPRE_SStructVariable* vartypes) {
  int ierr = 0;
  hypre_SStructVariable* new_vartypes;
  int i;
  hypre_Free((char*)((pgrid)->vartypes)), (pgrid)->vartypes = (void*)0;
  new_vartypes = (hypre_SStructVariable*)(hypre_MAlloc((unsigned)(sizeof(hypre_SStructVariable) * nvars)));
  for (i = 0; i < nvars; i++) {
    new_vartypes[i] = vartypes[i];
  }
  (pgrid)->nvars = nvars;
  (pgrid)->vartypes = new_vartypes;
  return ierr;
}
int hypre_SStructPGridSetPNeighbor(hypre_SStructPGrid* pgrid, hypre_Box* pneighbor_box) {
  int ierr = 0;
  hypre_AppendBox(pneighbor_box, (pgrid)->pneighbors);
  return ierr;
}
int hypre_SStructPGridAssemble(hypre_SStructPGrid* pgrid) {
  int ierr = 0;
  MPI_Comm comm = (pgrid)->comm;
  int ndim = (pgrid)->ndim;
  int nvars = (pgrid)->nvars;
  HYPRE_SStructVariable* vartypes = (pgrid)->vartypes;
  hypre_StructGrid** sgrids = (pgrid)->sgrids;
  hypre_BoxArray** iboxarrays = (pgrid)->iboxarrays;
  hypre_BoxArray* pneighbors = (pgrid)->pneighbors;
  hypre_IndexRef periodic = (pgrid)->periodic;
  hypre_StructGrid* cell_sgrid;
  hypre_IndexRef cell_imax;
  hypre_StructGrid* sgrid;
  hypre_BoxArray* iboxarray;
  hypre_BoxNeighbors* hood;
  hypre_BoxArray* hood_boxes;
  int hood_first_local;
  int hood_num_local;
  hypre_BoxArray* nbor_boxes;
  hypre_BoxArray* diff_boxes;
  hypre_BoxArray* tmp_boxes;
  hypre_BoxArray* boxes;
  hypre_Box* box;
  hypre_Index varoffset;
  int pneighbors_size;
  int nbor_boxes_size;
  int t;
  int var;
  int i;
  int j;
  int d;
  cell_sgrid = (pgrid)->sgrids[HYPRE_SSTRUCT_VARIABLE_CELL];
  HYPRE_StructGridSetPeriodic(cell_sgrid, periodic);
  if (!(pgrid)->cell_sgrid_done)
    HYPRE_StructGridAssemble(cell_sgrid);
  cell_imax = ((cell_sgrid)->bounding_box)->imax;
  hood = (cell_sgrid)->neighbors;
  hood_boxes = (hood)->boxes;
  hood_first_local = (hood)->first_local;
  hood_num_local = (hood)->num_local;
  pneighbors_size = (pneighbors)->size;
  nbor_boxes_size = (pneighbors_size + hood_first_local) + hood_num_local;
  nbor_boxes = hypre_BoxArrayCreate(nbor_boxes_size);
  diff_boxes = hypre_BoxArrayCreate(0);
  tmp_boxes = hypre_BoxArrayCreate(0);
  for (var = 0; var < nvars; var++) {
    t = vartypes[var];
    if ((t > 0) && ((sgrids[t]) == (void*)0)) {
      HYPRE_StructGridCreate(comm, ndim, &(sgrid));
      boxes = hypre_BoxArrayCreate(0);
      hypre_SStructVariableGetOffset((hypre_SStructVariable)t, ndim, varoffset);
      for (i = 0; i < pneighbors_size; i++) {
        (&((nbor_boxes)->boxes[i]))->imin[0] = (&((pneighbors)->boxes[i]))->imin[0], (&((nbor_boxes)->boxes[i]))->imin[1] = (&((pneighbors)->boxes[i]))->imin[1], (&((nbor_boxes)->boxes[i]))->imin[2] = (&((pneighbors)->boxes[i]))->imin[2], (&((nbor_boxes)->boxes[i]))->imax[0] = (&((pneighbors)->boxes[i]))->imax[0], (&((nbor_boxes)->boxes[i]))->imax[1] = (&((pneighbors)->boxes[i]))->imax[1], (&((nbor_boxes)->boxes[i]))->imax[2] = (&((pneighbors)->boxes[i]))->imax[2];
      }
      for (i = 0; i < (hood_first_local + hood_num_local); i++) {
        (&((nbor_boxes)->boxes[pneighbors_size + i]))->imin[0] = (&((hood_boxes)->boxes[i]))->imin[0], (&((nbor_boxes)->boxes[pneighbors_size + i]))->imin[1] = (&((hood_boxes)->boxes[i]))->imin[1], (&((nbor_boxes)->boxes[pneighbors_size + i]))->imin[2] = (&((hood_boxes)->boxes[i]))->imin[2], (&((nbor_boxes)->boxes[pneighbors_size + i]))->imax[0] = (&((hood_boxes)->boxes[i]))->imax[0], (&((nbor_boxes)->boxes[pneighbors_size + i]))->imax[1] = (&((hood_boxes)->boxes[i]))->imax[1], (&((nbor_boxes)->boxes[pneighbors_size + i]))->imax[2] = (&((hood_boxes)->boxes[i]))->imax[2];
      }
      for (i = 0; i < nbor_boxes_size; i++) {
        box = &((nbor_boxes)->boxes[i]);
        ((box)->imin[0]) -= (varoffset[0]);
        ((box)->imin[1]) -= (varoffset[1]);
        ((box)->imin[2]) -= (varoffset[2]);
      }
      for (i = 0; i < hood_num_local; i++) {
        j = (pneighbors_size + hood_first_local) + i;
        hypre_BoxArraySetSize(diff_boxes, 1);
        (&((diff_boxes)->boxes[0]))->imin[0] = (&((nbor_boxes)->boxes[j]))->imin[0], (&((diff_boxes)->boxes[0]))->imin[1] = (&((nbor_boxes)->boxes[j]))->imin[1], (&((diff_boxes)->boxes[0]))->imin[2] = (&((nbor_boxes)->boxes[j]))->imin[2], (&((diff_boxes)->boxes[0]))->imax[0] = (&((nbor_boxes)->boxes[j]))->imax[0], (&((diff_boxes)->boxes[0]))->imax[1] = (&((nbor_boxes)->boxes[j]))->imax[1], (&((diff_boxes)->boxes[0]))->imax[2] = (&((nbor_boxes)->boxes[j]))->imax[2];
        hypre_BoxArraySetSize(nbor_boxes, j);
        hypre_SubtractBoxArrays(diff_boxes, nbor_boxes, tmp_boxes);
        hypre_AppendBoxArray(diff_boxes, boxes);
      }
      for (d = 0; d < 3; d++) {
        if ((periodic[d]) && (varoffset[d])) {
          for (i = 0; i < (boxes)->size; i++) {
            box = &((boxes)->boxes[i]);
            if (((box)->imax[d]) == (cell_imax[d])) {
              (box)->imax[d]--;
            }
          }
        }
      }
      HYPRE_StructGridSetPeriodic(sgrid, periodic);
      hypre_StructGridSetBoxes(sgrid, boxes);
      HYPRE_StructGridAssemble(sgrid);
      sgrids[t] = sgrid;
    }
  }
  hypre_BoxArrayDestroy(nbor_boxes);
  hypre_BoxArrayDestroy(diff_boxes);
  hypre_BoxArrayDestroy(tmp_boxes);
  for (t = 0; t < 8; t++) {
    sgrid = sgrids[t];
    if (sgrid != (void*)0) {
      iboxarray = hypre_BoxArrayDuplicate((sgrid)->boxes);
      hypre_SStructVariableGetOffset((hypre_SStructVariable)t, ndim, varoffset);
      for (i = 0; i < (iboxarray)->size; i++) {
        box = &((iboxarray)->boxes[i]);
        ((box)->imin[0]) -= (varoffset[0]);
        ((box)->imin[1]) -= (varoffset[1]);
        ((box)->imin[2]) -= (varoffset[2]);
        (box)->imax[0] += varoffset[0];
        (box)->imax[1] += varoffset[1];
        (box)->imax[2] += varoffset[2];
      }
      iboxarrays[t] = iboxarray;
    }
  }
  for (var = 0; var < nvars; var++) {
    sgrid = (pgrid)->sgrids[(pgrid)->vartypes[var]];
    (pgrid)->local_size += (sgrid)->local_size;
    (pgrid)->global_size += (sgrid)->global_size;
    (pgrid)->ghlocal_size += (sgrid)->ghlocal_size;
  }
  return ierr;
}
int hypre_SStructGridRef(hypre_SStructGrid* grid, hypre_SStructGrid** grid_ref) {
  (grid)->ref_count++;
  *grid_ref = grid;
  return 0;
}
int hypre_SStructGridAssembleMaps(hypre_SStructGrid* grid) {
  int ierr = 0;
  MPI_Comm comm = (grid)->comm;
  int nparts = (grid)->nparts;
  int local_size = (grid)->local_size;
  hypre_BoxMap*** maps;
  hypre_SStructMapInfo*** info;
  hypre_SStructPGrid* pgrid;
  int nvars;
  hypre_StructGrid* sgrid;
  hypre_Box* bounding_box;
  int* offsets;
  hypre_SStructMapInfo* entry_info;
  hypre_BoxArray* boxes;
  hypre_Box* box;
  int* procs;
  int* local_boxnums;
  int* boxproc_offset;
  int first_local;
  int nprocs;
  int myproc;
  int proc;
  int part;
  int var;
  int b;
  hypre_Box* ghostbox;
  int* num_ghost;
  int* ghoffsets;
  int ghlocal_size = (grid)->ghlocal_size;
  int tmp_big_int;
  MPI_Comm_size(comm, &(nprocs));
  MPI_Comm_rank(comm, &(myproc));
  offsets = (int*)(hypre_MAlloc((unsigned)(sizeof(int) * (nprocs + 1))));
  offsets[0] = 0;
  tmp_big_int = (int)local_size;
  MPI_Allgather(&(tmp_big_int), 1, MPI_INT, &(offsets[1]), 1, MPI_INT, comm);
  ghoffsets = (int*)(hypre_MAlloc((unsigned)(sizeof(int) * (nprocs + 1))));
  ghoffsets[0] = 0;
  tmp_big_int = (int)ghlocal_size;
  MPI_Allgather(&(tmp_big_int), 1, MPI_INT, &(ghoffsets[1]), 1, MPI_INT, comm);
  for (proc = 1; proc < (nprocs + 1); proc++) {
    offsets[proc] += offsets[proc - 1];
    ghoffsets[proc] += ghoffsets[proc - 1];
  }
  (grid)->start_rank = offsets[myproc];
  (grid)->ghstart_rank = ghoffsets[myproc];
  maps = (hypre_BoxMap***)(hypre_MAlloc((unsigned)(sizeof(hypre_BoxMap**) * nparts)));
  info = (hypre_SStructMapInfo***)(hypre_MAlloc((unsigned)(sizeof(hypre_SStructMapInfo**) * nparts)));
  for (part = 0; part < nparts; part++) {
    pgrid = (grid)->pgrids[part];
    nvars = (pgrid)->nvars;
    maps[part] = (hypre_BoxMap**)(hypre_MAlloc((unsigned)(sizeof(hypre_BoxMap*) * nvars)));
    info[part] = (hypre_SStructMapInfo**)(hypre_MAlloc((unsigned)(sizeof(hypre_SStructMapInfo*) * nvars)));
    for (var = 0; var < nvars; var++) {
      sgrid = (pgrid)->sgrids[(pgrid)->vartypes[var]];
      hypre_GatherAllBoxes(comm, (sgrid)->boxes, &(boxes), &(procs), &(first_local));
      bounding_box = (sgrid)->bounding_box;
      hypre_ComputeBoxnums(boxes, procs, &(local_boxnums));
      hypre_BoxMapCreate((boxes)->size, (bounding_box)->imin, (bounding_box)->imax, nprocs, &(maps[part][var]));
      info[part][var] = (hypre_SStructMapInfo*)(hypre_MAlloc((unsigned)(sizeof(hypre_SStructMapInfo) * (boxes)->size)));
      num_ghost = (sgrid)->num_ghost;
      hypre_BoxMapSetNumGhost(maps[part][var], num_ghost);
      ghostbox = hypre_BoxCreate();
      boxproc_offset = (maps[part][var])->boxproc_offset;
      proc = -1;
      for (b = 0; b < (boxes)->size; b++) {
        box = &((boxes)->boxes[b]);
        if (proc != (procs[b])) {
          proc = procs[b];
          boxproc_offset[proc] = b;
        }
        entry_info = &(info[part][var][b]);
        (entry_info)->type = hypre_SSTRUCT_MAP_INFO_DEFAULT;
        (entry_info)->proc = proc;
        (entry_info)->offset = offsets[proc];
        (entry_info)->box = local_boxnums[b];
        (entry_info)->ghoffset = ghoffsets[proc];
        hypre_BoxMapAddEntry(maps[part][var], (box)->imin, (box)->imax, entry_info);
        offsets[proc] += (int)(((0 < ((((box)->imax[0]) - ((box)->imin[0])) + 1) ? (((box)->imax[0]) - ((box)->imin[0])) + 1 : 0) * (0 < ((((box)->imax[1]) - ((box)->imin[1])) + 1) ? (((box)->imax[1]) - ((box)->imin[1])) + 1 : 0)) * (0 < ((((box)->imax[2]) - ((box)->imin[2])) + 1) ? (((box)->imax[2]) - ((box)->imin[2])) + 1 : 0));
        (ghostbox)->imin[0] = (box)->imin[0], (ghostbox)->imin[1] = (box)->imin[1], (ghostbox)->imin[2] = (box)->imin[2], (ghostbox)->imax[0] = (box)->imax[0], (ghostbox)->imax[1] = (box)->imax[1], (ghostbox)->imax[2] = (box)->imax[2];
        hypre_BoxExpand(ghostbox, num_ghost);
        ghoffsets[proc] += (int)(((0 < ((((ghostbox)->imax[0]) - ((ghostbox)->imin[0])) + 1) ? (((ghostbox)->imax[0]) - ((ghostbox)->imin[0])) + 1 : 0) * (0 < ((((ghostbox)->imax[1]) - ((ghostbox)->imin[1])) + 1) ? (((ghostbox)->imax[1]) - ((ghostbox)->imin[1])) + 1 : 0)) * (0 < ((((ghostbox)->imax[2]) - ((ghostbox)->imin[2])) + 1) ? (((ghostbox)->imax[2]) - ((ghostbox)->imin[2])) + 1 : 0));
      }
      hypre_BoxDestroy(ghostbox);
      hypre_BoxArrayDestroy(boxes);
      hypre_Free((char*)procs), procs = (void*)0;
      hypre_Free((char*)local_boxnums), local_boxnums = (void*)0;
      hypre_BoxMapAssemble(maps[part][var], comm);
    }
  }
  hypre_Free((char*)offsets), offsets = (void*)0;
  hypre_Free((char*)ghoffsets), ghoffsets = (void*)0;
  (grid)->maps = maps;
  (grid)->info = info;
  return ierr;
}
int hypre_SStructGridAssembleNBorMaps(hypre_SStructGrid* grid) {
  int ierr = 0;
  MPI_Comm comm = (grid)->comm;
  int nparts = (grid)->nparts;
  int** nvneighbors = (grid)->nvneighbors;
  hypre_SStructNeighbor*** vneighbors = (grid)->vneighbors;
  hypre_SStructNeighbor* vneighbor;
  hypre_BoxMap*** maps = (grid)->maps;
  hypre_SStructNMapInfo*** ninfo;
  hypre_SStructPGrid* pgrid;
  int nvars;
  hypre_SStructNMapInfo* entry_ninfo;
  hypre_BoxMapEntry* map_entry;
  hypre_Box* nbor_box;
  hypre_Box* box;
  int nbor_part;
  int nbor_boxnum;
  hypre_Index nbor_ilower;
  int nbor_offset;
  int nbor_proc;
  hypre_Index c;
  int* d;
  int* stride;
  int part;
  int var;
  int b;
  hypre_Box* ghostbox;
  int nbor_ghoffset;
  int* ghstride;
  int* num_ghost;
  box = hypre_BoxCreate();
  ghostbox = hypre_BoxCreate();
  ninfo = (hypre_SStructNMapInfo***)(hypre_MAlloc((unsigned)(sizeof(hypre_SStructNMapInfo**) * nparts)));
  for (part = 0; part < nparts; part++) {
    pgrid = (grid)->pgrids[part];
    nvars = (pgrid)->nvars;
    ninfo[part] = (hypre_SStructNMapInfo**)(hypre_MAlloc((unsigned)(sizeof(hypre_SStructNMapInfo*) * nvars)));
    for (var = 0; var < nvars; var++) {
      ninfo[part][var] = (hypre_SStructNMapInfo*)(hypre_MAlloc((unsigned)(sizeof(hypre_SStructNMapInfo) * (nvneighbors[part][var]))));
      for (b = 0; b < (nvneighbors[part][var]); b++) {
        vneighbor = &(vneighbors[part][var][b]);
        nbor_box = &((vneighbor)->box);
        nbor_part = (vneighbor)->part;
        nbor_ilower[0] = (vneighbor)->ilower[0], nbor_ilower[1] = (vneighbor)->ilower[1], nbor_ilower[2] = (vneighbor)->ilower[2];
        hypre_SStructGridFindMapEntry(grid, nbor_part, nbor_ilower, var, &(map_entry));
        hypre_BoxMapEntryGetExtents(map_entry, (box)->imin, (box)->imax);
        hypre_SStructMapEntryGetProcess(map_entry, &(nbor_proc));
        hypre_SStructMapEntryGetBox(map_entry, &(nbor_boxnum));
        hypre_SStructMapEntryGetGlobalCSRank(map_entry, nbor_ilower, &(nbor_offset));
        hypre_SStructMapEntryGetGlobalGhrank(map_entry, nbor_ilower, &(nbor_ghoffset));
        num_ghost = (map_entry)->num_ghost;
        entry_ninfo = &(ninfo[part][var][b]);
        (entry_ninfo)->type = hypre_SSTRUCT_MAP_INFO_NEIGHBOR;
        (entry_ninfo)->proc = nbor_proc;
        (entry_ninfo)->box = nbor_boxnum;
        (entry_ninfo)->offset = nbor_offset;
        (entry_ninfo)->ghoffset = nbor_ghoffset;
        (entry_ninfo)->part = nbor_part;
        (entry_ninfo)->ilower[0] = nbor_ilower[0], (entry_ninfo)->ilower[1] = nbor_ilower[1], (entry_ninfo)->ilower[2] = nbor_ilower[2];
        (entry_ninfo)->coord[0] = (vneighbor)->coord[0], (entry_ninfo)->coord[1] = (vneighbor)->coord[1], (entry_ninfo)->coord[2] = (vneighbor)->coord[2];
        (entry_ninfo)->dir[0] = (vneighbor)->dir[0], (entry_ninfo)->dir[1] = (vneighbor)->dir[1], (entry_ninfo)->dir[2] = (vneighbor)->dir[2];
        d = (entry_ninfo)->coord;
        c[d[0]] = 0;
        c[d[1]] = 1;
        c[d[2]] = 2;
        d = (entry_ninfo)->dir;
        stride = (entry_ninfo)->stride;
        stride[c[0]] = 1;
        stride[c[1]] = 0 < ((((box)->imax[0]) - ((box)->imin[0])) + 1) ? (((box)->imax[0]) - ((box)->imin[0])) + 1 : 0;
        stride[c[2]] = (0 < ((((box)->imax[1]) - ((box)->imin[1])) + 1) ? (((box)->imax[1]) - ((box)->imin[1])) + 1 : 0) * (stride[c[1]]);
        (stride[c[0]]) -= (d[0]);
        (stride[c[1]]) -= (d[1]);
        (stride[c[2]]) -= (d[2]);
        (ghostbox)->imin[0] = (box)->imin[0], (ghostbox)->imin[1] = (box)->imin[1], (ghostbox)->imin[2] = (box)->imin[2], (ghostbox)->imax[0] = (box)->imax[0], (ghostbox)->imax[1] = (box)->imax[1], (ghostbox)->imax[2] = (box)->imax[2];
        hypre_BoxExpand(ghostbox, num_ghost);
        ghstride = (entry_ninfo)->ghstride;
        ghstride[c[0]] = 1;
        ghstride[c[1]] = 0 < ((((ghostbox)->imax[0]) - ((ghostbox)->imin[0])) + 1) ? (((ghostbox)->imax[0]) - ((ghostbox)->imin[0])) + 1 : 0;
        ghstride[c[2]] = (0 < ((((ghostbox)->imax[1]) - ((ghostbox)->imin[1])) + 1) ? (((ghostbox)->imax[1]) - ((ghostbox)->imin[1])) + 1 : 0) * (ghstride[c[1]]);
        (ghstride[c[0]]) -= (d[0]);
        (ghstride[c[1]]) -= (d[1]);
        (ghstride[c[2]]) -= (d[2]);
      }
    }
    for (var = 0; var < nvars; var++) {
      hypre_BoxMapIncSize(maps[part][var], nvneighbors[part][var]);
      for (b = 0; b < (nvneighbors[part][var]); b++) {
        vneighbor = &(vneighbors[part][var][b]);
        nbor_box = &((vneighbor)->box);
        hypre_BoxMapAddEntry(maps[part][var], (nbor_box)->imin, (nbor_box)->imax, &(ninfo[part][var][b]));
      }
      hypre_BoxMapAssemble(maps[part][var], comm);
    }
  }
  (grid)->ninfo = ninfo;
  hypre_BoxDestroy(box);
  hypre_BoxDestroy(ghostbox);
  return ierr;
}
int hypre_SStructGridFindMapEntry(hypre_SStructGrid* grid, int part, hypre_Index index, int var, hypre_BoxMapEntry** entry_ptr) {
  int ierr = 0;
  hypre_BoxMapFindEntry((grid)->maps[part][var], index, entry_ptr);
  return ierr;
}
int hypre_SStructGridBoxProcFindMapEntry(hypre_SStructGrid* grid, int part, int var, int box, int proc, hypre_BoxMapEntry** entry_ptr) {
  int ierr = 0;
  hypre_BoxMapFindBoxProcEntry((grid)->maps[part][var], box, proc, entry_ptr);
  return ierr;
}
int hypre_SStructMapEntryGetCSRstrides(hypre_BoxMapEntry* entry, hypre_Index strides) {
  int ierr = 0;
  hypre_SStructMapInfo* entry_info;
  hypre_BoxMapEntryGetInfo(entry, (void**)(&(entry_info)));
  if ((entry_info)->type == hypre_SSTRUCT_MAP_INFO_DEFAULT) {
    hypre_Index imin;
    hypre_Index imax;
    hypre_BoxMapEntryGetExtents(entry, imin, imax);
    strides[0] = 1;
    strides[1] = ((imax[0]) - (imin[0])) + 1;
    strides[2] = ((imax[1]) - (imin[1])) + 1;
    (strides[2]) -= (strides[1]);
  }
  else {
    hypre_SStructNMapInfo* entry_ninfo;
    entry_ninfo = (hypre_SStructNMapInfo*)entry_info;
    strides[0] = (entry_ninfo)->stride[0], strides[1] = (entry_ninfo)->stride[1], strides[2] = (entry_ninfo)->stride[2];
  }
  return ierr;
}
int hypre_SStructMapEntryGetGhstrides(hypre_BoxMapEntry* entry, hypre_Index strides) {
  int ierr = 0;
  hypre_SStructMapInfo* entry_info;
  int* numghost;
  int d;
  hypre_BoxMapEntryGetInfo(entry, (void**)(&(entry_info)));
  if ((entry_info)->type == hypre_SSTRUCT_MAP_INFO_DEFAULT) {
    hypre_Index imin;
    hypre_Index imax;
    hypre_BoxMapEntryGetExtents(entry, imin, imax);
    numghost = (entry)->num_ghost;
    for (d = 0; d < 3; d++) {
      imax[d] += numghost[(2 * d) + 1];
      (imin[d]) -= (numghost[2 * d]);
    }
    strides[0] = 1;
    strides[1] = ((imax[0]) - (imin[0])) + 1;
    strides[2] = ((imax[1]) - (imin[1])) + 1;
    (strides[2]) -= (strides[1]);
  }
  else {
    hypre_SStructNMapInfo* entry_ninfo;
    entry_ninfo = (hypre_SStructNMapInfo*)entry_info;
    strides[0] = (entry_ninfo)->ghstride[0], strides[1] = (entry_ninfo)->ghstride[1], strides[2] = (entry_ninfo)->ghstride[2];
  }
  return ierr;
}
int hypre_SStructMapEntryGetGlobalCSRank(hypre_BoxMapEntry* entry, hypre_Index index, int* rank_ptr) {
  int ierr = 0;
  hypre_SStructMapInfo* entry_info;
  hypre_Index imin;
  hypre_Index imax;
  hypre_Index strides;
  int offset;
  hypre_BoxMapEntryGetInfo(entry, (void**)(&(entry_info)));
  hypre_BoxMapEntryGetExtents(entry, imin, imax);
  offset = (entry_info)->offset;
  hypre_SStructMapEntryGetCSRstrides(entry, strides);
  *rank_ptr = offset + (int)(((((index[2]) - (imin[2])) * (strides[2])) + (((index[1]) - (imin[1])) * (strides[1]))) + (((index[0]) - (imin[0])) * (strides[0])));
  return ierr;
}
int hypre_SStructMapEntryGetGlobalGhrank(hypre_BoxMapEntry* entry, hypre_Index index, int* rank_ptr) {
  int ierr = 0;
  hypre_SStructMapInfo* entry_info;
  hypre_Index imin;
  hypre_Index imax;
  hypre_Index ghstrides;
  int ghoffset;
  int* numghost = (entry)->num_ghost;
  int d;
  int info_type;
  hypre_BoxMapEntryGetInfo(entry, (void**)(&(entry_info)));
  hypre_BoxMapEntryGetExtents(entry, imin, imax);
  ghoffset = (entry_info)->ghoffset;
  info_type = (entry_info)->type;
  hypre_SStructMapEntryGetGhstrides(entry, ghstrides);
  if (info_type == hypre_SSTRUCT_MAP_INFO_DEFAULT) {
    for (d = 0; d < 3; d++) {
      (imin[d]) -= (numghost[2 * d]);
    }
  }
  *rank_ptr = ghoffset + (int)(((((index[2]) - (imin[2])) * (ghstrides[2])) + (((index[1]) - (imin[1])) * (ghstrides[1]))) + (((index[0]) - (imin[0])) * (ghstrides[0])));
  return ierr;
}
int hypre_SStructMapEntryGetProcess(hypre_BoxMapEntry* entry, int* proc_ptr) {
  int ierr = 0;
  hypre_SStructMapInfo* entry_info;
  hypre_BoxMapEntryGetInfo(entry, (void**)(&(entry_info)));
  *proc_ptr = (entry_info)->proc;
  return ierr;
}
int hypre_SStructMapEntryGetBox(hypre_BoxMapEntry* entry, int* box_ptr) {
  int ierr = 0;
  hypre_SStructMapInfo* entry_info;
  hypre_BoxMapEntryGetInfo(entry, (void**)(&(entry_info)));
  *box_ptr = (entry_info)->box;
  return ierr;
}
int hypre_SStructBoxToNBorBox(hypre_Box* box, hypre_Index index, hypre_Index nbor_index, hypre_Index coord, hypre_Index dir) {
  int ierr = 0;
  int* imin = (box)->imin;
  int* imax = (box)->imax;
  int  nbor_imin[3];
  int  nbor_imax[3];
  int d;
  int nd;
  for (d = 0; d < 3; d++) {
    nd = coord[d];
    nbor_imin[nd] = (nbor_index[nd]) + (((imin[d]) - (index[d])) * (dir[nd]));
    nbor_imax[nd] = (nbor_index[nd]) + (((imax[d]) - (index[d])) * (dir[nd]));
  }
  for (d = 0; d < 3; d++) {
    imin[d] = (nbor_imin[d]) < (nbor_imax[d]) ? nbor_imin[d] : nbor_imax[d];
    imax[d] = (nbor_imin[d]) < (nbor_imax[d]) ? nbor_imax[d] : nbor_imin[d];
  }
  return ierr;
}
int hypre_SStructNBorBoxToBox(hypre_Box* nbor_box, hypre_Index index, hypre_Index nbor_index, hypre_Index coord, hypre_Index dir) {
  int ierr = 0;
  int* nbor_imin = (nbor_box)->imin;
  int* nbor_imax = (nbor_box)->imax;
  int  imin[3];
  int  imax[3];
  int d;
  int nd;
  for (d = 0; d < 3; d++) {
    nd = coord[d];
    imin[d] = (index[d]) + (((nbor_imin[nd]) - (nbor_index[nd])) * (dir[nd]));
    imax[d] = (index[d]) + (((nbor_imax[nd]) - (nbor_index[nd])) * (dir[nd]));
  }
  for (d = 0; d < 3; d++) {
    nbor_imin[d] = (imin[d]) < (imax[d]) ? imin[d] : imax[d];
    nbor_imax[d] = (imin[d]) < (imax[d]) ? imax[d] : imin[d];
  }
  return ierr;
}
int hypre_SStructMapEntryGetGlobalRank(hypre_BoxMapEntry* entry, hypre_Index index, int* rank_ptr, int type) {
  int ierr = 0;
  if (type == 5555) {
    hypre_SStructMapEntryGetGlobalCSRank(entry, index, rank_ptr);
  }
  if ((type == 3333) || (type == 1111)) {
    hypre_SStructMapEntryGetGlobalGhrank(entry, index, rank_ptr);
  }
  return ierr;
}
int hypre_SStructMapEntryGetStrides(hypre_BoxMapEntry* entry, hypre_Index strides, int type) {
  int ierr = 0;
  if (type == 5555) {
    hypre_SStructMapEntryGetCSRstrides(entry, strides);
  }
  if ((type == 3333) || (type == 1111)) {
    hypre_SStructMapEntryGetGhstrides(entry, strides);
  }
  return ierr;
}
//==================== sstruct_matrix.c ====================
int hypre_SStructPMatrixCreate(MPI_Comm comm, hypre_SStructPGrid* pgrid, hypre_SStructStencil** stencils, hypre_SStructPMatrix** pmatrix_ptr) {
  hypre_SStructPMatrix* pmatrix;
  int nvars;
  int** smaps;
  hypre_StructStencil*** sstencils;
  hypre_StructMatrix*** smatrices;
  int** symmetric;
  hypre_StructStencil* sstencil;
  int* vars;
  hypre_Index* sstencil_shape;
  int sstencil_size;
  int new_dim;
  int* new_sizes;
  hypre_Index** new_shapes;
  int size;
  hypre_StructGrid* sgrid;
  int vi;
  int vj;
  int i;
  int j;
  int k;
  pmatrix = (hypre_SStructPMatrix*)(hypre_MAlloc((unsigned)(sizeof(hypre_SStructPMatrix) * 1)));
  (pmatrix)->comm = comm;
  (pmatrix)->pgrid = pgrid;
  (pmatrix)->stencils = stencils;
  nvars = (pgrid)->nvars;
  (pmatrix)->nvars = nvars;
  smaps = (int**)(hypre_MAlloc((unsigned)(sizeof(int*) * nvars)));
  sstencils = (hypre_StructStencil***)(hypre_MAlloc((unsigned)(sizeof(hypre_StructStencil**) * nvars)));
  new_sizes = (int*)(hypre_MAlloc((unsigned)(sizeof(int) * nvars)));
  new_shapes = (hypre_Index**)(hypre_MAlloc((unsigned)(sizeof(hypre_Index*) * nvars)));
  size = 0;
  for (vi = 0; vi < nvars; vi++) {
    sstencils[vi] = (hypre_StructStencil**)(hypre_MAlloc((unsigned)(sizeof(hypre_StructStencil*) * nvars)));
    for (vj = 0; vj < nvars; vj++) {
      sstencils[vi][vj] = (void*)0;
      new_sizes[vj] = 0;
    }
    sstencil = (stencils[vi])->sstencil;
    vars = (stencils[vi])->vars;
    sstencil_shape = (sstencil)->shape;
    sstencil_size = (sstencil)->size;
    smaps[vi] = (int*)(hypre_MAlloc((unsigned)(sizeof(int) * sstencil_size)));
    for (i = 0; i < sstencil_size; i++) {
      j = vars[i];
      new_sizes[j]++;
    }
    for (vj = 0; vj < nvars; vj++) {
      if (new_sizes[vj]) {
        new_shapes[vj] = (hypre_Index*)(hypre_MAlloc((unsigned)(sizeof(hypre_Index) * (new_sizes[vj]))));
        new_sizes[vj] = 0;
      }
    }
    for (i = 0; i < sstencil_size; i++) {
      j = vars[i];
      k = new_sizes[j];
      new_shapes[j][k][0] = sstencil_shape[i][0], new_shapes[j][k][1] = sstencil_shape[i][1], new_shapes[j][k][2] = sstencil_shape[i][2];
      smaps[vi][i] = k;
      new_sizes[j]++;
    }
    new_dim = (sstencil)->dim;
    for (vj = 0; vj < nvars; vj++) {
      if (new_sizes[vj]) {
        sstencils[vi][vj] = hypre_StructStencilCreate(new_dim, new_sizes[vj], new_shapes[vj]);
      }
      size = size < (new_sizes[vj]) ? new_sizes[vj] : size;
    }
  }
  (pmatrix)->smaps = smaps;
  (pmatrix)->sstencils = sstencils;
  hypre_Free((char*)new_sizes), new_sizes = (void*)0;
  hypre_Free((char*)new_shapes), new_shapes = (void*)0;
  smatrices = (hypre_StructMatrix***)(hypre_MAlloc((unsigned)(sizeof(hypre_StructMatrix**) * nvars)));
  for (vi = 0; vi < nvars; vi++) {
    smatrices[vi] = (hypre_StructMatrix**)(hypre_MAlloc((unsigned)(sizeof(hypre_StructMatrix*) * nvars)));
    for (vj = 0; vj < nvars; vj++) {
      smatrices[vi][vj] = (void*)0;
      if ((sstencils[vi][vj]) != (void*)0) {
        sgrid = (pgrid)->sgrids[(pgrid)->vartypes[vi]];
        smatrices[vi][vj] = hypre_StructMatrixCreate(comm, sgrid, sstencils[vi][vj]);
      }
    }
  }
  (pmatrix)->smatrices = smatrices;
  symmetric = (int**)(hypre_MAlloc((unsigned)(sizeof(int*) * nvars)));
  for (vi = 0; vi < nvars; vi++) {
    symmetric[vi] = (int*)(hypre_MAlloc((unsigned)(sizeof(int) * nvars)));
    for (vj = 0; vj < nvars; vj++) {
      symmetric[vi][vj] = 0;
    }
  }
  (pmatrix)->symmetric = symmetric;
  (pmatrix)->sentries_size = size;
  (pmatrix)->sentries = (int*)(hypre_MAlloc((unsigned)(sizeof(int) * size)));
  (pmatrix)->ref_count = 1;
  *pmatrix_ptr = pmatrix;
  return hypre__global_error;
}
int hypre_SStructPMatrixDestroy(hypre_SStructPMatrix* pmatrix) {
  hypre_SStructStencil** stencils;
  int nvars;
  int** smaps;
  hypre_StructStencil*** sstencils;
  hypre_StructMatrix*** smatrices;
  int** symmetric;
  int vi;
  int vj;
  if (pmatrix) {
    (pmatrix)->ref_count--;
    if ((pmatrix)->ref_count == 0) {
      stencils = (pmatrix)->stencils;
      nvars = (pmatrix)->nvars;
      smaps = (pmatrix)->smaps;
      sstencils = (pmatrix)->sstencils;
      smatrices = (pmatrix)->smatrices;
      symmetric = (pmatrix)->symmetric;
      for (vi = 0; vi < nvars; vi++) {
        HYPRE_SStructStencilDestroy(stencils[vi]);
        hypre_Free((char*)(smaps[vi])), smaps[vi] = (void*)0;
        for (vj = 0; vj < nvars; vj++) {
          hypre_StructStencilDestroy(sstencils[vi][vj]);
          hypre_StructMatrixDestroy(smatrices[vi][vj]);
        }
        hypre_Free((char*)(sstencils[vi])), sstencils[vi] = (void*)0;
        hypre_Free((char*)(smatrices[vi])), smatrices[vi] = (void*)0;
        hypre_Free((char*)(symmetric[vi])), symmetric[vi] = (void*)0;
      }
      hypre_Free((char*)stencils), stencils = (void*)0;
      hypre_Free((char*)smaps), smaps = (void*)0;
      hypre_Free((char*)sstencils), sstencils = (void*)0;
      hypre_Free((char*)smatrices), smatrices = (void*)0;
      hypre_Free((char*)symmetric), symmetric = (void*)0;
      hypre_Free((char*)((pmatrix)->sentries)), (pmatrix)->sentries = (void*)0;
      hypre_Free((char*)pmatrix), pmatrix = (void*)0;
    }
  }
  return hypre__global_error;
}
int hypre_SStructPMatrixInitialize(hypre_SStructPMatrix* pmatrix) {
  int nvars = (pmatrix)->nvars;
  int** symmetric = (pmatrix)->symmetric;
  hypre_SStructPGrid* pgrid = (pmatrix)->pgrid;
  HYPRE_SStructVariable* vartypes = (pgrid)->vartypes;
  int ndim = (pgrid)->ndim;
  int  num_ghost[6] = {1, 1, 1, 1, 1, 1};
  hypre_StructMatrix* smatrix;
  hypre_StructGrid* sgrid;
  hypre_Index varoffset;
  int vi;
  int vj;
  int d;
  for (vi = 0; vi < nvars; vi++) {
    sgrid = (pgrid)->sgrids[(pgrid)->vartypes[vi]];
    hypre_SStructVariableGetOffset(vartypes[vi], ndim, varoffset);
    for (vj = 0; vj < nvars; vj++) {
      smatrix = (pmatrix)->smatrices[vi][vj];
      if (smatrix != (void*)0) {
        HYPRE_StructMatrixSetSymmetric(smatrix, symmetric[vi][vj]);
        hypre_StructMatrixSetNumGhost(smatrix, num_ghost);
        for (d = 0; d < 3; d++) {
          (smatrix)->add_num_ghost[2 * d] = varoffset[d];
          (smatrix)->add_num_ghost[(2 * d) + 1] = varoffset[d];
        }
        hypre_StructMatrixInitialize(smatrix);
      }
    }
  }
  return hypre__global_error;
}
int hypre_SStructPMatrixSetValues(hypre_SStructPMatrix* pmatrix, hypre_Index index, int var, int nentries, int* entries, double* values, int add_to) {
  hypre_SStructStencil* stencil = (pmatrix)->stencils[var];
  int* smap = (pmatrix)->smaps[var];
  int* vars = (stencil)->vars;
  hypre_StructMatrix* smatrix;
  int* sentries;
  int i;
  smatrix = (pmatrix)->smatrices[var][vars[entries[0]]];
  sentries = (pmatrix)->sentries;
  for (i = 0; i < nentries; i++) {
    sentries[i] = smap[entries[i]];
  }
  hypre_StructMatrixSetValues(smatrix, index, nentries, sentries, values, add_to);
  return hypre__global_error;
}
int hypre_SStructPMatrixSetBoxValues(hypre_SStructPMatrix* pmatrix, hypre_Index ilower, hypre_Index iupper, int var, int nentries, int* entries, double* values, int add_to) {
  hypre_SStructStencil* stencil = (pmatrix)->stencils[var];
  int* smap = (pmatrix)->smaps[var];
  int* vars = (stencil)->vars;
  hypre_StructMatrix* smatrix;
  hypre_Box* box;
  int* sentries;
  int i;
  smatrix = (pmatrix)->smatrices[var][vars[entries[0]]];
  box = hypre_BoxCreate();
  (box)->imin[0] = ilower[0], (box)->imin[1] = ilower[1], (box)->imin[2] = ilower[2];
  (box)->imax[0] = iupper[0], (box)->imax[1] = iupper[1], (box)->imax[2] = iupper[2];
  sentries = (pmatrix)->sentries;
  for (i = 0; i < nentries; i++) {
    sentries[i] = smap[entries[i]];
  }
  hypre_StructMatrixSetBoxValues(smatrix, box, nentries, sentries, values, add_to);
  hypre_BoxDestroy(box);
  return hypre__global_error;
}
int hypre_SStructPMatrixAssemble(hypre_SStructPMatrix* pmatrix) {
  int nvars = (pmatrix)->nvars;
  hypre_StructMatrix* smatrix;
  int vi;
  int vj;
  for (vi = 0; vi < nvars; vi++) {
    for (vj = 0; vj < nvars; vj++) {
      smatrix = (pmatrix)->smatrices[vi][vj];
      if (smatrix != (void*)0) {
        hypre_StructMatrixAssemble(smatrix);
      }
    }
  }
  return hypre__global_error;
}
int hypre_SStructPMatrixSetSymmetric(hypre_SStructPMatrix* pmatrix, int var, int to_var, int symmetric) {
  int** pmsymmetric = (pmatrix)->symmetric;
  int vstart = var;
  int vsize = 1;
  int tstart = to_var;
  int tsize = 1;
  int v;
  int t;
  if (var == (-1)) {
    vstart = 0;
    vsize = (pmatrix)->nvars;
  }
  if (to_var == (-1)) {
    tstart = 0;
    tsize = (pmatrix)->nvars;
  }
  for (v = vstart; v < vsize; v++) {
    for (t = tstart; t < tsize; t++) {
      pmsymmetric[v][t] = symmetric;
    }
  }
  return hypre__global_error;
}
int hypre_SStructPMatrixPrint(char* filename, hypre_SStructPMatrix* pmatrix, int all) {
  int nvars = (pmatrix)->nvars;
  hypre_StructMatrix* smatrix;
  int vi;
  int vj;
  char  new_filename[255];
  for (vi = 0; vi < nvars; vi++) {
    for (vj = 0; vj < nvars; vj++) {
      smatrix = (pmatrix)->smatrices[vi][vj];
      if (smatrix != (void*)0) {
        sprintf(new_filename, "%s.%02d.%02d", filename, vi, vj);
        hypre_StructMatrixPrint(new_filename, smatrix, all);
      }
    }
  }
  return hypre__global_error;
}
int hypre_SStructUMatrixInitialize(hypre_SStructMatrix* matrix) {
  HYPRE_IJMatrix ijmatrix = (matrix)->ijmatrix;
  hypre_SStructGraph* graph = (matrix)->graph;
  hypre_SStructGrid* grid = (graph)->grid;
  int nparts = (graph)->nparts;
  hypre_SStructPGrid** pgrids = (graph)->pgrids;
  hypre_SStructStencil*** stencils = (graph)->stencils;
  int nUventries = (graph)->nUventries;
  int* iUventries = (graph)->iUventries;
  hypre_SStructUVEntry** Uventries = (graph)->Uventries;
  int** nvneighbors = (grid)->nvneighbors;
  hypre_StructGrid* sgrid;
  hypre_SStructStencil* stencil;
  int* split;
  int nvars;
  int nrows;
  int nnzs;
  int part;
  int var;
  int entry;
  int i;
  int j;
  int k;
  int m;
  int b;
  int* row_sizes;
  int max_row_size;
  int matrix_type = (matrix)->object_type;
  hypre_Box* gridbox;
  hypre_Box* loopbox;
  hypre_Box* ghostbox;
  hypre_BoxArray* boxes;
  int* num_ghost;
  HYPRE_IJMatrixSetObjectType(ijmatrix, 5555);
  if (matrix_type == 5555) {
    nrows = (grid)->local_size;
  }
  if ((matrix_type == 3333) || (matrix_type == 1111)) {
    nrows = (grid)->ghlocal_size;
  }
  m = 0;
  row_sizes = (int*)(hypre_CAlloc((unsigned)nrows, (unsigned)(sizeof(int))));
  max_row_size = 0;
  for (part = 0; part < nparts; part++) {
    nvars = (pgrids[part])->nvars;
    for (var = 0; var < nvars; var++) {
      sgrid = (pgrids[part])->sgrids[(pgrids[part])->vartypes[var]];
      stencil = stencils[part][var];
      split = (matrix)->splits[part][var];
      nnzs = 0;
      for (entry = 0; entry < ((stencil)->sstencil)->size; entry++) {
        if ((split[entry]) == (-1)) {
          nnzs++;
        }
      }
      boxes = (sgrid)->boxes;
      num_ghost = (sgrid)->num_ghost;
      for (b = 0; b < (boxes)->size; b++) {
        gridbox = &((boxes)->boxes[b]);
        ghostbox = hypre_BoxCreate();
        loopbox = hypre_BoxCreate();
        (ghostbox)->imin[0] = (gridbox)->imin[0], (ghostbox)->imin[1] = (gridbox)->imin[1], (ghostbox)->imin[2] = (gridbox)->imin[2], (ghostbox)->imax[0] = (gridbox)->imax[0], (ghostbox)->imax[1] = (gridbox)->imax[1], (ghostbox)->imax[2] = (gridbox)->imax[2];
        hypre_BoxExpand(ghostbox, num_ghost);
        if ((matrix_type == 3333) || (matrix_type == 1111)) {
          (loopbox)->imin[0] = (ghostbox)->imin[0], (loopbox)->imin[1] = (ghostbox)->imin[1], (loopbox)->imin[2] = (ghostbox)->imin[2], (loopbox)->imax[0] = (ghostbox)->imax[0], (loopbox)->imax[1] = (ghostbox)->imax[1], (loopbox)->imax[2] = (ghostbox)->imax[2];
        }
        if (matrix_type == 5555) {
          (loopbox)->imin[0] = (gridbox)->imin[0], (loopbox)->imin[1] = (gridbox)->imin[1], (loopbox)->imin[2] = (gridbox)->imin[2], (loopbox)->imax[0] = (gridbox)->imax[0], (loopbox)->imax[1] = (gridbox)->imax[1], (loopbox)->imax[2] = (gridbox)->imax[2];
        }
        for (k = (loopbox)->imin[2]; k <= ((loopbox)->imax[2]); k++) {
          for (j = (loopbox)->imin[1]; j <= ((loopbox)->imax[1]); j++) {
            for (i = (loopbox)->imin[0]; i <= ((loopbox)->imax[0]); i++) {
              if (((i >= ((gridbox)->imin[0])) && (j >= ((gridbox)->imin[1]))) && (k >= ((gridbox)->imin[2]))) {
                if (((i <= ((gridbox)->imax[0])) && (j <= ((gridbox)->imax[1]))) && (k <= ((gridbox)->imax[2]))) {
                  row_sizes[m] = nnzs;
                  max_row_size = max_row_size < (row_sizes[m]) ? row_sizes[m] : max_row_size;
                }
              }
              m++;
            }
          }
        }
        hypre_BoxDestroy(ghostbox);
        hypre_BoxDestroy(loopbox);
      }
      if (nvneighbors[part][var]) {
        max_row_size = max_row_size < ((stencil)->sstencil)->size ? ((stencil)->sstencil)->size : max_row_size;
      }
    }
  }
  for (entry = 0; entry < nUventries; entry++) {
    i = iUventries[entry];
    row_sizes[i] += (Uventries[i])->nUentries;
    max_row_size = max_row_size < (row_sizes[i]) ? row_sizes[i] : max_row_size;
  }
  HYPRE_IJMatrixSetRowSizes(ijmatrix, (int*)row_sizes);
  hypre_Free((char*)row_sizes), row_sizes = (void*)0;
  (matrix)->tmp_col_coords = (int*)(hypre_CAlloc((unsigned)max_row_size, (unsigned)(sizeof(int))));
  (matrix)->tmp_coeffs = (double*)(hypre_CAlloc((unsigned)max_row_size, (unsigned)(sizeof(double))));
  HYPRE_IJMatrixInitialize(ijmatrix);
  return hypre__global_error;
}
int hypre_SStructUMatrixSetValues(hypre_SStructMatrix* matrix, int part, hypre_Index index, int var, int nentries, int* entries, double* values, int add_to) {
  HYPRE_IJMatrix ijmatrix = (matrix)->ijmatrix;
  hypre_SStructGraph* graph = (matrix)->graph;
  hypre_SStructGrid* grid = (graph)->grid;
  hypre_SStructStencil* stencil = (graph)->stencils[part][var];
  int* vars = (stencil)->vars;
  hypre_Index* shape = ((stencil)->sstencil)->shape;
  int size = ((stencil)->sstencil)->size;
  hypre_IndexRef offset;
  hypre_Index to_index;
  hypre_SStructUVEntry* Uventry;
  hypre_BoxMapEntry* map_entry;
  hypre_SStructMapInfo* entry_info;
  int row_coord;
  int* col_coords;
  int ncoeffs;
  double* coeffs;
  int i;
  int entry;
  int proc;
  int myproc;
  int matrix_type = (matrix)->object_type;
  hypre_SStructGridFindMapEntry(grid, part, index, var, &(map_entry));
  if (map_entry == (void*)0) {
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/sstruct_mv/sstruct_matrix.c", 908, 4 | (1 << 3));
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/sstruct_mv/sstruct_matrix.c", 908, 4 | (2 << 3));
    hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/sstruct_mv/sstruct_matrix.c", 908, 4 | (3 << 3));
    printf("Warning: Attempt to set coeffs for point not in grid\n");
    printf("hypre_SStructUMatrixSetValues call aborted for grid point\n");
    printf("    part=%d, var=%d, index=(%d, %d, %d)\n", part, var, index[0], index[1], index[2]);
    return hypre__global_error;
  }
  else {
    hypre_BoxMapEntryGetInfo(map_entry, (void**)(&(entry_info)));
  }
  if (!add_to) {
    hypre_SStructMapEntryGetProcess(map_entry, &(proc));
    MPI_Comm_rank((grid)->comm, &(myproc));
    if (proc != myproc) {
      return hypre__global_error;
    }
  }
  hypre_SStructMapEntryGetGlobalRank(map_entry, index, &(row_coord), matrix_type);
  col_coords = (matrix)->tmp_col_coords;
  coeffs = (matrix)->tmp_coeffs;
  ncoeffs = 0;
  for (i = 0; i < nentries; i++) {
    entry = entries[i];
    if (entry < size) {
      offset = shape[entry];
      to_index[0] = (index[0]) + (offset[0]);
      to_index[1] = (index[1]) + (offset[1]);
      to_index[2] = (index[2]) + (offset[2]);
      hypre_SStructGridFindMapEntry(grid, part, to_index, vars[entry], &(map_entry));
      if (map_entry != (void*)0) {
        hypre_SStructMapEntryGetGlobalRank(map_entry, to_index, &(col_coords[ncoeffs]), matrix_type);
        coeffs[ncoeffs] = values[i];
        ncoeffs++;
      }
    }
    else {
      entry -= size;
      hypre_SStructGraphFindUVEntry(graph, part, index, var, &(Uventry));
      col_coords[ncoeffs] = (Uventry)->Uentries[entry].rank;
      coeffs[ncoeffs] = values[i];
      ncoeffs++;
    }
  }
  if (add_to > 0) {
    HYPRE_IJMatrixAddToValues(ijmatrix, 1, &(ncoeffs), &(row_coord), (int*)col_coords, (double*)coeffs);
  }
  else
    if (add_to > (-1)) {
      HYPRE_IJMatrixSetValues(ijmatrix, 1, &(ncoeffs), &(row_coord), (int*)col_coords, (double*)coeffs);
    }
    else {
      HYPRE_IJMatrixGetValues(ijmatrix, 1, &(ncoeffs), &(row_coord), col_coords, values);
    }
  return hypre__global_error;
}
int hypre_SStructUMatrixSetBoxValues(hypre_SStructMatrix* matrix, int part, hypre_Index ilower, hypre_Index iupper, int var, int nentries, int* entries, double* values, int add_to) {
  HYPRE_IJMatrix ijmatrix = (matrix)->ijmatrix;
  hypre_SStructGraph* graph = (matrix)->graph;
  hypre_SStructGrid* grid = (graph)->grid;
  hypre_SStructStencil* stencil = (graph)->stencils[part][var];
  int* vars = (stencil)->vars;
  hypre_Index* shape = ((stencil)->sstencil)->shape;
  int size = ((stencil)->sstencil)->size;
  hypre_IndexRef offset;
  hypre_BoxMap* map;
  hypre_BoxMapEntry** map_entries;
  int nmap_entries;
  hypre_BoxMapEntry** map_to_entries;
  int nmap_to_entries;
  int nrows;
  int* ncols;
  int* rows;
  int* cols;
  double* ijvalues;
  hypre_Box* box;
  hypre_Box* to_box;
  hypre_Box* map_box;
  hypre_Box* int_box;
  hypre_Index index;
  hypre_Index rs;
  hypre_Index cs;
  int sy;
  int sz;
  int row_base;
  int col_base;
  int val_base;
  int e;
  int entry;
  int ii;
  int jj;
  int i;
  int j;
  int k;
  int proc;
  int myproc;
  int matrix_type = (matrix)->object_type;
  box = hypre_BoxCreate();
  if ((entries[0]) < size) {
    to_box = hypre_BoxCreate();
    map_box = hypre_BoxCreate();
    int_box = hypre_BoxCreate();
    (box)->imin[0] = ilower[0], (box)->imin[1] = ilower[1], (box)->imin[2] = ilower[2];
    (box)->imax[0] = iupper[0], (box)->imax[1] = iupper[1], (box)->imax[2] = iupper[2];
    nrows = (((0 < ((((box)->imax[0]) - ((box)->imin[0])) + 1) ? (((box)->imax[0]) - ((box)->imin[0])) + 1 : 0) * (0 < ((((box)->imax[1]) - ((box)->imin[1])) + 1) ? (((box)->imax[1]) - ((box)->imin[1])) + 1 : 0)) * (0 < ((((box)->imax[2]) - ((box)->imin[2])) + 1) ? (((box)->imax[2]) - ((box)->imin[2])) + 1 : 0)) * nentries;
    ncols = (int*)(hypre_CAlloc((unsigned)nrows, (unsigned)(sizeof(int))));
    for (i = 0; i < nrows; i++) {
      ncols[i] = 1;
    }
    rows = (int*)(hypre_CAlloc((unsigned)nrows, (unsigned)(sizeof(int))));
    cols = (int*)(hypre_CAlloc((unsigned)nrows, (unsigned)(sizeof(int))));
    ijvalues = (double*)(hypre_CAlloc((unsigned)nrows, (unsigned)(sizeof(double))));
    sy = ((iupper[0]) - (ilower[0])) + 1;
    sz = (((iupper[1]) - (ilower[1])) + 1) * sy;
    map = (grid)->maps[part][var];
    hypre_BoxMapIntersect(map, ilower, iupper, &(map_entries), &(nmap_entries));
    for (ii = 0; ii < nmap_entries; ii++) {
      if (!add_to) {
        hypre_SStructMapEntryGetProcess(map_entries[ii], &(proc));
        MPI_Comm_rank((grid)->comm, &(myproc));
        if (proc != myproc) {
          continue;
        }
      }
      hypre_SStructMapEntryGetStrides(map_entries[ii], rs, matrix_type);
      (box)->imin[0] = ilower[0], (box)->imin[1] = ilower[1], (box)->imin[2] = ilower[2];
      (box)->imax[0] = iupper[0], (box)->imax[1] = iupper[1], (box)->imax[2] = iupper[2];
      hypre_BoxMapEntryGetExtents(map_entries[ii], (map_box)->imin, (map_box)->imax);
      hypre_IntersectBoxes(box, map_box, int_box);
      (box)->imin[0] = (int_box)->imin[0], (box)->imin[1] = (int_box)->imin[1], (box)->imin[2] = (int_box)->imin[2], (box)->imax[0] = (int_box)->imax[0], (box)->imax[1] = (int_box)->imax[1], (box)->imax[2] = (int_box)->imax[2];
      nrows = 0;
      for (e = 0; e < nentries; e++) {
        entry = entries[e];
        (to_box)->imin[0] = (box)->imin[0], (to_box)->imin[1] = (box)->imin[1], (to_box)->imin[2] = (box)->imin[2], (to_box)->imax[0] = (box)->imax[0], (to_box)->imax[1] = (box)->imax[1], (to_box)->imax[2] = (box)->imax[2];
        offset = shape[entry];
        (to_box)->imin[0] += offset[0];
        (to_box)->imin[1] += offset[1];
        (to_box)->imin[2] += offset[2];
        (to_box)->imax[0] += offset[0];
        (to_box)->imax[1] += offset[1];
        (to_box)->imax[2] += offset[2];
        map = (grid)->maps[part][vars[entry]];
        hypre_BoxMapIntersect(map, (to_box)->imin, (to_box)->imax, &(map_to_entries), &(nmap_to_entries));
        for (jj = 0; jj < nmap_to_entries; jj++) {
          hypre_SStructMapEntryGetStrides(map_to_entries[jj], cs, matrix_type);
          hypre_BoxMapEntryGetExtents(map_to_entries[jj], (map_box)->imin, (map_box)->imax);
          hypre_IntersectBoxes(to_box, map_box, int_box);
          index[0] = (int_box)->imin[0], index[1] = (int_box)->imin[1], index[2] = (int_box)->imin[2];
          hypre_SStructMapEntryGetGlobalRank(map_to_entries[jj], index, &(col_base), matrix_type);
          (index[0]) -= (offset[0]);
          (index[1]) -= (offset[1]);
          (index[2]) -= (offset[2]);
          hypre_SStructMapEntryGetGlobalRank(map_entries[ii], index, &(row_base), matrix_type);
          (index[0]) -= (ilower[0]);
          (index[1]) -= (ilower[1]);
          (index[2]) -= (ilower[2]);
          val_base = e + ((((index[0]) + ((index[1]) * sy)) + ((index[2]) * sz)) * nentries);
          for (k = 0; k < (0 < ((((int_box)->imax[2]) - ((int_box)->imin[2])) + 1) ? (((int_box)->imax[2]) - ((int_box)->imin[2])) + 1 : 0); k++) {
            for (j = 0; j < (0 < ((((int_box)->imax[1]) - ((int_box)->imin[1])) + 1) ? (((int_box)->imax[1]) - ((int_box)->imin[1])) + 1 : 0); j++) {
              for (i = 0; i < (0 < ((((int_box)->imax[0]) - ((int_box)->imin[0])) + 1) ? (((int_box)->imax[0]) - ((int_box)->imin[0])) + 1 : 0); i++) {
                rows[nrows] = row_base + (int)(((i * (rs[0])) + (j * (rs[1]))) + (k * (rs[2])));
                cols[nrows] = col_base + (int)(((i * (cs[0])) + (j * (cs[1]))) + (k * (cs[2])));
                ijvalues[nrows] = values[val_base + (((i + (j * sy)) + (k * sz)) * nentries)];
                nrows++;
              }
            }
          }
        }
        hypre_Free((char*)map_to_entries), map_to_entries = (void*)0;
      }
      if (add_to > 0) {
        HYPRE_IJMatrixAddToValues(ijmatrix, nrows, ncols, (int*)rows, (int*)cols, (double*)ijvalues);
      }
      else
        if (add_to > (-1)) {
          HYPRE_IJMatrixSetValues(ijmatrix, nrows, ncols, (int*)rows, (int*)cols, (double*)ijvalues);
        }
        else {
          HYPRE_IJMatrixGetValues(ijmatrix, nrows, ncols, rows, cols, values);
        }
    }
    hypre_Free((char*)map_entries), map_entries = (void*)0;
    hypre_Free((char*)ncols), ncols = (void*)0;
    hypre_Free((char*)rows), rows = (void*)0;
    hypre_Free((char*)cols), cols = (void*)0;
    hypre_Free((char*)ijvalues), ijvalues = (void*)0;
    hypre_BoxDestroy(to_box);
    hypre_BoxDestroy(map_box);
    hypre_BoxDestroy(int_box);
  }
  else {
    (box)->imin[0] = ilower[0], (box)->imin[1] = ilower[1], (box)->imin[2] = ilower[2];
    (box)->imax[0] = iupper[0], (box)->imax[1] = iupper[1], (box)->imax[2] = iupper[2];
    for (k = (box)->imin[2]; k <= ((box)->imax[2]); k++) {
      for (j = (box)->imin[1]; j <= ((box)->imax[1]); j++) {
        for (i = (box)->imin[0]; i <= ((box)->imax[0]); i++) {
          index[0] = i, index[1] = j, index[2] = k;
          hypre_SStructUMatrixSetValues(matrix, part, index, var, nentries, entries, values, add_to);
          values += nentries;
        }
      }
    }
  }
  hypre_BoxDestroy(box);
  return hypre__global_error;
}
int hypre_SStructUMatrixAssemble(hypre_SStructMatrix* matrix) {
  HYPRE_IJMatrix ijmatrix = (matrix)->ijmatrix;
  HYPRE_IJMatrixAssemble(ijmatrix);
  HYPRE_IJMatrixGetObject(ijmatrix, (void**)(&((matrix)->parcsrmatrix)));
  return hypre__global_error;
}
int hypre_SStructMatrixSplitEntries(hypre_SStructMatrix* matrix, int part, int var, int nentries, int* entries, int* nSentries_ptr, int** Sentries_ptr, int* nUentries_ptr, int** Uentries_ptr) {
  hypre_SStructGraph* graph = (matrix)->graph;
  int* split = (matrix)->splits[part][var];
  hypre_SStructStencil* stencil = (graph)->stencils[part][var];
  int entry;
  int i;
  int nSentries = 0;
  int* Sentries = (matrix)->Sentries;
  int nUentries = 0;
  int* Uentries = (matrix)->Uentries;
  for (i = 0; i < nentries; i++) {
    entry = entries[i];
    if (entry < ((stencil)->sstencil)->size) {
      if ((split[entry]) > (-1)) {
        Sentries[nSentries] = split[entry];
        nSentries++;
      }
      else {
        Uentries[nUentries] = entry;
        nUentries++;
      }
    }
    else {
      Uentries[nUentries] = entry;
      nUentries++;
    }
  }
  *nSentries_ptr = nSentries;
  *Sentries_ptr = Sentries;
  *nUentries_ptr = nUentries;
  *Uentries_ptr = Uentries;
  return hypre__global_error;
}
//==================== sstruct_matvec.c ====================
typedef struct $anon_struct_33$TU72{
  int nvars;
  void*** smatvec_data;
} hypre_SStructPMatvecData;
int hypre_SStructPMatvecCreate(void** pmatvec_vdata_ptr) {
  int ierr = 0;
  hypre_SStructPMatvecData* pmatvec_data;
  pmatvec_data = (hypre_SStructPMatvecData*)(hypre_CAlloc((unsigned)1, (unsigned)(sizeof(hypre_SStructPMatvecData))));
  *pmatvec_vdata_ptr = (void*)pmatvec_data;
  return ierr;
}
int hypre_SStructPMatvecSetup(void* pmatvec_vdata, hypre_SStructPMatrix* pA, hypre_SStructPVector* px) {
  int ierr = 0;
  hypre_SStructPMatvecData* pmatvec_data = pmatvec_vdata;
  int nvars;
  void*** smatvec_data;
  hypre_StructMatrix* sA;
  hypre_StructVector* sx;
  int vi;
  int vj;
  nvars = (pA)->nvars;
  smatvec_data = (void***)(hypre_MAlloc((unsigned)(sizeof(void**) * nvars)));
  for (vi = 0; vi < nvars; vi++) {
    smatvec_data[vi] = (void**)(hypre_MAlloc((unsigned)(sizeof(void*) * nvars)));
    for (vj = 0; vj < nvars; vj++) {
      sA = (pA)->smatrices[vi][vj];
      sx = (px)->svectors[vj];
      smatvec_data[vi][vj] = (void*)0;
      if (sA != (void*)0) {
        smatvec_data[vi][vj] = hypre_StructMatvecCreate();
        hypre_StructMatvecSetup(smatvec_data[vi][vj], sA, sx);
      }
    }
  }
  (pmatvec_data)->nvars = nvars;
  (pmatvec_data)->smatvec_data = smatvec_data;
  return ierr;
}
int hypre_SStructPMatvecCompute(void* pmatvec_vdata, double alpha, hypre_SStructPMatrix* pA, hypre_SStructPVector* px, double beta, hypre_SStructPVector* py) {
  int ierr = 0;
  hypre_SStructPMatvecData* pmatvec_data = pmatvec_vdata;
  int nvars = (pmatvec_data)->nvars;
  void*** smatvec_data = (pmatvec_data)->smatvec_data;
  void* sdata;
  hypre_StructMatrix* sA;
  hypre_StructVector* sx;
  hypre_StructVector* sy;
  int vi;
  int vj;
  for (vi = 0; vi < nvars; vi++) {
    sy = (py)->svectors[vi];
    if ((smatvec_data[vi][vi]) != (void*)0) {
      sdata = smatvec_data[vi][vi];
      sA = (pA)->smatrices[vi][vi];
      sx = (px)->svectors[vi];
      hypre_StructMatvecCompute(sdata, alpha, sA, sx, beta, sy);
    }
    else {
      hypre_StructScale(beta, sy);
    }
    for (vj = 0; vj < nvars; vj++) {
      if (((smatvec_data[vi][vj]) != (void*)0) && (vj != vi)) {
        sdata = smatvec_data[vi][vj];
        sA = (pA)->smatrices[vi][vj];
        sx = (px)->svectors[vj];
        hypre_StructMatvecCompute(sdata, alpha, sA, sx, 1.0, sy);
      }
    }
  }
  return ierr;
}
int hypre_SStructPMatvecDestroy(void* pmatvec_vdata) {
  int ierr = 0;
  hypre_SStructPMatvecData* pmatvec_data = pmatvec_vdata;
  int nvars;
  void*** smatvec_data;
  int vi;
  int vj;
  if (pmatvec_data) {
    nvars = (pmatvec_data)->nvars;
    smatvec_data = (pmatvec_data)->smatvec_data;
    for (vi = 0; vi < nvars; vi++) {
      for (vj = 0; vj < nvars; vj++) {
        if ((smatvec_data[vi][vj]) != (void*)0) {
          hypre_StructMatvecDestroy(smatvec_data[vi][vj]);
        }
      }
      hypre_Free((char*)(smatvec_data[vi])), smatvec_data[vi] = (void*)0;
    }
    hypre_Free((char*)smatvec_data), smatvec_data = (void*)0;
    hypre_Free((char*)pmatvec_data), pmatvec_data = (void*)0;
  }
  return ierr;
}
typedef struct $anon_struct_34$TU72{
  int nparts;
  void** pmatvec_data;
} hypre_SStructMatvecData;
int hypre_SStructMatvecCreate(void** matvec_vdata_ptr) {
  int ierr = 0;
  hypre_SStructMatvecData* matvec_data;
  matvec_data = (hypre_SStructMatvecData*)(hypre_CAlloc((unsigned)1, (unsigned)(sizeof(hypre_SStructMatvecData))));
  *matvec_vdata_ptr = (void*)matvec_data;
  return ierr;
}
int hypre_SStructMatvecSetup(void* matvec_vdata, hypre_SStructMatrix* A, hypre_SStructVector* x) {
  int ierr = 0;
  hypre_SStructMatvecData* matvec_data = matvec_vdata;
  int nparts;
  void** pmatvec_data;
  hypre_SStructPMatrix* pA;
  hypre_SStructPVector* px;
  int part;
  nparts = (A)->nparts;
  pmatvec_data = (void**)(hypre_MAlloc((unsigned)(sizeof(void*) * nparts)));
  for (part = 0; part < nparts; part++) {
    hypre_SStructPMatvecCreate(&(pmatvec_data[part]));
    pA = (A)->pmatrices[part];
    px = (x)->pvectors[part];
    hypre_SStructPMatvecSetup(pmatvec_data[part], pA, px);
  }
  (matvec_data)->nparts = nparts;
  (matvec_data)->pmatvec_data = pmatvec_data;
  return ierr;
}
int hypre_SStructMatvecCompute(void* matvec_vdata, double alpha, hypre_SStructMatrix* A, hypre_SStructVector* x, double beta, hypre_SStructVector* y) {
  int ierr = 0;
  hypre_SStructMatvecData* matvec_data = matvec_vdata;
  int nparts = (matvec_data)->nparts;
  void** pmatvec_data = (matvec_data)->pmatvec_data;
  void* pdata;
  hypre_SStructPMatrix* pA;
  hypre_SStructPVector* px;
  hypre_SStructPVector* py;
  hypre_ParCSRMatrix* parcsrA = (A)->parcsrmatrix;
  hypre_ParVector* parx;
  hypre_ParVector* pary;
  int part;
  int x_object_type = (x)->object_type;
  int A_object_type = (A)->object_type;
  if (x_object_type != A_object_type) {
    printf("possible error: A and x are different object types\n");
  }
  if (x_object_type == 3333) {
    for (part = 0; part < nparts; part++) {
      pdata = pmatvec_data[part];
      pA = (A)->pmatrices[part];
      px = (x)->pvectors[part];
      py = (y)->pvectors[part];
      hypre_SStructPMatvecCompute(pdata, alpha, pA, px, beta, py);
    }
    hypre_SStructVectorConvert(x, &(parx));
    hypre_SStructVectorConvert(y, &(pary));
    hypre_ParCSRMatrixMatvec(alpha, parcsrA, parx, 1.0, pary);
    hypre_SStructVectorRestore(x, (void*)0);
    hypre_SStructVectorRestore(y, pary);
    parx = (void*)0;
  }
  else
    if (x_object_type == 5555) {
      hypre_SStructVectorConvert(x, &(parx));
      hypre_SStructVectorConvert(y, &(pary));
      hypre_ParCSRMatrixMatvec(alpha, parcsrA, parx, beta, pary);
      hypre_SStructVectorRestore(x, (void*)0);
      hypre_SStructVectorRestore(y, pary);
      parx = (void*)0;
    }
  return ierr;
}
int hypre_SStructMatvecDestroy(void* matvec_vdata) {
  int ierr = 0;
  hypre_SStructMatvecData* matvec_data = matvec_vdata;
  int nparts;
  void** pmatvec_data;
  int part;
  if (matvec_data) {
    nparts = (matvec_data)->nparts;
    pmatvec_data = (matvec_data)->pmatvec_data;
    for (part = 0; part < nparts; part++) {
      hypre_SStructPMatvecDestroy(pmatvec_data[part]);
    }
    hypre_Free((char*)pmatvec_data), pmatvec_data = (void*)0;
    hypre_Free((char*)matvec_data), matvec_data = (void*)0;
  }
  return ierr;
}
int hypre_SStructMatvec(double alpha, hypre_SStructMatrix* A, hypre_SStructVector* x, double beta, hypre_SStructVector* y) {
  int ierr = 0;
  void* matvec_data;
  hypre_SStructMatvecCreate(&(matvec_data));
  ierr = hypre_SStructMatvecSetup(matvec_data, A, x);
  ierr = hypre_SStructMatvecCompute(matvec_data, alpha, A, x, beta, y);
  ierr = hypre_SStructMatvecDestroy(matvec_data);
  return ierr;
}
//==================== sstruct_stencil.c ===================
int hypre_SStructStencilRef(hypre_SStructStencil* stencil, hypre_SStructStencil** stencil_ref) {
  (stencil)->ref_count++;
  *stencil_ref = stencil;
  return 0;
}
//==================== sstruct_vector.c ====================
int hypre_SStructPVectorCreate(MPI_Comm comm, hypre_SStructPGrid* pgrid, hypre_SStructPVector** pvector_ptr) {
  int ierr = 0;
  hypre_SStructPVector* pvector;
  int nvars;
  hypre_StructVector** svectors;
  hypre_CommPkg** comm_pkgs;
  hypre_StructGrid* sgrid;
  HYPRE_SStructVariable* vartypes = (pgrid)->vartypes;
  int ndim = (pgrid)->ndim;
  hypre_Index varoffset;
  int var;
  int d;
  pvector = (hypre_SStructPVector*)(hypre_MAlloc((unsigned)(sizeof(hypre_SStructPVector) * 1)));
  (pvector)->comm = comm;
  (pvector)->pgrid = pgrid;
  nvars = (pgrid)->nvars;
  (pvector)->nvars = nvars;
  svectors = (hypre_StructVector**)(hypre_MAlloc((unsigned)(sizeof(hypre_StructVector*) * nvars)));
  for (var = 0; var < nvars; var++) {
    sgrid = (pgrid)->sgrids[(pgrid)->vartypes[var]];
    svectors[var] = hypre_StructVectorCreate(comm, sgrid);
    if ((vartypes[var]) > 0) {
      sgrid = (svectors[var])->grid;
      hypre_SStructVariableGetOffset(vartypes[var], ndim, varoffset);
      for (d = 0; d < 3; d++) {
        (svectors[var])->add_num_ghost[2 * d] = varoffset[d];
        (svectors[var])->add_num_ghost[(2 * d) + 1] = varoffset[d];
      }
    }
  }
  (pvector)->svectors = svectors;
  comm_pkgs = (hypre_CommPkg**)(hypre_MAlloc((unsigned)(sizeof(hypre_CommPkg*) * nvars)));
  for (var = 0; var < nvars; var++) {
    comm_pkgs[var] = (void*)0;
  }
  (pvector)->comm_pkgs = comm_pkgs;
  (pvector)->ref_count = 1;
  (pvector)->dataindices = (void*)0;
  *pvector_ptr = pvector;
  return ierr;
}
int hypre_SStructPVectorDestroy(hypre_SStructPVector* pvector) {
  int ierr = 0;
  int nvars;
  hypre_StructVector** svectors;
  hypre_CommPkg** comm_pkgs;
  int var;
  int* dataindices;
  if (pvector) {
    (pvector)->ref_count--;
    if ((pvector)->ref_count == 0) {
      nvars = (pvector)->nvars;
      svectors = (pvector)->svectors;
      comm_pkgs = (pvector)->comm_pkgs;
      dataindices = (pvector)->dataindices;
      for (var = 0; var < nvars; var++) {
        hypre_StructVectorDestroy(svectors[var]);
        hypre_CommPkgDestroy(comm_pkgs[var]);
      }
      hypre_Free((char*)dataindices), dataindices = (void*)0;
      hypre_Free((char*)svectors), svectors = (void*)0;
      hypre_Free((char*)comm_pkgs), comm_pkgs = (void*)0;
      hypre_Free((char*)pvector), pvector = (void*)0;
    }
  }
  return ierr;
}
int hypre_SStructPVectorSetBoxValues(hypre_SStructPVector* pvector, hypre_Index ilower, hypre_Index iupper, int var, double* values, int add_to) {
  int ierr = 0;
  hypre_StructVector* svector = (pvector)->svectors[var];
  hypre_Box* box;
  box = hypre_BoxCreate();
  (box)->imin[0] = ilower[0], (box)->imin[1] = ilower[1], (box)->imin[2] = ilower[2];
  (box)->imax[0] = iupper[0], (box)->imax[1] = iupper[1], (box)->imax[2] = iupper[2];
  ierr = hypre_StructVectorSetBoxValues(svector, box, values, add_to);
  hypre_BoxDestroy(box);
  return ierr;
}
int hypre_SStructPVectorAssemble(hypre_SStructPVector* pvector) {
  int ierr = 0;
  hypre_SStructPGrid* pgrid = (pvector)->pgrid;
  int nvars = (pvector)->nvars;
  hypre_StructVector** svectors = (pvector)->svectors;
  hypre_CommPkg** comm_pkgs = (pvector)->comm_pkgs;
  hypre_CommInfo* comm_info;
  int ndim = (pgrid)->ndim;
  HYPRE_SStructVariable* vartypes = (pgrid)->vartypes;
  hypre_Index varoffset;
  int  num_ghost[6];
  hypre_StructGrid* sgrid;
  int var;
  int d;
  for (var = 0; var < nvars; var++) {
    hypre_StructVectorAssemble(svectors[var]);
    if ((vartypes[var]) > 0) {
      sgrid = (svectors[var])->grid;
      hypre_SStructVariableGetOffset(vartypes[var], ndim, varoffset);
      for (d = 0; d < 3; d++) {
        num_ghost[2 * d] = varoffset[d];
        num_ghost[(2 * d) + 1] = varoffset[d];
      }
      hypre_CreateCommInfoFromNumGhost(sgrid, num_ghost, &(comm_info));
      hypre_CommPkgDestroy(comm_pkgs[var]);
      hypre_CommPkgCreate(comm_info, (svectors[var])->data_space, (svectors[var])->data_space, 1, (svectors[var])->comm, &(comm_pkgs[var]));
    }
  }
  return ierr;
}
int hypre_SStructPVectorGather(hypre_SStructPVector* pvector) {
  int ierr = 0;
  int nvars = (pvector)->nvars;
  hypre_StructVector** svectors = (pvector)->svectors;
  hypre_CommPkg** comm_pkgs = (pvector)->comm_pkgs;
  hypre_CommHandle* comm_handle;
  int var;
  for (var = 0; var < nvars; var++) {
    if ((comm_pkgs[var]) != (void*)0) {
      hypre_InitializeCommunication(comm_pkgs[var], (svectors[var])->data, (svectors[var])->data, &(comm_handle));
      hypre_FinalizeCommunication(comm_handle);
    }
  }
  return ierr;
}
int hypre_SStructPVectorPrint(char* filename, hypre_SStructPVector* pvector, int all) {
  int ierr = 0;
  int nvars = (pvector)->nvars;
  int var;
  char  new_filename[255];
  for (var = 0; var < nvars; var++) {
    sprintf(new_filename, "%s.%02d", filename, var);
    hypre_StructVectorPrint(new_filename, (pvector)->svectors[var], all);
  }
  return ierr;
}
int hypre_SStructVectorConvert(hypre_SStructVector* vector, hypre_ParVector** parvector_ptr) {
  int ierr = 0;
  *parvector_ptr = (vector)->parvector;
  return ierr;
}
int hypre_SStructVectorParConvert(hypre_SStructVector* vector, hypre_ParVector** parvector_ptr) {
  int ierr = 0;
  hypre_ParVector* parvector;
  double* pardata;
  int pari;
  hypre_SStructPVector* pvector;
  hypre_StructVector* y;
  hypre_Box* y_data_box;
  int yi;
  double* yp;
  hypre_BoxArray* boxes;
  hypre_Box* box;
  int bi;
  hypre_Index loop_size;
  hypre_IndexRef start;
  hypre_Index stride;
  int nparts;
  int nvars;
  int part;
  int var;
  int i;
  int loopi;
  int loopj;
  int loopk;
  stride[0] = 1, stride[1] = 1, stride[2] = 1;
  parvector = (vector)->parvector;
  pardata = ((parvector)->local_vector)->data;
  pari = 0;
  nparts = (vector)->nparts;
  for (part = 0; part < nparts; part++) {
    pvector = (vector)->pvectors[part];
    nvars = (pvector)->nvars;
    for (var = 0; var < nvars; var++) {
      y = (pvector)->svectors[var];
      boxes = ((y)->grid)->boxes;
      for (i = 0; i < (boxes)->size; i++) {
        box = &((boxes)->boxes[i]);
        start = (box)->imin;
        y_data_box = &(((y)->data_space)->boxes[i]);
        yp = (y)->data + ((y)->data_indices[i]);
        hypre_BoxGetSize(box, loop_size);
        {
          int hypre__i1start = ((start[0]) - ((y_data_box)->imin[0])) + ((((start[1]) - ((y_data_box)->imin[1])) + (((start[2]) - ((y_data_box)->imin[2])) * (0 < ((((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1) ? (((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1 : 0))) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0));
          int hypre__i2start = ((start[0]) - ((box)->imin[0])) + ((((start[1]) - ((box)->imin[1])) + (((start[2]) - ((box)->imin[2])) * (0 < ((((box)->imax[1]) - ((box)->imin[1])) + 1) ? (((box)->imax[1]) - ((box)->imin[1])) + 1 : 0))) * (0 < ((((box)->imax[0]) - ((box)->imin[0])) + 1) ? (((box)->imax[0]) - ((box)->imin[0])) + 1 : 0));
          int hypre__sx1 = stride[0];
          int hypre__sy1 = (stride[1]) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0);
          int hypre__sz1 = ((stride[2]) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0)) * (0 < ((((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1) ? (((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1 : 0);
          int hypre__sx2 = stride[0];
          int hypre__sy2 = (stride[1]) * (0 < ((((box)->imax[0]) - ((box)->imin[0])) + 1) ? (((box)->imax[0]) - ((box)->imin[0])) + 1 : 0);
          int hypre__sz2 = ((stride[2]) * (0 < ((((box)->imax[0]) - ((box)->imin[0])) + 1) ? (((box)->imax[0]) - ((box)->imin[0])) + 1 : 0)) * (0 < ((((box)->imax[1]) - ((box)->imin[1])) + 1) ? (((box)->imax[1]) - ((box)->imin[1])) + 1 : 0);
          int hypre__nx = loop_size[0];
          int hypre__ny = loop_size[1];
          int hypre__nz = loop_size[2];
          int hypre__mx = hypre__nx;
          int hypre__my = hypre__ny;
          int hypre__mz = hypre__nz;
          int hypre__dir;
          int hypre__max;
          int hypre__div;
          int hypre__mod;
          int hypre__block;
          int hypre__num_blocks;
          hypre__dir = 0;
          hypre__max = hypre__nx;
          if (hypre__ny > hypre__max) {
            hypre__dir = 1;
            hypre__max = hypre__ny;
          }
          if (hypre__nz > hypre__max) {
            hypre__dir = 2;
            hypre__max = hypre__nz;
          }
          hypre__num_blocks = 1;
          if (hypre__max < hypre__num_blocks) {
            hypre__num_blocks = hypre__max;
          }
          if (hypre__num_blocks > 0) {
            hypre__div = hypre__max / hypre__num_blocks;
            hypre__mod = hypre__max % hypre__num_blocks;
          }
          ;
          ;
          for (hypre__block = 0; hypre__block < hypre__num_blocks; hypre__block++) {
            loopi = 0;
            loopj = 0;
            loopk = 0;
            hypre__nx = hypre__mx;
            hypre__ny = hypre__my;
            hypre__nz = hypre__mz;
            if (hypre__num_blocks > 1) {
              if (hypre__dir == 0) {
                loopi = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                hypre__nx = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
              }
              else
                if (hypre__dir == 1) {
                  loopj = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                  hypre__ny = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                }
                else
                  if (hypre__dir == 2) {
                    loopk = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                    hypre__nz = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                  }
            }
            ;
            yi = ((hypre__i1start + (loopi * hypre__sx1)) + (loopj * hypre__sy1)) + (loopk * hypre__sz1);
            bi = ((hypre__i2start + (loopi * hypre__sx2)) + (loopj * hypre__sy2)) + (loopk * hypre__sz2);
            for (loopk = 0; loopk < hypre__nz; loopk++) {
              for (loopj = 0; loopj < hypre__ny; loopj++) {
                for (loopi = 0; loopi < hypre__nx; loopi++) {
                  {
                    pardata[pari + bi] = yp[yi];
                  }
                  yi += hypre__sx1;
                  bi += hypre__sx2;
                }
                yi += hypre__sy1 - (hypre__nx * hypre__sx1);
                bi += hypre__sy2 - (hypre__nx * hypre__sx2);
              }
              yi += hypre__sz1 - (hypre__ny * hypre__sy1);
              bi += hypre__sz2 - (hypre__ny * hypre__sy2);
            }
          }
        }
        ;
        pari += ((loop_size[0]) * (loop_size[1])) * (loop_size[2]);
      }
    }
  }
  *parvector_ptr = (vector)->parvector;
  return ierr;
}
int hypre_SStructVectorRestore(hypre_SStructVector* vector, hypre_ParVector* parvector) {
  int ierr = 0;
  return ierr;
}
int hypre_SStructVectorParRestore(hypre_SStructVector* vector, hypre_ParVector* parvector) {
  int ierr = 0;
  double* pardata;
  int pari;
  hypre_SStructPVector* pvector;
  hypre_StructVector* y;
  hypre_Box* y_data_box;
  int yi;
  double* yp;
  hypre_BoxArray* boxes;
  hypre_Box* box;
  int bi;
  hypre_Index loop_size;
  hypre_IndexRef start;
  hypre_Index stride;
  int nparts;
  int nvars;
  int part;
  int var;
  int i;
  int loopi;
  int loopj;
  int loopk;
  if (parvector != (void*)0) {
    stride[0] = 1, stride[1] = 1, stride[2] = 1;
    parvector = (vector)->parvector;
    pardata = ((parvector)->local_vector)->data;
    pari = 0;
    nparts = (vector)->nparts;
    for (part = 0; part < nparts; part++) {
      pvector = (vector)->pvectors[part];
      nvars = (pvector)->nvars;
      for (var = 0; var < nvars; var++) {
        y = (pvector)->svectors[var];
        boxes = ((y)->grid)->boxes;
        for (i = 0; i < (boxes)->size; i++) {
          box = &((boxes)->boxes[i]);
          start = (box)->imin;
          y_data_box = &(((y)->data_space)->boxes[i]);
          yp = (y)->data + ((y)->data_indices[i]);
          hypre_BoxGetSize(box, loop_size);
          {
            int hypre__i1start = ((start[0]) - ((y_data_box)->imin[0])) + ((((start[1]) - ((y_data_box)->imin[1])) + (((start[2]) - ((y_data_box)->imin[2])) * (0 < ((((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1) ? (((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1 : 0))) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0));
            int hypre__i2start = ((start[0]) - ((box)->imin[0])) + ((((start[1]) - ((box)->imin[1])) + (((start[2]) - ((box)->imin[2])) * (0 < ((((box)->imax[1]) - ((box)->imin[1])) + 1) ? (((box)->imax[1]) - ((box)->imin[1])) + 1 : 0))) * (0 < ((((box)->imax[0]) - ((box)->imin[0])) + 1) ? (((box)->imax[0]) - ((box)->imin[0])) + 1 : 0));
            int hypre__sx1 = stride[0];
            int hypre__sy1 = (stride[1]) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0);
            int hypre__sz1 = ((stride[2]) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0)) * (0 < ((((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1) ? (((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1 : 0);
            int hypre__sx2 = stride[0];
            int hypre__sy2 = (stride[1]) * (0 < ((((box)->imax[0]) - ((box)->imin[0])) + 1) ? (((box)->imax[0]) - ((box)->imin[0])) + 1 : 0);
            int hypre__sz2 = ((stride[2]) * (0 < ((((box)->imax[0]) - ((box)->imin[0])) + 1) ? (((box)->imax[0]) - ((box)->imin[0])) + 1 : 0)) * (0 < ((((box)->imax[1]) - ((box)->imin[1])) + 1) ? (((box)->imax[1]) - ((box)->imin[1])) + 1 : 0);
            int hypre__nx = loop_size[0];
            int hypre__ny = loop_size[1];
            int hypre__nz = loop_size[2];
            int hypre__mx = hypre__nx;
            int hypre__my = hypre__ny;
            int hypre__mz = hypre__nz;
            int hypre__dir;
            int hypre__max;
            int hypre__div;
            int hypre__mod;
            int hypre__block;
            int hypre__num_blocks;
            hypre__dir = 0;
            hypre__max = hypre__nx;
            if (hypre__ny > hypre__max) {
              hypre__dir = 1;
              hypre__max = hypre__ny;
            }
            if (hypre__nz > hypre__max) {
              hypre__dir = 2;
              hypre__max = hypre__nz;
            }
            hypre__num_blocks = 1;
            if (hypre__max < hypre__num_blocks) {
              hypre__num_blocks = hypre__max;
            }
            if (hypre__num_blocks > 0) {
              hypre__div = hypre__max / hypre__num_blocks;
              hypre__mod = hypre__max % hypre__num_blocks;
            }
            ;
            ;
            for (hypre__block = 0; hypre__block < hypre__num_blocks; hypre__block++) {
              loopi = 0;
              loopj = 0;
              loopk = 0;
              hypre__nx = hypre__mx;
              hypre__ny = hypre__my;
              hypre__nz = hypre__mz;
              if (hypre__num_blocks > 1) {
                if (hypre__dir == 0) {
                  loopi = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                  hypre__nx = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                }
                else
                  if (hypre__dir == 1) {
                    loopj = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                    hypre__ny = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                  }
                  else
                    if (hypre__dir == 2) {
                      loopk = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                      hypre__nz = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                    }
              }
              ;
              yi = ((hypre__i1start + (loopi * hypre__sx1)) + (loopj * hypre__sy1)) + (loopk * hypre__sz1);
              bi = ((hypre__i2start + (loopi * hypre__sx2)) + (loopj * hypre__sy2)) + (loopk * hypre__sz2);
              for (loopk = 0; loopk < hypre__nz; loopk++) {
                for (loopj = 0; loopj < hypre__ny; loopj++) {
                  for (loopi = 0; loopi < hypre__nx; loopi++) {
                    {
                      yp[yi] = pardata[pari + bi];
                    }
                    yi += hypre__sx1;
                    bi += hypre__sx2;
                  }
                  yi += hypre__sy1 - (hypre__nx * hypre__sx1);
                  bi += hypre__sy2 - (hypre__nx * hypre__sx2);
                }
                yi += hypre__sz1 - (hypre__ny * hypre__sy1);
                bi += hypre__sz2 - (hypre__ny * hypre__sy2);
              }
            }
          }
          ;
          pari += ((loop_size[0]) * (loop_size[1])) * (loop_size[2]);
        }
      }
    }
  }
  return ierr;
}
int hypre_SStructPVectorInitializeShell(hypre_SStructPVector* pvector) {
  int ierr = 0;
  int nvars = (pvector)->nvars;
  int var;
  int pdatasize;
  int svectdatasize;
  int* pdataindices;
  int nucvars = 0;
  hypre_StructVector* svector;
  pdatasize = 0;
  pdataindices = (int*)(hypre_CAlloc((unsigned)nvars, (unsigned)(sizeof(int))));
  for (var = 0; var < nvars; var++) {
    svector = (pvector)->svectors[var];
    hypre_StructVectorInitializeShell(svector);
    pdataindices[var] = pdatasize;
    svectdatasize = (svector)->data_size;
    pdatasize += svectdatasize;
  }
  (pvector)->dataindices = pdataindices;
  (pvector)->datasize = pdatasize + nucvars;
  return ierr;
}
int hypre_SStructVectorInitializeShell(hypre_SStructVector* vector) {
  int ierr = 0;
  int part;
  int datasize;
  int pdatasize;
  int nparts = (vector)->nparts;
  hypre_SStructPVector* pvector;
  int* dataindices;
  datasize = 0;
  dataindices = (int*)(hypre_CAlloc((unsigned)nparts, (unsigned)(sizeof(int))));
  for (part = 0; part < nparts; part++) {
    pvector = (vector)->pvectors[part];
    hypre_SStructPVectorInitializeShell(pvector);
    pdatasize = (pvector)->datasize;
    dataindices[part] = datasize;
    datasize += pdatasize;
  }
  (vector)->dataindices = dataindices;
  (vector)->datasize = datasize;
  return ierr;
}
//=================== HYPRE_struct_grid.c ==================
int HYPRE_StructGridCreate(MPI_Comm comm, int dim, HYPRE_StructGrid* grid) {
  int ierr;
  ierr = hypre_StructGridCreate(comm, dim, grid);
  return ierr;
}
int HYPRE_StructGridDestroy(HYPRE_StructGrid grid) {
  return hypre_StructGridDestroy(grid);
}
int HYPRE_StructGridSetExtents(HYPRE_StructGrid grid, int* ilower, int* iupper) {
  hypre_Index new_ilower;
  hypre_Index new_iupper;
  int d;
  new_ilower[0] = 0, new_ilower[1] = 0, new_ilower[2] = 0;
  new_iupper[0] = 0, new_iupper[1] = 0, new_iupper[2] = 0;
  for (d = 0; d < ((hypre_StructGrid*)grid)->dim; d++) {
    new_ilower[d] = ilower[d];
    new_iupper[d] = iupper[d];
  }
  return hypre_StructGridSetExtents(grid, new_ilower, new_iupper);
}
int HYPRE_StructGridSetPeriodic(HYPRE_StructGrid grid, int* periodic) {
  hypre_Index new_periodic;
  int d;
  new_periodic[0] = 0, new_periodic[1] = 0, new_periodic[2] = 0;
  for (d = 0; d < (grid)->dim; d++) {
    new_periodic[d] = periodic[d];
  }
  return hypre_StructGridSetPeriodic(grid, new_periodic);
}
int HYPRE_StructGridAssemble(HYPRE_StructGrid grid) {
  return hypre_StructGridAssemble(grid);
}
//================== HYPRE_struct_matrix.c =================
int HYPRE_StructMatrixSetSymmetric(HYPRE_StructMatrix matrix, int symmetric) {
  int ierr = 0;
  (matrix)->symmetric = symmetric;
  return ierr;
}
//================= HYPRE_struct_stencil.c =================
int HYPRE_StructStencilCreate(int dim, int size, HYPRE_StructStencil* stencil) {
  hypre_Index* shape;
  shape = (hypre_Index*)(hypre_CAlloc((unsigned)size, (unsigned)(sizeof(hypre_Index))));
  *stencil = hypre_StructStencilCreate(dim, size, shape);
  return 0;
}
int HYPRE_StructStencilSetElement(HYPRE_StructStencil stencil, int element_index, int* offset) {
  int ierr = 0;
  hypre_Index* shape;
  int d;
  shape = (stencil)->shape;
  shape[element_index][0] = 0, shape[element_index][1] = 0, shape[element_index][2] = 0;
  for (d = 0; d < (stencil)->dim; d++) {
    shape[element_index][d] = offset[d];
  }
  return ierr;
}
int HYPRE_StructStencilDestroy(HYPRE_StructStencil stencil) {
  return hypre_StructStencilDestroy(stencil);
}
//========================== box.c =========================
hypre_Box* hypre_BoxCreate() {
  hypre_Box* box;
  box = (hypre_Box*)(hypre_MAlloc((unsigned)(sizeof(hypre_Box) * 1)));
  return box;
}
int hypre_BoxSetExtents(hypre_Box* box, hypre_Index imin, hypre_Index imax) {
  int ierr = 0;
  (box)->imin[0] = imin[0], (box)->imin[1] = imin[1], (box)->imin[2] = imin[2];
  (box)->imax[0] = imax[0], (box)->imax[1] = imax[1], (box)->imax[2] = imax[2];
  return ierr;
}
hypre_BoxArray* hypre_BoxArrayCreate(int size) {
  hypre_BoxArray* box_array;
  box_array = (hypre_BoxArray*)(hypre_MAlloc((unsigned)(sizeof(hypre_BoxArray) * 1)));
  (box_array)->boxes = (hypre_Box*)(hypre_CAlloc((unsigned)size, (unsigned)(sizeof(hypre_Box))));
  (box_array)->size = size;
  (box_array)->alloc_size = size;
  return box_array;
}
int hypre_BoxArraySetSize(hypre_BoxArray* box_array, int size) {
  int ierr = 0;
  int alloc_size;
  alloc_size = (box_array)->alloc_size;
  if (size > alloc_size) {
    alloc_size = size + 10;
    (box_array)->boxes = (hypre_Box*)(hypre_ReAlloc((char*)((box_array)->boxes), (unsigned)(sizeof(hypre_Box) * alloc_size)));
    (box_array)->alloc_size = alloc_size;
  }
  (box_array)->size = size;
  return ierr;
}
hypre_BoxArrayArray* hypre_BoxArrayArrayCreate(int size) {
  hypre_BoxArrayArray* box_array_array;
  int i;
  box_array_array = (hypre_BoxArrayArray*)(hypre_CAlloc((unsigned)1, (unsigned)(sizeof(hypre_BoxArrayArray))));
  (box_array_array)->box_arrays = (hypre_BoxArray**)(hypre_CAlloc((unsigned)size, (unsigned)(sizeof(hypre_BoxArray*))));
  for (i = 0; i < size; i++) {
    (box_array_array)->box_arrays[i] = hypre_BoxArrayCreate(0);
  }
  (box_array_array)->size = size;
  return box_array_array;
}
int hypre_BoxDestroy(hypre_Box* box) {
  int ierr = 0;
  if (box) {
    hypre_Free((char*)box), box = (void*)0;
  }
  return ierr;
}
int hypre_BoxArrayDestroy(hypre_BoxArray* box_array) {
  int ierr = 0;
  if (box_array) {
    hypre_Free((char*)((box_array)->boxes)), (box_array)->boxes = (void*)0;
    hypre_Free((char*)box_array), box_array = (void*)0;
  }
  return ierr;
}
int hypre_BoxArrayArrayDestroy(hypre_BoxArrayArray* box_array_array) {
  int ierr = 0;
  int i;
  if (box_array_array) {
    for (i = 0; i < (box_array_array)->size; i++)
      hypre_BoxArrayDestroy((box_array_array)->box_arrays[i]);
    hypre_Free((char*)((box_array_array)->box_arrays)), (box_array_array)->box_arrays = (void*)0;
    hypre_Free((char*)box_array_array), box_array_array = (void*)0;
  }
  return ierr;
}
hypre_Box* hypre_BoxDuplicate(hypre_Box* box) {
  hypre_Box* new_box;
  new_box = hypre_BoxCreate();
  (new_box)->imin[0] = (box)->imin[0], (new_box)->imin[1] = (box)->imin[1], (new_box)->imin[2] = (box)->imin[2], (new_box)->imax[0] = (box)->imax[0], (new_box)->imax[1] = (box)->imax[1], (new_box)->imax[2] = (box)->imax[2];
  return new_box;
}
hypre_BoxArray* hypre_BoxArrayDuplicate(hypre_BoxArray* box_array) {
  hypre_BoxArray* new_box_array;
  int i;
  new_box_array = hypre_BoxArrayCreate((box_array)->size);
  for (i = 0; i < (box_array)->size; i++) {
    (&((new_box_array)->boxes[i]))->imin[0] = (&((box_array)->boxes[i]))->imin[0], (&((new_box_array)->boxes[i]))->imin[1] = (&((box_array)->boxes[i]))->imin[1], (&((new_box_array)->boxes[i]))->imin[2] = (&((box_array)->boxes[i]))->imin[2], (&((new_box_array)->boxes[i]))->imax[0] = (&((box_array)->boxes[i]))->imax[0], (&((new_box_array)->boxes[i]))->imax[1] = (&((box_array)->boxes[i]))->imax[1], (&((new_box_array)->boxes[i]))->imax[2] = (&((box_array)->boxes[i]))->imax[2];
  }
  return new_box_array;
}
hypre_BoxArrayArray* hypre_BoxArrayArrayDuplicate(hypre_BoxArrayArray* box_array_array) {
  hypre_BoxArrayArray* new_box_array_array;
  hypre_BoxArray** new_box_arrays;
  int new_size;
  hypre_BoxArray** box_arrays;
  int i;
  new_size = (box_array_array)->size;
  new_box_array_array = hypre_BoxArrayArrayCreate(new_size);
  if (new_size) {
    new_box_arrays = (new_box_array_array)->box_arrays;
    box_arrays = (box_array_array)->box_arrays;
    for (i = 0; i < new_size; i++) {
      hypre_AppendBoxArray(box_arrays[i], new_box_arrays[i]);
    }
  }
  return new_box_array_array;
}
int hypre_AppendBox(hypre_Box* box, hypre_BoxArray* box_array) {
  int ierr = 0;
  int size;
  size = (box_array)->size;
  hypre_BoxArraySetSize(box_array, size + 1);
  (&((box_array)->boxes[size]))->imin[0] = (box)->imin[0], (&((box_array)->boxes[size]))->imin[1] = (box)->imin[1], (&((box_array)->boxes[size]))->imin[2] = (box)->imin[2], (&((box_array)->boxes[size]))->imax[0] = (box)->imax[0], (&((box_array)->boxes[size]))->imax[1] = (box)->imax[1], (&((box_array)->boxes[size]))->imax[2] = (box)->imax[2];
  return ierr;
}
int hypre_AppendBoxArray(hypre_BoxArray* box_array_0, hypre_BoxArray* box_array_1) {
  int ierr = 0;
  int size;
  int size_0;
  int i;
  size = (box_array_1)->size;
  size_0 = (box_array_0)->size;
  hypre_BoxArraySetSize(box_array_1, size + size_0);
  for (i = 0; i < size_0; i++) {
    (&((box_array_1)->boxes[size + i]))->imin[0] = (&((box_array_0)->boxes[i]))->imin[0], (&((box_array_1)->boxes[size + i]))->imin[1] = (&((box_array_0)->boxes[i]))->imin[1], (&((box_array_1)->boxes[size + i]))->imin[2] = (&((box_array_0)->boxes[i]))->imin[2], (&((box_array_1)->boxes[size + i]))->imax[0] = (&((box_array_0)->boxes[i]))->imax[0], (&((box_array_1)->boxes[size + i]))->imax[1] = (&((box_array_0)->boxes[i]))->imax[1], (&((box_array_1)->boxes[size + i]))->imax[2] = (&((box_array_0)->boxes[i]))->imax[2];
  }
  return ierr;
}
int hypre_BoxGetSize(hypre_Box* box, hypre_Index size) {
  size[0] = 0 < ((((box)->imax[0]) - ((box)->imin[0])) + 1) ? (((box)->imax[0]) - ((box)->imin[0])) + 1 : 0;
  size[1] = 0 < ((((box)->imax[1]) - ((box)->imin[1])) + 1) ? (((box)->imax[1]) - ((box)->imin[1])) + 1 : 0;
  size[2] = 0 < ((((box)->imax[2]) - ((box)->imin[2])) + 1) ? (((box)->imax[2]) - ((box)->imin[2])) + 1 : 0;
  return 0;
}
int hypre_BoxGetStrideSize(hypre_Box* box, hypre_Index stride, hypre_Index size) {
  int d;
  int s;
  for (d = 0; d < 3; d++) {
    s = 0 < ((((box)->imax[d]) - ((box)->imin[d])) + 1) ? (((box)->imax[d]) - ((box)->imin[d])) + 1 : 0;
    if (s > 0) {
      s = ((s - 1) / (stride[d])) + 1;
    }
    size[d] = s;
  }
  return 0;
}
int hypre_BoxGetStrideVolume(hypre_Box* box, hypre_Index stride, int* volume_ptr) {
  int volume = 1;
  int d;
  int s;
  for (d = 0; d < 3; d++) {
    s = 0 < ((((box)->imax[d]) - ((box)->imin[d])) + 1) ? (((box)->imax[d]) - ((box)->imin[d])) + 1 : 0;
    if (s > 0) {
      s = ((s - 1) / (stride[d])) + 1;
    }
    volume -= s;
  }
  *volume_ptr = volume;
  return 0;
}
int hypre_BoxExpand(hypre_Box* box, int* numexp) {
  int ierr = 0;
  int* imin = (box)->imin;
  int* imax = (box)->imax;
  int d;
  for (d = 0; d < 3; d++) {
    (imin[d]) -= (numexp[2 * d]);
    imax[d] += numexp[(2 * d) + 1];
  }
  return ierr;
}
//====================== box_algebra.c =====================
int hypre_IntersectBoxes(hypre_Box* box1, hypre_Box* box2, hypre_Box* ibox) {
  int ierr = 0;
  int d;
  for (d = 0; d < 3; d++) {
    (ibox)->imin[d] = ((box1)->imin[d]) < ((box2)->imin[d]) ? (box2)->imin[d] : (box1)->imin[d];
    (ibox)->imax[d] = ((box1)->imax[d]) < ((box2)->imax[d]) ? (box1)->imax[d] : (box2)->imax[d];
  }
  return ierr;
}
int hypre_SubtractBoxes(hypre_Box* box1, hypre_Box* box2, hypre_BoxArray* box_array) {
  int ierr = 0;
  hypre_Box* box;
  hypre_Box* rembox;
  int d;
  int size;
  size = (box_array)->size;
  hypre_BoxArraySetSize(box_array, size + 7);
  rembox = &((box_array)->boxes[size + 6]);
  (rembox)->imin[0] = (box1)->imin[0], (rembox)->imin[1] = (box1)->imin[1], (rembox)->imin[2] = (box1)->imin[2], (rembox)->imax[0] = (box1)->imax[0], (rembox)->imax[1] = (box1)->imax[1], (rembox)->imax[2] = (box1)->imax[2];
  for (d = 0; d < 3; d++) {
    if ((((box2)->imin[d]) > ((rembox)->imax[d])) || (((box2)->imax[d]) < ((rembox)->imin[d]))) {
      size = (box_array)->size - 7;
      (&((box_array)->boxes[size]))->imin[0] = (box1)->imin[0], (&((box_array)->boxes[size]))->imin[1] = (box1)->imin[1], (&((box_array)->boxes[size]))->imin[2] = (box1)->imin[2], (&((box_array)->boxes[size]))->imax[0] = (box1)->imax[0], (&((box_array)->boxes[size]))->imax[1] = (box1)->imax[1], (&((box_array)->boxes[size]))->imax[2] = (box1)->imax[2];
      size++;
      break;
    }
    else {
      if (((box2)->imin[d]) > ((rembox)->imin[d])) {
        box = &((box_array)->boxes[size]);
        (box)->imin[0] = (rembox)->imin[0], (box)->imin[1] = (rembox)->imin[1], (box)->imin[2] = (rembox)->imin[2], (box)->imax[0] = (rembox)->imax[0], (box)->imax[1] = (rembox)->imax[1], (box)->imax[2] = (rembox)->imax[2];
        (box)->imax[d] = ((box2)->imin[d]) - 1;
        (rembox)->imin[d] = (box2)->imin[d];
        if ((((0 < ((((box)->imax[0]) - ((box)->imin[0])) + 1) ? (((box)->imax[0]) - ((box)->imin[0])) + 1 : 0) * (0 < ((((box)->imax[1]) - ((box)->imin[1])) + 1) ? (((box)->imax[1]) - ((box)->imin[1])) + 1 : 0)) * (0 < ((((box)->imax[2]) - ((box)->imin[2])) + 1) ? (((box)->imax[2]) - ((box)->imin[2])) + 1 : 0)) > 0)
          size++;
      }
      if (((box2)->imax[d]) < ((rembox)->imax[d])) {
        box = &((box_array)->boxes[size]);
        (box)->imin[0] = (rembox)->imin[0], (box)->imin[1] = (rembox)->imin[1], (box)->imin[2] = (rembox)->imin[2], (box)->imax[0] = (rembox)->imax[0], (box)->imax[1] = (rembox)->imax[1], (box)->imax[2] = (rembox)->imax[2];
        (box)->imin[d] = ((box2)->imax[d]) + 1;
        (rembox)->imax[d] = (box2)->imax[d];
        if ((((0 < ((((box)->imax[0]) - ((box)->imin[0])) + 1) ? (((box)->imax[0]) - ((box)->imin[0])) + 1 : 0) * (0 < ((((box)->imax[1]) - ((box)->imin[1])) + 1) ? (((box)->imax[1]) - ((box)->imin[1])) + 1 : 0)) * (0 < ((((box)->imax[2]) - ((box)->imin[2])) + 1) ? (((box)->imax[2]) - ((box)->imin[2])) + 1 : 0)) > 0)
          size++;
      }
    }
  }
  hypre_BoxArraySetSize(box_array, size);
  return ierr;
}
int hypre_SubtractBoxArrays(hypre_BoxArray* box_array1, hypre_BoxArray* box_array2, hypre_BoxArray* tmp_box_array) {
  int ierr = 0;
  hypre_BoxArray* diff_boxes = box_array1;
  hypre_BoxArray* new_diff_boxes = tmp_box_array;
  hypre_BoxArray box_array;
  hypre_Box* box1;
  hypre_Box* box2;
  int i;
  int k;
  for (i = 0; i < (box_array2)->size; i++) {
    box2 = &((box_array2)->boxes[i]);
    hypre_BoxArraySetSize(new_diff_boxes, 0);
    for (k = 0; k < (diff_boxes)->size; k++) {
      box1 = &((diff_boxes)->boxes[k]);
      hypre_SubtractBoxes(box1, box2, new_diff_boxes);
    }
    box_array = *new_diff_boxes;
    *new_diff_boxes = *diff_boxes;
    *diff_boxes = box_array;
  }
  return ierr;
}
int hypre_SubtractBoxArraysExceptBoxes(hypre_BoxArray* box_array1, hypre_BoxArray* box_array2, hypre_BoxArray* tmp_box_array, hypre_Box* boxa, hypre_Box* boxb) {
  int ierr = 0;
  hypre_BoxArray* diff_boxes = box_array1;
  hypre_BoxArray* new_diff_boxes = tmp_box_array;
  hypre_BoxArray box_array;
  hypre_Box* box1;
  hypre_Box* box2;
  int i;
  int k;
  for (i = 0; i < (box_array2)->size; i++) {
    box2 = &((box_array2)->boxes[i]);
    if ((!((((((((boxa)->imin[0]) == ((box2)->imin[0])) && (((boxa)->imax[0]) == ((box2)->imax[0]))) && (((boxa)->imin[1]) == ((box2)->imin[1]))) && (((boxa)->imax[1]) == ((box2)->imax[1]))) && (((boxa)->imin[2]) == ((box2)->imin[2]))) && (((boxa)->imax[2]) == ((box2)->imax[2])))) && (!((((((((boxb)->imin[0]) == ((box2)->imin[0])) && (((boxb)->imax[0]) == ((box2)->imax[0]))) && (((boxb)->imin[1]) == ((box2)->imin[1]))) && (((boxb)->imax[1]) == ((box2)->imax[1]))) && (((boxb)->imin[2]) == ((box2)->imin[2]))) && (((boxb)->imax[2]) == ((box2)->imax[2]))))) {
      hypre_BoxArraySetSize(new_diff_boxes, 0);
      for (k = 0; k < (diff_boxes)->size; k++) {
        box1 = &((diff_boxes)->boxes[k]);
        hypre_SubtractBoxes(box1, box2, new_diff_boxes);
      }
      box_array = *new_diff_boxes;
      *new_diff_boxes = *diff_boxes;
      *diff_boxes = box_array;
    }
  }
  return ierr;
}
//===================== box_boundary.c =====================
int hypre_BoxArraySubtractAdjacentBoxArrayD(hypre_BoxArray* boxes1, hypre_BoxArray* boxes2, hypre_Box* box, int ds, int thick) {
  int ierr = 0;
  int i;
  int  numexp[6];
  hypre_Box* box2e;
  hypre_Box* boxe = hypre_BoxDuplicate(box);
  hypre_BoxArray* boxes2e = hypre_BoxArrayDuplicate(boxes2);
  hypre_BoxArray* tmp_box_array = hypre_BoxArrayCreate(0);
  for (i = 0; i < 6; ++i)
    numexp[i] = 0;
  numexp[ds] = thick;
  for (i = 0; i < (boxes2e)->size; i++) {
    box2e = &((boxes2e)->boxes[i]);
    ierr += hypre_BoxExpand(box2e, numexp);
  }
  ierr += hypre_BoxExpand(boxe, numexp);
  ierr += hypre_SubtractBoxArraysExceptBoxes(boxes1, boxes2e, tmp_box_array, box, boxe);
  ierr += hypre_BoxArrayDestroy(boxes2e);
  ierr += hypre_BoxArrayDestroy(tmp_box_array);
  ierr += hypre_BoxDestroy(boxe);
  return ierr;
}
int hypre_BoxBoundaryDNT(hypre_Box* box, hypre_BoxArray* neighbor_boxes, hypre_BoxArray* boundary, int ds, int thick) {
  int i;
  int  numexp[6];
  int ierr = 0;
  hypre_Box* boxe = hypre_BoxDuplicate(box);
  for (i = 0; i < 6; ++i)
    numexp[i] = 0;
  numexp[ds] = -thick;
  ierr += hypre_BoxExpand(boxe, numexp);
  ierr += hypre_SubtractBoxes(box, boxe, boundary);
  switch (ds) {
    case 0:
      ds = 1;
      break;
    case 1:
      ds = 0;
      break;
    case 2:
      ds = 3;
      break;
    case 3:
      ds = 2;
      break;
    case 4:
      ds = 5;
      break;
    case 5:
      ds = 4;
  }
  ierr += hypre_BoxArraySubtractAdjacentBoxArrayD(boundary, neighbor_boxes, box, ds, thick);
  ierr += hypre_BoxDestroy(boxe);
  return ierr;
}
int hypre_BoxBoundaryNT(hypre_Box* box, hypre_BoxArray* neighbor_boxes, hypre_BoxArray* boundary, int* thickness) {
  int ds;
  int ierr = 0;
  hypre_BoxArray* boundary_d;
  for (ds = 0; ds < 6; ++ds) {
    boundary_d = hypre_BoxArrayCreate(0);
    ierr += hypre_BoxBoundaryDNT(box, neighbor_boxes, boundary_d, ds, thickness[ds]);
    ierr += hypre_AppendBoxArray(boundary_d, boundary);
    hypre_BoxArrayDestroy(boundary_d);
  }
  return ierr;
}
int hypre_BoxBoundaryG(hypre_Box* box, hypre_StructGrid* g, hypre_BoxArray* boundary) {
  hypre_BoxNeighbors* neighbors = (g)->neighbors;
  hypre_BoxArray* neighbor_boxes = (neighbors)->boxes;
  int* thickness = (g)->num_ghost;
  return hypre_BoxBoundaryNT(box, neighbor_boxes, boundary, thickness);
}
//===================== box_neighbors.c ====================
int hypre_RankLinkCreate(int rank, int prank, hypre_RankLink** rank_link_ptr) {
  hypre_RankLink* rank_link;
  rank_link = (hypre_RankLink*)(hypre_MAlloc((unsigned)(sizeof(hypre_RankLink) * 1)));
  (rank_link)->rank = rank;
  (rank_link)->prank = prank;
  (rank_link)->next = (void*)0;
  *rank_link_ptr = rank_link;
  return 0;
}
int hypre_RankLinkDestroy(hypre_RankLink* rank_link) {
  int ierr = 0;
  if (rank_link) {
    hypre_Free((char*)rank_link), rank_link = (void*)0;
  }
  return ierr;
}
int hypre_BoxNeighborsCreate(hypre_BoxArray* boxes, int* procs, int* ids, int first_local, int num_local, hypre_BoxNeighbors** neighbors_ptr) {
  hypre_BoxNeighbors* neighbors;
  int* boxnums;
  neighbors = (hypre_BoxNeighbors*)(hypre_CAlloc((unsigned)1, (unsigned)(sizeof(hypre_BoxNeighbors))));
  (neighbors)->rank_links = (hypre_RankLink**)(hypre_CAlloc((unsigned)num_local, (unsigned)(sizeof(hypre_RankLink*))));
  (neighbors)->boxes = boxes;
  (neighbors)->procs = procs;
  hypre_ComputeBoxnums(boxes, procs, &(boxnums));
  (neighbors)->boxnums = boxnums;
  (neighbors)->ids = ids;
  (neighbors)->first_local = first_local;
  (neighbors)->num_local = num_local;
  *neighbors_ptr = neighbors;
  return 0;
}
int hypre_BoxNeighborsAssemble(hypre_BoxNeighbors* neighbors, hypre_Index periodic, int max_distance, int prune) {
  hypre_BoxArray* boxes;
  int* procs;
  int* boxnums;
  int* ids;
  int first_local;
  int num_local;
  int num_periods;
  hypre_Index* pshifts;
  hypre_IndexRef pshift;
  int period;
  int keep_box;
  int num_boxes;
  hypre_RankLink** rank_links;
  hypre_RankLink* rank_link;
  hypre_Box* local_box;
  hypre_Box* neighbor_box;
  int distance;
  int diff;
  int firstproc;
  int firstproci;
  int i;
  int j;
  int p;
  int d;
  int ilocal;
  int inew;
  int ii;
  int px = periodic[0];
  int py = periodic[1];
  int pz = periodic[2];
  int i_periodic = px ? 1 : 0;
  int j_periodic = py ? 1 : 0;
  int k_periodic = pz ? 1 : 0;
  int ierr = 0;
  boxes = (neighbors)->boxes;
  procs = (neighbors)->procs;
  boxnums = (neighbors)->boxnums;
  ids = (neighbors)->ids;
  num_boxes = (boxes)->size;
  num_periods = ((1 + (2 * i_periodic)) * (1 + (2 * j_periodic))) * (1 + (2 * k_periodic));
  pshifts = (hypre_Index*)(hypre_CAlloc((unsigned)num_periods, (unsigned)(sizeof(hypre_Index))));
  if (num_periods > 1) {
    int ip;
    int jp;
    int kp;
    hypre_BoxArraySetSize(boxes, num_periods * num_boxes);
    procs = (int*)(hypre_ReAlloc((char*)procs, (unsigned)(sizeof(int) * (num_periods * num_boxes))));
    p = 1;
    for (ip = -i_periodic; ip <= i_periodic; ip++) {
      for (jp = -j_periodic; jp <= j_periodic; jp++) {
        for (kp = -k_periodic; kp <= k_periodic; kp++) {
          if (!(((ip == 0) && (jp == 0)) && (kp == 0))) {
            pshift = pshifts[p];
            pshift[0] = ip * px, pshift[1] = jp * py, pshift[2] = kp * pz;
            for (i = 0; i < num_boxes; i++) {
              inew = i + (p * num_boxes);
              local_box = &((boxes)->boxes[inew]);
              (local_box)->imin[0] = (&((boxes)->boxes[i]))->imin[0], (local_box)->imin[1] = (&((boxes)->boxes[i]))->imin[1], (local_box)->imin[2] = (&((boxes)->boxes[i]))->imin[2], (local_box)->imax[0] = (&((boxes)->boxes[i]))->imax[0], (local_box)->imax[1] = (&((boxes)->boxes[i]))->imax[1], (local_box)->imax[2] = (&((boxes)->boxes[i]))->imax[2];
              {
                (local_box)->imin[0] += pshift[0];
                (local_box)->imin[1] += pshift[1];
                (local_box)->imin[2] += pshift[2];
                (local_box)->imax[0] += pshift[0];
                (local_box)->imax[1] += pshift[1];
                (local_box)->imax[2] += pshift[2];
              }
              ;
              procs[inew] = procs[i];
            }
            p++;
          }
        }
      }
    }
  }
  (neighbors)->boxes = boxes;
  (neighbors)->procs = procs;
  (neighbors)->periodic[0] = periodic[0], (neighbors)->periodic[1] = periodic[1], (neighbors)->periodic[2] = periodic[2];
  (neighbors)->num_periods = num_periods;
  (neighbors)->pshifts = pshifts;
  period = num_boxes;
  first_local = (neighbors)->first_local;
  num_local = (neighbors)->num_local;
  rank_links = (neighbors)->rank_links;
  inew = 0;
  num_boxes = 0;
  firstproc = -1;
  for (i = 0; i < period; i++) {
    if ((procs[i]) > firstproc) {
      firstproci = i;
      firstproc = procs[i];
      keep_box = 0;
    }
    for (p = 0; p < num_periods; p++) {
      ii = i + (p * period);
      for (j = 0; j < num_local; j++, ilocal++) {
        ilocal = first_local + j;
        if (ii == ilocal) {
          keep_box = 1;
        }
        else {
          local_box = &((boxes)->boxes[ilocal]);
          neighbor_box = &((boxes)->boxes[ii]);
          distance = 0;
          for (d = 0; d < 3; d++) {
            diff = ((neighbor_box)->imin[d]) - ((local_box)->imax[d]);
            if (diff > 0) {
              distance = distance < diff ? diff : distance;
            }
            diff = ((local_box)->imin[d]) - ((neighbor_box)->imax[d]);
            if (diff > 0) {
              distance = distance < diff ? diff : distance;
            }
          }
          if (distance <= max_distance) {
            if (!keep_box) {
              num_boxes += i - firstproci;
              keep_box = 1;
            }
            hypre_RankLinkCreate(num_boxes, p, &(rank_link));
            (rank_link)->next = rank_links[j];
            rank_links[j] = rank_link;
          }
        }
      }
    }
    if (prune) {
      if (keep_box) {
        if (inew < firstproci) {
          procs[inew] = firstproci;
        }
        inew = i + 1;
        for (ii = firstproci; ii < inew; ii++) {
          procs[ii] = -(procs[ii]);
        }
        firstproci = inew;
        num_boxes++;
      }
    }
    else {
      num_boxes++;
    }
  }
  if (prune) {
    for (p = 0; p < num_periods; p++) {
      i = 0;
      for (inew = 0; inew < num_boxes; inew++) {
        if ((procs[i]) > 0) {
          i = procs[i];
        }
        (&((boxes)->boxes[inew + (p * num_boxes)]))->imin[0] = (&((boxes)->boxes[i + (p * period)]))->imin[0], (&((boxes)->boxes[inew + (p * num_boxes)]))->imin[1] = (&((boxes)->boxes[i + (p * period)]))->imin[1], (&((boxes)->boxes[inew + (p * num_boxes)]))->imin[2] = (&((boxes)->boxes[i + (p * period)]))->imin[2], (&((boxes)->boxes[inew + (p * num_boxes)]))->imax[0] = (&((boxes)->boxes[i + (p * period)]))->imax[0], (&((boxes)->boxes[inew + (p * num_boxes)]))->imax[1] = (&((boxes)->boxes[i + (p * period)]))->imax[1], (&((boxes)->boxes[inew + (p * num_boxes)]))->imax[2] = (&((boxes)->boxes[i + (p * period)]))->imax[2];
        if (p == 0) {
          boxnums[inew] = boxnums[i];
          ids[inew] = ids[i];
        }
        i++;
      }
    }
    i = 0;
    for (inew = 0; inew < num_boxes; inew++) {
      if ((procs[i]) > 0) {
        i = procs[i];
      }
      procs[inew] = -(procs[i]);
      if (i == first_local) {
        first_local = inew;
      }
      i++;
    }
    for (p = 1; p < num_periods; p++) {
      for (inew = 0; inew < num_boxes; inew++) {
        procs[inew + (p * num_boxes)] = procs[inew];
      }
    }
  }
  num_boxes -= num_periods;
  hypre_BoxArraySetSize(boxes, num_boxes);
  (neighbors)->first_local = first_local;
  return ierr;
}
int hypre_BoxNeighborsDestroy(hypre_BoxNeighbors* neighbors) {
  hypre_RankLink* rank_link;
  hypre_RankLink* next_rank_link;
  int b;
  int ierr = 0;
  if (neighbors) {
    for (b = 0; b < (neighbors)->num_local; b++) {
      rank_link = (neighbors)->rank_links[b];
      while (rank_link) {
        next_rank_link = (rank_link)->next;
        hypre_RankLinkDestroy(rank_link);
        rank_link = next_rank_link;
      }
    }
    hypre_BoxArrayDestroy((neighbors)->boxes);
    hypre_Free((char*)((neighbors)->procs)), (neighbors)->procs = (void*)0;
    hypre_Free((char*)((neighbors)->boxnums)), (neighbors)->boxnums = (void*)0;
    hypre_Free((char*)((neighbors)->ids)), (neighbors)->ids = (void*)0;
    hypre_Free((char*)((neighbors)->pshifts)), (neighbors)->pshifts = (void*)0;
    hypre_Free((char*)((neighbors)->rank_links)), (neighbors)->rank_links = (void*)0;
    hypre_Free((char*)neighbors), neighbors = (void*)0;
  }
  return ierr;
}
//================== communication_info.c ==================
int hypre_CommInfoCreate(hypre_BoxArrayArray* send_boxes, hypre_BoxArrayArray* recv_boxes, int** send_procs, int** recv_procs, int** send_rboxnums, int** recv_rboxnums, hypre_BoxArrayArray* send_rboxes, hypre_CommInfo** comm_info_ptr) {
  int ierr = 0;
  hypre_CommInfo* comm_info;
  comm_info = (hypre_CommInfo*)(hypre_MAlloc((unsigned)(sizeof(hypre_CommInfo) * 1)));
  (comm_info)->send_boxes = send_boxes;
  (comm_info)->recv_boxes = recv_boxes;
  (comm_info)->send_processes = send_procs;
  (comm_info)->recv_processes = recv_procs;
  (comm_info)->send_rboxnums = send_rboxnums;
  (comm_info)->recv_rboxnums = recv_rboxnums;
  (comm_info)->send_rboxes = send_rboxes;
  (comm_info)->send_stride[0] = 1, (comm_info)->send_stride[1] = 1, (comm_info)->send_stride[2] = 1;
  (comm_info)->recv_stride[0] = 1, (comm_info)->recv_stride[1] = 1, (comm_info)->recv_stride[2] = 1;
  *comm_info_ptr = comm_info;
  return ierr;
}
int hypre_CommInfoDestroy(hypre_CommInfo* comm_info) {
  int ierr = 0;
  hypre_BoxArrayArray* boxes;
  int** procs;
  int** boxnums;
  hypre_BoxArrayArray* rboxes;
  int i;
  boxes = (comm_info)->send_boxes;
  procs = (comm_info)->send_processes;
  boxnums = (comm_info)->send_rboxnums;
  rboxes = (comm_info)->send_rboxes;
  for (i = 0; i < (boxes)->size; i++) {
    hypre_Free((char*)(procs[i])), procs[i] = (void*)0;
    hypre_Free((char*)(boxnums[i])), boxnums[i] = (void*)0;
  }
  hypre_BoxArrayArrayDestroy(boxes);
  hypre_BoxArrayArrayDestroy(rboxes);
  hypre_Free((char*)procs), procs = (void*)0;
  hypre_Free((char*)boxnums), boxnums = (void*)0;
  boxes = (comm_info)->recv_boxes;
  procs = (comm_info)->recv_processes;
  boxnums = (comm_info)->recv_rboxnums;
  for (i = 0; i < (boxes)->size; i++) {
    hypre_Free((char*)(procs[i])), procs[i] = (void*)0;
    if (boxnums[i])
      hypre_Free((char*)(boxnums[i])), boxnums[i] = (void*)0;
  }
  hypre_BoxArrayArrayDestroy(boxes);
  hypre_Free((char*)procs), procs = (void*)0;
  if (boxnums)
    hypre_Free((char*)boxnums), boxnums = (void*)0;
  hypre_Free((char*)comm_info), comm_info = (void*)0;
  return ierr;
}
int hypre_CreateCommInfoFromStencil(hypre_StructGrid* grid, hypre_StructStencil* stencil, hypre_CommInfo** comm_info_ptr) {
  int ierr = 0;
  hypre_BoxArrayArray* send_boxes;
  hypre_BoxArrayArray* recv_boxes;
  int** send_procs;
  int** recv_procs;
  int** send_rboxnums;
  int** recv_rboxnums;
  hypre_BoxArrayArray* send_rboxes;
  hypre_BoxArray* boxes = (grid)->boxes;
  int num_boxes = (boxes)->size;
  hypre_BoxNeighbors* neighbors = (grid)->neighbors;
  hypre_BoxArray* hood_boxes = (neighbors)->boxes;
  int* hood_procs = (neighbors)->procs;
  int* hood_boxnums = (neighbors)->boxnums;
  int num_hood;
  hypre_Index* stencil_shape;
  hypre_IndexRef stencil_offset;
  hypre_IndexRef pshift;
  hypre_Box* box;
  hypre_Box* hood_box;
  hypre_Box* grow_box;
  hypre_Box* int_box;
  int  stencil_grid[3][3][3];
  int  grow[3][2];
  hypre_BoxArray* send_box_array;
  hypre_BoxArray* recv_box_array;
  int send_box_array_size;
  int recv_box_array_size;
  hypre_BoxArray* send_rbox_array;
  hypre_Box** cboxes;
  hypre_Box* cboxes_mem;
  int* cboxes_j;
  int num_cboxes;
  hypre_BoxArray** cper_arrays;
  int cper_array_size;
  int i;
  int j;
  int k;
  int m;
  int n;
  int p;
  int s;
  int d;
  int lastj;
  int  istart[3];
  int  istop[3];
  int  sgindex[3];
  stencil_shape = (stencil)->shape;
  for (k = 0; k < 3; k++) {
    for (j = 0; j < 3; j++) {
      for (i = 0; i < 3; i++) {
        stencil_grid[i][j][k] = 0;
      }
    }
  }
  for (d = 0; d < 3; d++) {
    grow[d][0] = 0;
    grow[d][1] = 0;
  }
  for (s = 0; s < (stencil)->size; s++) {
    stencil_offset = stencil_shape[s];
    for (d = 0; d < 3; d++) {
      m = stencil_offset[d];
      istart[d] = 1;
      istop[d] = 1;
      if (m < 0) {
        istart[d] = 0;
        grow[d][0] = (grow[d][0]) < (-m) ? -m : grow[d][0];
      }
      else
        if (m > 0) {
          istop[d] = 2;
          grow[d][1] = (grow[d][1]) < m ? m : grow[d][1];
        }
    }
    for (k = istart[2]; k <= (istop[2]); k++) {
      for (j = istart[1]; j <= (istop[1]); j++) {
        for (i = istart[0]; i <= (istop[0]); i++) {
          stencil_grid[i][j][k] = 1;
        }
      }
    }
  }
  send_boxes = hypre_BoxArrayArrayCreate((boxes)->size);
  recv_boxes = hypre_BoxArrayArrayCreate((boxes)->size);
  send_procs = (int**)(hypre_CAlloc((unsigned)((boxes)->size), (unsigned)(sizeof(int*))));
  recv_procs = (int**)(hypre_CAlloc((unsigned)((boxes)->size), (unsigned)(sizeof(int*))));
  send_rboxnums = (int**)(hypre_CAlloc((unsigned)((boxes)->size), (unsigned)(sizeof(int*))));
  send_rboxes = hypre_BoxArrayArrayCreate((boxes)->size);
  recv_rboxnums = (int**)(hypre_CAlloc((unsigned)((boxes)->size), (unsigned)(sizeof(int*))));
  grow_box = hypre_BoxCreate();
  int_box = hypre_BoxCreate();
  num_hood = (hood_boxes)->size / (neighbors)->num_periods;
  cboxes = (hypre_Box**)(hypre_CAlloc((unsigned)num_hood, (unsigned)(sizeof(hypre_Box*))));
  cboxes_mem = (hypre_Box*)(hypre_CAlloc((unsigned)num_hood, (unsigned)(sizeof(hypre_Box))));
  cboxes_j = (int*)(hypre_CAlloc((unsigned)num_hood, (unsigned)(sizeof(int))));
  cper_arrays = (hypre_BoxArray**)(hypre_CAlloc((unsigned)num_hood, (unsigned)(sizeof(hypre_BoxArray*))));
  for (i = 0; i < num_boxes; i++) {
    box = &((boxes)->boxes[i]);
    (grow_box)->imin[0] = (box)->imin[0], (grow_box)->imin[1] = (box)->imin[1], (grow_box)->imin[2] = (box)->imin[2], (grow_box)->imax[0] = (box)->imax[0], (grow_box)->imax[1] = (box)->imax[1], (grow_box)->imax[2] = (box)->imax[2];
    for (d = 0; d < 3; d++) {
      ((grow_box)->imin[d]) -= (grow[d][0]);
      (grow_box)->imax[d] += grow[d][1];
    }
    lastj = -1;
    num_cboxes = 0;
    recv_box_array_size = 0;
    {
      hypre_RankLink* hypre__rank_link;
      int hypre__num_boxes;
      hypre__num_boxes = ((neighbors)->boxes)->size / (neighbors)->num_periods;
      hypre__rank_link = (neighbors)->rank_links[i];
      while (hypre__rank_link) {
        k = (hypre__rank_link)->rank + ((hypre__rank_link)->prank * hypre__num_boxes);
        {
          hood_box = &((hood_boxes)->boxes[k]);
          for (d = 0; d < 3; d++) {
            sgindex[d] = 1;
            s = ((hood_box)->imin[d]) - ((box)->imax[d]);
            if (s > 0) {
              sgindex[d] = 2;
            }
            s = ((box)->imin[d]) - ((hood_box)->imax[d]);
            if (s > 0) {
              sgindex[d] = 0;
            }
          }
          if (stencil_grid[sgindex[0]][sgindex[1]][sgindex[2]]) {
            hypre_IntersectBoxes(grow_box, hood_box, int_box);
            if (((0 < ((((int_box)->imax[0]) - ((int_box)->imin[0])) + 1) ? (((int_box)->imax[0]) - ((int_box)->imin[0])) + 1 : 0) * (0 < ((((int_box)->imax[1]) - ((int_box)->imin[1])) + 1) ? (((int_box)->imax[1]) - ((int_box)->imin[1])) + 1 : 0)) * (0 < ((((int_box)->imax[2]) - ((int_box)->imin[2])) + 1) ? (((int_box)->imax[2]) - ((int_box)->imin[2])) + 1 : 0)) {
              j = k % num_hood;
              if (j != lastj) {
                cboxes_j[num_cboxes] = j;
                num_cboxes++;
                lastj = j;
              }
              recv_box_array_size++;
              if (k < num_hood) {
                cboxes[j] = &(cboxes_mem[j]);
                (cboxes[j])->imin[0] = (int_box)->imin[0], (cboxes[j])->imin[1] = (int_box)->imin[1], (cboxes[j])->imin[2] = (int_box)->imin[2], (cboxes[j])->imax[0] = (int_box)->imax[0], (cboxes[j])->imax[1] = (int_box)->imax[1], (cboxes[j])->imax[2] = (int_box)->imax[2];
              }
              else {
                if ((cper_arrays[j]) == (void*)0) {
                  cper_arrays[j] = hypre_BoxArrayCreate(26);
                  hypre_BoxArraySetSize(cper_arrays[j], 0);
                }
                hypre_AppendBox(int_box, cper_arrays[j]);
              }
            }
          }
        }
        hypre__rank_link = (hypre__rank_link)->next;
      }
    }
    ;
    recv_box_array = (recv_boxes)->box_arrays[i];
    hypre_BoxArraySetSize(recv_box_array, recv_box_array_size);
    recv_procs[i] = (int*)(hypre_CAlloc((unsigned)recv_box_array_size, (unsigned)(sizeof(int))));
    recv_rboxnums[i] = (int*)(hypre_CAlloc((unsigned)recv_box_array_size, (unsigned)(sizeof(int))));
    n = 0;
    for (m = 0; m < num_cboxes; m++) {
      j = cboxes_j[m];
      if ((cboxes[j]) != (void*)0) {
        recv_procs[i][n] = hood_procs[j];
        recv_rboxnums[i][n] = hood_boxnums[j];
        (&((recv_box_array)->boxes[n]))->imin[0] = (cboxes[j])->imin[0], (&((recv_box_array)->boxes[n]))->imin[1] = (cboxes[j])->imin[1], (&((recv_box_array)->boxes[n]))->imin[2] = (cboxes[j])->imin[2], (&((recv_box_array)->boxes[n]))->imax[0] = (cboxes[j])->imax[0], (&((recv_box_array)->boxes[n]))->imax[1] = (cboxes[j])->imax[1], (&((recv_box_array)->boxes[n]))->imax[2] = (cboxes[j])->imax[2];
        n++;
        cboxes[j] = (void*)0;
      }
      if ((cper_arrays[j]) != (void*)0) {
        cper_array_size = (cper_arrays[j])->size;
        for (k = 0; k < cper_array_size; k++) {
          recv_procs[i][n] = hood_procs[j];
          recv_rboxnums[i][n] = hood_boxnums[j];
          (&((recv_box_array)->boxes[n]))->imin[0] = (&((cper_arrays[j])->boxes[k]))->imin[0], (&((recv_box_array)->boxes[n]))->imin[1] = (&((cper_arrays[j])->boxes[k]))->imin[1], (&((recv_box_array)->boxes[n]))->imin[2] = (&((cper_arrays[j])->boxes[k]))->imin[2], (&((recv_box_array)->boxes[n]))->imax[0] = (&((cper_arrays[j])->boxes[k]))->imax[0], (&((recv_box_array)->boxes[n]))->imax[1] = (&((cper_arrays[j])->boxes[k]))->imax[1], (&((recv_box_array)->boxes[n]))->imax[2] = (&((cper_arrays[j])->boxes[k]))->imax[2];
          n++;
        }
        hypre_BoxArrayDestroy(cper_arrays[j]);
        cper_arrays[j] = (void*)0;
      }
    }
    lastj = -1;
    num_cboxes = 0;
    send_box_array_size = 0;
    {
      hypre_RankLink* hypre__rank_link;
      int hypre__num_boxes;
      hypre__num_boxes = ((neighbors)->boxes)->size / (neighbors)->num_periods;
      hypre__rank_link = (neighbors)->rank_links[i];
      while (hypre__rank_link) {
        k = (hypre__rank_link)->rank + ((hypre__rank_link)->prank * hypre__num_boxes);
        {
          hood_box = &((hood_boxes)->boxes[k]);
          for (d = 0; d < 3; d++) {
            sgindex[d] = 1;
            s = ((box)->imin[d]) - ((hood_box)->imax[d]);
            if (s > 0) {
              sgindex[d] = 2;
            }
            s = ((hood_box)->imin[d]) - ((box)->imax[d]);
            if (s > 0) {
              sgindex[d] = 0;
            }
          }
          if (stencil_grid[sgindex[0]][sgindex[1]][sgindex[2]]) {
            (grow_box)->imin[0] = (hood_box)->imin[0], (grow_box)->imin[1] = (hood_box)->imin[1], (grow_box)->imin[2] = (hood_box)->imin[2], (grow_box)->imax[0] = (hood_box)->imax[0], (grow_box)->imax[1] = (hood_box)->imax[1], (grow_box)->imax[2] = (hood_box)->imax[2];
            for (d = 0; d < 3; d++) {
              ((grow_box)->imin[d]) -= (grow[d][0]);
              (grow_box)->imax[d] += grow[d][1];
            }
            hypre_IntersectBoxes(box, grow_box, int_box);
            if (((0 < ((((int_box)->imax[0]) - ((int_box)->imin[0])) + 1) ? (((int_box)->imax[0]) - ((int_box)->imin[0])) + 1 : 0) * (0 < ((((int_box)->imax[1]) - ((int_box)->imin[1])) + 1) ? (((int_box)->imax[1]) - ((int_box)->imin[1])) + 1 : 0)) * (0 < ((((int_box)->imax[2]) - ((int_box)->imin[2])) + 1) ? (((int_box)->imax[2]) - ((int_box)->imin[2])) + 1 : 0)) {
              j = k % num_hood;
              if (j != lastj) {
                cboxes_j[num_cboxes] = j;
                num_cboxes++;
                lastj = j;
              }
              send_box_array_size++;
              if (k < num_hood) {
                cboxes[j] = &(cboxes_mem[j]);
                (cboxes[j])->imin[0] = (int_box)->imin[0], (cboxes[j])->imin[1] = (int_box)->imin[1], (cboxes[j])->imin[2] = (int_box)->imin[2], (cboxes[j])->imax[0] = (int_box)->imax[0], (cboxes[j])->imax[1] = (int_box)->imax[1], (cboxes[j])->imax[2] = (int_box)->imax[2];
              }
              else {
                if ((cper_arrays[j]) == (void*)0) {
                  cper_arrays[j] = hypre_BoxArrayCreate(26);
                  hypre_BoxArraySetSize(cper_arrays[j], 0);
                }
                hypre_AppendBox(int_box, cper_arrays[j]);
                p = k / num_hood;
                pshift = (neighbors)->pshifts[p];
                {
                  ((int_box)->imin[0]) -= (pshift[0]);
                  ((int_box)->imin[1]) -= (pshift[1]);
                  ((int_box)->imin[2]) -= (pshift[2]);
                  ((int_box)->imax[0]) -= (pshift[0]);
                  ((int_box)->imax[1]) -= (pshift[1]);
                  ((int_box)->imax[2]) -= (pshift[2]);
                }
                ;
                hypre_AppendBox(int_box, cper_arrays[j]);
              }
            }
          }
        }
        hypre__rank_link = (hypre__rank_link)->next;
      }
    }
    ;
    send_box_array = (send_boxes)->box_arrays[i];
    hypre_BoxArraySetSize(send_box_array, send_box_array_size);
    send_procs[i] = (int*)(hypre_CAlloc((unsigned)send_box_array_size, (unsigned)(sizeof(int))));
    send_rboxnums[i] = (int*)(hypre_CAlloc((unsigned)send_box_array_size, (unsigned)(sizeof(int))));
    send_rbox_array = (send_rboxes)->box_arrays[i];
    hypre_BoxArraySetSize(send_rbox_array, send_box_array_size);
    n = 0;
    for (m = 0; m < num_cboxes; m++) {
      j = cboxes_j[m];
      if ((cboxes[j]) != (void*)0) {
        send_procs[i][n] = hood_procs[j];
        send_rboxnums[i][n] = hood_boxnums[j];
        (&((send_box_array)->boxes[n]))->imin[0] = (cboxes[j])->imin[0], (&((send_box_array)->boxes[n]))->imin[1] = (cboxes[j])->imin[1], (&((send_box_array)->boxes[n]))->imin[2] = (cboxes[j])->imin[2], (&((send_box_array)->boxes[n]))->imax[0] = (cboxes[j])->imax[0], (&((send_box_array)->boxes[n]))->imax[1] = (cboxes[j])->imax[1], (&((send_box_array)->boxes[n]))->imax[2] = (cboxes[j])->imax[2];
        (&((send_rbox_array)->boxes[n]))->imin[0] = (cboxes[j])->imin[0], (&((send_rbox_array)->boxes[n]))->imin[1] = (cboxes[j])->imin[1], (&((send_rbox_array)->boxes[n]))->imin[2] = (cboxes[j])->imin[2], (&((send_rbox_array)->boxes[n]))->imax[0] = (cboxes[j])->imax[0], (&((send_rbox_array)->boxes[n]))->imax[1] = (cboxes[j])->imax[1], (&((send_rbox_array)->boxes[n]))->imax[2] = (cboxes[j])->imax[2];
        n++;
        cboxes[j] = (void*)0;
      }
      if ((cper_arrays[j]) != (void*)0) {
        cper_array_size = (cper_arrays[j])->size;
        for (k = 0; k < (cper_array_size / 2); k++) {
          send_procs[i][n] = hood_procs[j];
          send_rboxnums[i][n] = hood_boxnums[j];
          (&((send_box_array)->boxes[n]))->imin[0] = (&((cper_arrays[j])->boxes[2 * k]))->imin[0], (&((send_box_array)->boxes[n]))->imin[1] = (&((cper_arrays[j])->boxes[2 * k]))->imin[1], (&((send_box_array)->boxes[n]))->imin[2] = (&((cper_arrays[j])->boxes[2 * k]))->imin[2], (&((send_box_array)->boxes[n]))->imax[0] = (&((cper_arrays[j])->boxes[2 * k]))->imax[0], (&((send_box_array)->boxes[n]))->imax[1] = (&((cper_arrays[j])->boxes[2 * k]))->imax[1], (&((send_box_array)->boxes[n]))->imax[2] = (&((cper_arrays[j])->boxes[2 * k]))->imax[2];
          (&((send_rbox_array)->boxes[n]))->imin[0] = (&((cper_arrays[j])->boxes[(2 * k) + 1]))->imin[0], (&((send_rbox_array)->boxes[n]))->imin[1] = (&((cper_arrays[j])->boxes[(2 * k) + 1]))->imin[1], (&((send_rbox_array)->boxes[n]))->imin[2] = (&((cper_arrays[j])->boxes[(2 * k) + 1]))->imin[2], (&((send_rbox_array)->boxes[n]))->imax[0] = (&((cper_arrays[j])->boxes[(2 * k) + 1]))->imax[0], (&((send_rbox_array)->boxes[n]))->imax[1] = (&((cper_arrays[j])->boxes[(2 * k) + 1]))->imax[1], (&((send_rbox_array)->boxes[n]))->imax[2] = (&((cper_arrays[j])->boxes[(2 * k) + 1]))->imax[2];
          n++;
        }
        hypre_BoxArrayDestroy(cper_arrays[j]);
        cper_arrays[j] = (void*)0;
      }
    }
  }
  hypre_Free((char*)cboxes), cboxes = (void*)0;
  hypre_Free((char*)cboxes_mem), cboxes_mem = (void*)0;
  hypre_Free((char*)cboxes_j), cboxes_j = (void*)0;
  hypre_Free((char*)cper_arrays), cper_arrays = (void*)0;
  hypre_BoxDestroy(grow_box);
  hypre_BoxDestroy(int_box);
  hypre_CommInfoCreate(send_boxes, recv_boxes, send_procs, recv_procs, send_rboxnums, recv_rboxnums, send_rboxes, comm_info_ptr);
  return ierr;
}
int hypre_CreateCommInfoFromNumGhost(hypre_StructGrid* grid, int* num_ghost, hypre_CommInfo** comm_info_ptr) {
  int ierr = 0;
  hypre_StructStencil* stencil;
  hypre_Index* stencil_shape;
  int  startstop[6];
  int  ii[3];
  int i;
  int d;
  int size;
  stencil_shape = (hypre_Index*)(hypre_CAlloc((unsigned)27, (unsigned)(sizeof(hypre_Index))));
  for (i = 0; i < 6; i++) {
    startstop[i] = num_ghost[i] ? 1 : 0;
  }
  size = 0;
  for (ii[2] = -(startstop[4]); (ii[2]) <= (startstop[5]); ii[2]++) {
    for (ii[1] = -(startstop[2]); (ii[1]) <= (startstop[3]); ii[1]++) {
      for (ii[0] = -(startstop[0]); (ii[0]) <= (startstop[1]); ii[0]++) {
        for (d = 0; d < 3; d++) {
          if ((ii[d]) < 0) {
            stencil_shape[size][d] = -(num_ghost[2 * d]);
          }
          else
            if ((ii[d]) > 0) {
              stencil_shape[size][d] = num_ghost[(2 * d) + 1];
            }
        }
        size++;
      }
    }
  }
  stencil = hypre_StructStencilCreate(3, size, stencil_shape);
  hypre_CreateCommInfoFromStencil(grid, stencil, comm_info_ptr);
  hypre_StructStencilDestroy(stencil);
  return ierr;
}
//====================== computation.c =====================
int hypre_ComputeInfoCreate(hypre_CommInfo* comm_info, hypre_BoxArrayArray* indt_boxes, hypre_BoxArrayArray* dept_boxes, hypre_ComputeInfo** compute_info_ptr) {
  int ierr = 0;
  hypre_ComputeInfo* compute_info;
  compute_info = (hypre_ComputeInfo*)(hypre_MAlloc((unsigned)(sizeof(hypre_ComputeInfo) * 1)));
  (compute_info)->comm_info = comm_info;
  (compute_info)->indt_boxes = indt_boxes;
  (compute_info)->dept_boxes = dept_boxes;
  (compute_info)->stride[0] = 1, (compute_info)->stride[1] = 1, (compute_info)->stride[2] = 1;
  *compute_info_ptr = compute_info;
  return ierr;
}
int hypre_ComputeInfoDestroy(hypre_ComputeInfo* compute_info) {
  int ierr = 0;
  hypre_Free((char*)compute_info), compute_info = (void*)0;
  return ierr;
}
int hypre_CreateComputeInfo(hypre_StructGrid* grid, hypre_StructStencil* stencil, hypre_ComputeInfo** compute_info_ptr) {
  int ierr = 0;
  hypre_CommInfo* comm_info;
  hypre_BoxArrayArray* indt_boxes;
  hypre_BoxArrayArray* dept_boxes;
  hypre_BoxArray* boxes;
  hypre_BoxArray* cbox_array;
  hypre_Box* cbox;
  int i;
  boxes = (grid)->boxes;
  hypre_CreateCommInfoFromStencil(grid, stencil, &(comm_info));
  indt_boxes = hypre_BoxArrayArrayCreate((boxes)->size);
  dept_boxes = hypre_BoxArrayArrayCreate((boxes)->size);
  for (i = 0; i < (boxes)->size; i++) {
    cbox_array = (dept_boxes)->box_arrays[i];
    hypre_BoxArraySetSize(cbox_array, 1);
    cbox = &((cbox_array)->boxes[0]);
    (cbox)->imin[0] = (&((boxes)->boxes[i]))->imin[0], (cbox)->imin[1] = (&((boxes)->boxes[i]))->imin[1], (cbox)->imin[2] = (&((boxes)->boxes[i]))->imin[2], (cbox)->imax[0] = (&((boxes)->boxes[i]))->imax[0], (cbox)->imax[1] = (&((boxes)->boxes[i]))->imax[1], (cbox)->imax[2] = (&((boxes)->boxes[i]))->imax[2];
  }
  hypre_ComputeInfoCreate(comm_info, indt_boxes, dept_boxes, compute_info_ptr);
  return ierr;
}
int hypre_ComputePkgCreate(hypre_ComputeInfo* compute_info, hypre_BoxArray* data_space, int num_values, hypre_StructGrid* grid, hypre_ComputePkg** compute_pkg_ptr) {
  int ierr = 0;
  hypre_ComputePkg* compute_pkg;
  hypre_CommPkg* comm_pkg;
  compute_pkg = (hypre_ComputePkg*)(hypre_CAlloc((unsigned)1, (unsigned)(sizeof(hypre_ComputePkg))));
  hypre_CommPkgCreate((compute_info)->comm_info, data_space, data_space, num_values, (grid)->comm, &(comm_pkg));
  (compute_pkg)->comm_pkg = comm_pkg;
  (compute_pkg)->indt_boxes = (compute_info)->indt_boxes;
  (compute_pkg)->dept_boxes = (compute_info)->dept_boxes;
  (compute_pkg)->stride[0] = (compute_info)->stride[0], (compute_pkg)->stride[1] = (compute_info)->stride[1], (compute_pkg)->stride[2] = (compute_info)->stride[2];
  hypre_StructGridRef(grid, &((compute_pkg)->grid));
  (compute_pkg)->data_space = data_space;
  (compute_pkg)->num_values = num_values;
  hypre_ComputeInfoDestroy(compute_info);
  *compute_pkg_ptr = compute_pkg;
  return ierr;
}
int hypre_ComputePkgDestroy(hypre_ComputePkg* compute_pkg) {
  int ierr = 0;
  if (compute_pkg) {
    hypre_CommPkgDestroy((compute_pkg)->comm_pkg);
    hypre_BoxArrayArrayDestroy((compute_pkg)->indt_boxes);
    hypre_BoxArrayArrayDestroy((compute_pkg)->dept_boxes);
    hypre_StructGridDestroy((compute_pkg)->grid);
    hypre_Free((char*)compute_pkg), compute_pkg = (void*)0;
  }
  return ierr;
}
int hypre_InitializeIndtComputations(hypre_ComputePkg* compute_pkg, double* data, hypre_CommHandle** comm_handle_ptr) {
  int ierr = 0;
  hypre_CommPkg* comm_pkg = (compute_pkg)->comm_pkg;
  ierr = hypre_InitializeCommunication(comm_pkg, data, data, comm_handle_ptr);
  return ierr;
}
int hypre_FinalizeIndtComputations(hypre_CommHandle* comm_handle) {
  int ierr = 0;
  ierr = hypre_FinalizeCommunication(comm_handle);
  return ierr;
}
//================= struct_communication.c =================
int hypre_CommPkgCreate(hypre_CommInfo* comm_info, hypre_BoxArray* send_data_space, hypre_BoxArray* recv_data_space, int num_values, MPI_Comm comm, hypre_CommPkg** comm_pkg_ptr) {
  int ierr = 0;
  hypre_BoxArrayArray* send_boxes;
  hypre_BoxArrayArray* recv_boxes;
  hypre_IndexRef send_stride;
  hypre_IndexRef recv_stride;
  int** send_processes;
  int** recv_processes;
  int** send_rboxnums;
  hypre_BoxArrayArray* send_rboxes;
  hypre_CommPkg* comm_pkg;
  hypre_CommType* comm_types;
  hypre_CommType* comm_type;
  hypre_CommEntryType* ct_entries;
  int* ct_loc_boxnums;
  int* ct_rem_boxnums;
  hypre_Box* ct_loc_boxes;
  hypre_Box* ct_rem_boxes;
  int* p_comm_types;
  int num_comms;
  int num_entries;
  int comm_bufsize;
  hypre_BoxArray* box_array;
  hypre_Box* box;
  hypre_BoxArray* rbox_array;
  hypre_Box* rbox;
  hypre_Box* data_box;
  int* data_offsets;
  int data_offset;
  int i;
  int j;
  int k;
  int p;
  int m;
  int size;
  int num_procs;
  int my_proc;
  send_boxes = (comm_info)->send_boxes;
  recv_boxes = (comm_info)->recv_boxes;
  send_stride = (comm_info)->send_stride;
  recv_stride = (comm_info)->recv_stride;
  send_processes = (comm_info)->send_processes;
  recv_processes = (comm_info)->recv_processes;
  send_rboxnums = (comm_info)->send_rboxnums;
  send_rboxes = (comm_info)->send_rboxes;
  MPI_Comm_size(comm, &(num_procs));
  MPI_Comm_rank(comm, &(my_proc));
  comm_pkg = (hypre_CommPkg*)(hypre_CAlloc((unsigned)1, (unsigned)(sizeof(hypre_CommPkg))));
  (comm_pkg)->comm = comm;
  (comm_pkg)->first_send = 1;
  (comm_pkg)->first_recv = 1;
  (comm_pkg)->num_values = num_values;
  (comm_pkg)->send_stride[0] = send_stride[0], (comm_pkg)->send_stride[1] = send_stride[1], (comm_pkg)->send_stride[2] = send_stride[2];
  (comm_pkg)->recv_stride[0] = recv_stride[0], (comm_pkg)->recv_stride[1] = recv_stride[1], (comm_pkg)->recv_stride[2] = recv_stride[2];
  p_comm_types = (int*)(hypre_CAlloc((unsigned)num_procs, (unsigned)(sizeof(int))));
  data_offsets = (int*)(hypre_MAlloc((unsigned)(sizeof(int) * (send_data_space)->size)));
  data_offset = 0;
  for (i = 0; i < (send_data_space)->size; i++) {
    data_offsets[i] = data_offset;
    data_box = &((send_data_space)->boxes[i]);
    data_offset += (((0 < ((((data_box)->imax[0]) - ((data_box)->imin[0])) + 1) ? (((data_box)->imax[0]) - ((data_box)->imin[0])) + 1 : 0) * (0 < ((((data_box)->imax[1]) - ((data_box)->imin[1])) + 1) ? (((data_box)->imax[1]) - ((data_box)->imin[1])) + 1 : 0)) * (0 < ((((data_box)->imax[2]) - ((data_box)->imin[2])) + 1) ? (((data_box)->imax[2]) - ((data_box)->imin[2])) + 1 : 0)) * num_values;
  }
  num_comms = 0;
  num_entries = 0;
  for (i = 0; i < (send_boxes)->size; i++) {
    box_array = (send_boxes)->box_arrays[i];
    for (j = 0; j < (box_array)->size; j++) {
      box = &((box_array)->boxes[j]);
      p = send_processes[i][j];
      if ((((0 < ((((box)->imax[0]) - ((box)->imin[0])) + 1) ? (((box)->imax[0]) - ((box)->imin[0])) + 1 : 0) * (0 < ((((box)->imax[1]) - ((box)->imin[1])) + 1) ? (((box)->imax[1]) - ((box)->imin[1])) + 1 : 0)) * (0 < ((((box)->imax[2]) - ((box)->imin[2])) + 1) ? (((box)->imax[2]) - ((box)->imin[2])) + 1 : 0)) != 0) {
        p_comm_types[p]--;
        num_entries++;
        if (((p_comm_types[p]) == (-1)) && (p != my_proc)) {
          num_comms++;
        }
      }
    }
  }
  comm_types = (hypre_CommType*)(hypre_CAlloc((unsigned)(num_comms + 1), (unsigned)(sizeof(hypre_CommType))));
  ct_entries = (hypre_CommEntryType*)(hypre_MAlloc((unsigned)(sizeof(hypre_CommEntryType) * num_entries)));
  ct_loc_boxnums = (int*)(hypre_MAlloc((unsigned)(sizeof(int) * num_entries)));
  ct_rem_boxnums = (int*)(hypre_MAlloc((unsigned)(sizeof(int) * num_entries)));
  ct_loc_boxes = (hypre_Box*)(hypre_MAlloc((unsigned)(sizeof(hypre_Box) * num_entries)));
  ct_rem_boxes = (hypre_Box*)(hypre_MAlloc((unsigned)(sizeof(hypre_Box) * num_entries)));
  comm_type = &(comm_types[0]);
  k = -(p_comm_types[my_proc]);
  p_comm_types[my_proc] = 0;
  (comm_type)->proc = my_proc;
  (comm_type)->num_entries = 0;
  (comm_type)->entries = ct_entries;
  (comm_type)->loc_boxnums = ct_loc_boxnums;
  (comm_type)->rem_boxnums = ct_rem_boxnums;
  (comm_type)->loc_boxes = ct_loc_boxes;
  (comm_type)->rem_boxes = ct_rem_boxes;
  ct_entries += k;
  ct_loc_boxnums += k;
  ct_rem_boxnums += k;
  ct_loc_boxes += k;
  ct_rem_boxes += k;
  m = 1;
  comm_bufsize = 0;
  for (i = 0; i < (send_boxes)->size; i++) {
    box_array = (send_boxes)->box_arrays[i];
    rbox_array = (send_rboxes)->box_arrays[i];
    for (j = 0; j < (box_array)->size; j++) {
      box = &((box_array)->boxes[j]);
      rbox = &((rbox_array)->boxes[j]);
      p = send_processes[i][j];
      if ((((0 < ((((box)->imax[0]) - ((box)->imin[0])) + 1) ? (((box)->imax[0]) - ((box)->imin[0])) + 1 : 0) * (0 < ((((box)->imax[1]) - ((box)->imin[1])) + 1) ? (((box)->imax[1]) - ((box)->imin[1])) + 1 : 0)) * (0 < ((((box)->imax[2]) - ((box)->imin[2])) + 1) ? (((box)->imax[2]) - ((box)->imin[2])) + 1 : 0)) != 0) {
        if ((p_comm_types[p]) < 0) {
          comm_type = &(comm_types[m]);
          k = -(p_comm_types[p]);
          p_comm_types[p] = m;
          (comm_type)->proc = p;
          size = (((k * sizeof(int)) + (k * sizeof(hypre_Box))) / sizeof(double)) + 1;
          (comm_type)->bufsize = size;
          comm_bufsize += size;
          (comm_type)->num_entries = 0;
          (comm_type)->entries = ct_entries;
          (comm_type)->loc_boxnums = ct_loc_boxnums;
          (comm_type)->rem_boxnums = ct_rem_boxnums;
          (comm_type)->loc_boxes = ct_loc_boxes;
          (comm_type)->rem_boxes = ct_rem_boxes;
          ct_entries += k;
          ct_loc_boxnums += k;
          ct_rem_boxnums += k;
          ct_loc_boxes += k;
          ct_rem_boxes += k;
          m++;
        }
        comm_type = &(comm_types[p_comm_types[p]]);
        k = (comm_type)->num_entries;
        hypre_BoxGetStrideVolume(box, send_stride, &(size));
        (comm_type)->bufsize += size * num_values;
        comm_bufsize += size * num_values;
        (comm_type)->loc_boxnums[k] = i;
        (comm_type)->rem_boxnums[k] = send_rboxnums[i][j];
        (&((comm_type)->loc_boxes[k]))->imin[0] = (box)->imin[0], (&((comm_type)->loc_boxes[k]))->imin[1] = (box)->imin[1], (&((comm_type)->loc_boxes[k]))->imin[2] = (box)->imin[2], (&((comm_type)->loc_boxes[k]))->imax[0] = (box)->imax[0], (&((comm_type)->loc_boxes[k]))->imax[1] = (box)->imax[1], (&((comm_type)->loc_boxes[k]))->imax[2] = (box)->imax[2];
        (&((comm_type)->rem_boxes[k]))->imin[0] = (rbox)->imin[0], (&((comm_type)->rem_boxes[k]))->imin[1] = (rbox)->imin[1], (&((comm_type)->rem_boxes[k]))->imin[2] = (rbox)->imin[2], (&((comm_type)->rem_boxes[k]))->imax[0] = (rbox)->imax[0], (&((comm_type)->rem_boxes[k]))->imax[1] = (rbox)->imax[1], (&((comm_type)->rem_boxes[k]))->imax[2] = (rbox)->imax[2];
        (comm_type)->num_entries++;
      }
    }
  }
  for (m = 0; m < (num_comms + 1); m++) {
    comm_type = &(comm_types[m]);
    hypre_CommTypeSetEntries(comm_type, (comm_type)->loc_boxnums, (comm_type)->loc_boxes, (comm_pkg)->send_stride, (comm_pkg)->num_values, send_data_space, data_offsets);
    if (m > 0) {
      (comm_type)->loc_boxnums = (void*)0;
      (comm_type)->loc_boxes = (void*)0;
    }
    p_comm_types[(comm_type)->proc] = 0;
  }
  (comm_pkg)->send_bufsize = comm_bufsize;
  (comm_pkg)->num_sends = num_comms;
  (comm_pkg)->send_types = &(comm_types[1]);
  (comm_pkg)->copy_from_type = &(comm_types[0]);
  hypre_Free((char*)data_offsets), data_offsets = (void*)0;
  comm_type = (comm_pkg)->copy_from_type;
  hypre_Free((char*)((comm_type)->loc_boxnums)), (comm_type)->loc_boxnums = (void*)0;
  hypre_Free((char*)((comm_type)->loc_boxes)), (comm_type)->loc_boxes = (void*)0;
  data_offsets = (int*)(hypre_MAlloc((unsigned)(sizeof(int) * (recv_data_space)->size)));
  data_offset = 0;
  for (i = 0; i < (recv_data_space)->size; i++) {
    data_offsets[i] = data_offset;
    data_box = &((recv_data_space)->boxes[i]);
    data_offset += (((0 < ((((data_box)->imax[0]) - ((data_box)->imin[0])) + 1) ? (((data_box)->imax[0]) - ((data_box)->imin[0])) + 1 : 0) * (0 < ((((data_box)->imax[1]) - ((data_box)->imin[1])) + 1) ? (((data_box)->imax[1]) - ((data_box)->imin[1])) + 1 : 0)) * (0 < ((((data_box)->imax[2]) - ((data_box)->imin[2])) + 1) ? (((data_box)->imax[2]) - ((data_box)->imin[2])) + 1 : 0)) * num_values;
  }
  (comm_pkg)->recv_data_offsets = data_offsets;
  (comm_pkg)->recv_data_space = hypre_BoxArrayDuplicate(recv_data_space);
  num_comms = 0;
  num_entries = 0;
  for (i = 0; i < (recv_boxes)->size; i++) {
    box_array = (recv_boxes)->box_arrays[i];
    for (j = 0; j < (box_array)->size; j++) {
      box = &((box_array)->boxes[j]);
      p = recv_processes[i][j];
      if ((((0 < ((((box)->imax[0]) - ((box)->imin[0])) + 1) ? (((box)->imax[0]) - ((box)->imin[0])) + 1 : 0) * (0 < ((((box)->imax[1]) - ((box)->imin[1])) + 1) ? (((box)->imax[1]) - ((box)->imin[1])) + 1 : 0)) * (0 < ((((box)->imax[2]) - ((box)->imin[2])) + 1) ? (((box)->imax[2]) - ((box)->imin[2])) + 1 : 0)) != 0) {
        p_comm_types[p]--;
        num_entries++;
        if (((p_comm_types[p]) == (-1)) && (p != my_proc)) {
          num_comms++;
        }
      }
    }
  }
  comm_types = (hypre_CommType*)(hypre_CAlloc((unsigned)(num_comms + 1), (unsigned)(sizeof(hypre_CommType))));
  ct_entries = (hypre_CommEntryType*)(hypre_MAlloc((unsigned)(sizeof(hypre_CommEntryType) * num_entries)));
  comm_type = &(comm_types[0]);
  k = -(p_comm_types[my_proc]);
  p_comm_types[my_proc] = 0;
  (comm_type)->proc = my_proc;
  (comm_type)->num_entries = 0;
  (comm_type)->entries = ct_entries;
  ct_entries += k;
  m = 1;
  comm_bufsize = 0;
  for (i = 0; i < (recv_boxes)->size; i++) {
    box_array = (recv_boxes)->box_arrays[i];
    for (j = 0; j < (box_array)->size; j++) {
      box = &((box_array)->boxes[j]);
      p = recv_processes[i][j];
      if ((((0 < ((((box)->imax[0]) - ((box)->imin[0])) + 1) ? (((box)->imax[0]) - ((box)->imin[0])) + 1 : 0) * (0 < ((((box)->imax[1]) - ((box)->imin[1])) + 1) ? (((box)->imax[1]) - ((box)->imin[1])) + 1 : 0)) * (0 < ((((box)->imax[2]) - ((box)->imin[2])) + 1) ? (((box)->imax[2]) - ((box)->imin[2])) + 1 : 0)) != 0) {
        if ((p_comm_types[p]) < 0) {
          comm_type = &(comm_types[m]);
          k = -(p_comm_types[p]);
          p_comm_types[p] = m;
          (comm_type)->proc = p;
          size = (((k * sizeof(int)) + (k * sizeof(hypre_Box))) / sizeof(double)) + 1;
          (comm_type)->bufsize = size;
          comm_bufsize += size;
          (comm_type)->num_entries = 0;
          (comm_type)->entries = ct_entries;
          ct_entries += k;
          m++;
        }
        comm_type = &(comm_types[p_comm_types[p]]);
        hypre_BoxGetStrideVolume(box, recv_stride, &(size));
        (comm_type)->bufsize += size * num_values;
        comm_bufsize += size * num_values;
        (comm_type)->num_entries++;
      }
    }
  }
  comm_type = (comm_pkg)->copy_from_type;
  hypre_CommTypeSetEntries(&(comm_types[0]), (comm_type)->rem_boxnums, (comm_type)->rem_boxes, (comm_pkg)->recv_stride, (comm_pkg)->num_values, (comm_pkg)->recv_data_space, (comm_pkg)->recv_data_offsets);
  (comm_pkg)->recv_bufsize = comm_bufsize;
  (comm_pkg)->num_recvs = num_comms;
  (comm_pkg)->recv_types = &(comm_types[1]);
  (comm_pkg)->copy_to_type = &(comm_types[0]);
  hypre_CommInfoDestroy(comm_info);
  hypre_Free((char*)p_comm_types), p_comm_types = (void*)0;
  *comm_pkg_ptr = comm_pkg;
  return ierr;
}
int hypre_CommTypeSetEntries(hypre_CommType* comm_type, int* boxnums, hypre_Box* boxes, hypre_Index stride, int num_values, hypre_BoxArray* data_space, int* data_offsets) {
  int ierr = 0;
  int num_entries = (comm_type)->num_entries;
  hypre_CommEntryType* entries = (comm_type)->entries;
  hypre_Box* box;
  hypre_Box* data_box;
  int i;
  int j;
  for (j = 0; j < num_entries; j++) {
    i = boxnums[j];
    box = &(boxes[j]);
    data_box = &((data_space)->boxes[i]);
    hypre_CommTypeSetEntry(box, stride, data_box, num_values, data_offsets[i], &(entries[j]));
  }
  return ierr;
}
int hypre_CommTypeSetEntry(hypre_Box* box, hypre_Index stride, hypre_Box* data_box, int num_values, int data_box_offset, hypre_CommEntryType* comm_entry) {
  int ierr = 0;
  int* length_array;
  int* stride_array;
  hypre_Index size;
  int i;
  int j;
  int dim;
  (comm_entry)->offset = data_box_offset + ((((box)->imin[0]) - ((data_box)->imin[0])) + (((((box)->imin[1]) - ((data_box)->imin[1])) + ((((box)->imin[2]) - ((data_box)->imin[2])) * (0 < ((((data_box)->imax[1]) - ((data_box)->imin[1])) + 1) ? (((data_box)->imax[1]) - ((data_box)->imin[1])) + 1 : 0))) * (0 < ((((data_box)->imax[0]) - ((data_box)->imin[0])) + 1) ? (((data_box)->imax[0]) - ((data_box)->imin[0])) + 1 : 0)));
  length_array = (comm_entry)->length_array;
  stride_array = (comm_entry)->stride_array;
  hypre_BoxGetStrideSize(box, stride, size);
  for (i = 0; i < 3; i++) {
    length_array[i] = size[i];
  }
  length_array[3] = num_values;
  for (i = 0; i < 3; i++) {
    stride_array[i] = stride[i];
    for (j = 0; j < i; j++) {
      (stride_array[i]) -= (0 < ((((data_box)->imax[j]) - ((data_box)->imin[j])) + 1) ? (((data_box)->imax[j]) - ((data_box)->imin[j])) + 1 : 0);
    }
  }
  stride_array[3] = ((0 < ((((data_box)->imax[0]) - ((data_box)->imin[0])) + 1) ? (((data_box)->imax[0]) - ((data_box)->imin[0])) + 1 : 0) * (0 < ((((data_box)->imax[1]) - ((data_box)->imin[1])) + 1) ? (((data_box)->imax[1]) - ((data_box)->imin[1])) + 1 : 0)) * (0 < ((((data_box)->imax[2]) - ((data_box)->imin[2])) + 1) ? (((data_box)->imax[2]) - ((data_box)->imin[2])) + 1 : 0);
  dim = 4;
  i = 0;
  while (i < dim) {
    if ((length_array[i]) == 1) {
      for (j = i; j < (dim - 1); j++) {
        length_array[j] = length_array[j + 1];
        stride_array[j] = stride_array[j + 1];
      }
      length_array[dim - 1] = 1;
      stride_array[dim - 1] = 1;
      dim--;
    }
    else {
      i++;
    }
  }
  if (!dim) {
    dim = 1;
  }
  (comm_entry)->dim = dim;
  return ierr;
}
int hypre_InitializeCommunication(hypre_CommPkg* comm_pkg, double* send_data, double* recv_data, hypre_CommHandle** comm_handle_ptr) {
  int ierr = 0;
  hypre_CommHandle* comm_handle;
  int num_sends = (comm_pkg)->num_sends;
  int num_recvs = (comm_pkg)->num_recvs;
  MPI_Comm comm = (comm_pkg)->comm;
  int num_requests;
  MPI_Request* requests;
  MPI_Status* status;
  double** send_buffers;
  double** recv_buffers;
  hypre_CommType* comm_type;
  hypre_CommEntryType* comm_entry;
  int num_entries;
  int* length_array;
  int length;
  int* stride_array;
  int stride;
  double* dptr;
  double* iptr;
  double* jptr;
  double* kptr;
  double* lptr;
  int* qptr;
  int i;
  int j;
  int ii;
  int jj;
  int kk;
  int ll;
  int size;
  num_requests = num_sends + num_recvs;
  requests = (MPI_Request*)(hypre_CAlloc((unsigned)num_requests, (unsigned)(sizeof(MPI_Request))));
  status = (MPI_Status*)(hypre_CAlloc((unsigned)num_requests, (unsigned)(sizeof(MPI_Status))));
  send_buffers = (double**)(hypre_MAlloc((unsigned)(sizeof(double*) * num_sends)));
  if (num_sends > 0) {
    size = (comm_pkg)->send_bufsize;
    send_buffers[0] = (double*)(hypre_MAlloc((unsigned)(sizeof(double) * size)));
    for (i = 1; i < num_sends; i++) {
      comm_type = &((comm_pkg)->send_types[i - 1]);
      size = (comm_type)->bufsize;
      send_buffers[i] = (send_buffers[i - 1]) + size;
    }
  }
  recv_buffers = (double**)(hypre_MAlloc((unsigned)(sizeof(double*) * num_recvs)));
  if (num_recvs > 0) {
    size = (comm_pkg)->recv_bufsize;
    recv_buffers[0] = (double*)(hypre_MAlloc((unsigned)(sizeof(double) * size)));
    for (i = 1; i < num_recvs; i++) {
      comm_type = &((comm_pkg)->recv_types[i - 1]);
      size = (comm_type)->bufsize;
      recv_buffers[i] = (recv_buffers[i - 1]) + size;
    }
  }
  for (i = 0; i < num_sends; i++) {
    comm_type = &((comm_pkg)->send_types[i]);
    num_entries = (comm_type)->num_entries;
    dptr = (double*)(send_buffers[i]);
    if ((comm_pkg)->first_send) {
      qptr = (int*)(send_buffers[i]);
      memcpy(qptr, (comm_type)->rem_boxnums, num_entries * sizeof(int));
      qptr += num_entries;
      memcpy(qptr, (comm_type)->rem_boxes, num_entries * sizeof(hypre_Box));
      (comm_type)->rem_boxnums = (void*)0;
      (comm_type)->rem_boxes = (void*)0;
      dptr += (((num_entries * sizeof(int)) + (num_entries * sizeof(hypre_Box))) / sizeof(double)) + 1;
    }
    for (j = 0; j < num_entries; j++) {
      comm_entry = &((comm_type)->entries[j]);
      length_array = (comm_entry)->length_array;
      stride_array = (comm_entry)->stride_array;
      lptr = send_data + (comm_entry)->offset;
      for (ll = 0; ll < (length_array[3]); ll++) {
        kptr = lptr;
        for (kk = 0; kk < (length_array[2]); kk++) {
          jptr = kptr;
          for (jj = 0; jj < (length_array[1]); jj++) {
            if ((stride_array[0]) == 1) {
              memcpy(dptr, jptr, (length_array[0]) * sizeof(double));
            }
            else {
              iptr = jptr;
              length = length_array[0];
              stride = stride_array[0];
              for (ii = 0; ii < length; ii++) {
                dptr[ii] = *iptr;
                iptr += stride;
              }
            }
            dptr += length_array[0];
            jptr += stride_array[1];
          }
          kptr += stride_array[2];
        }
        lptr += stride_array[3];
      }
    }
  }
  j = 0;
  for (i = 0; i < num_recvs; i++) {
    comm_type = &((comm_pkg)->recv_types[i]);
    MPI_Irecv(recv_buffers[i], (comm_type)->bufsize * sizeof(double), MPI_BYTE, (comm_type)->proc, 0, comm, &(requests[j++]));
    if ((comm_pkg)->first_recv) {
      size = ((((comm_type)->num_entries * sizeof(int)) + ((comm_type)->num_entries * sizeof(hypre_Box))) / sizeof(double)) + 1;
      (comm_type)->bufsize -= size;
      (comm_pkg)->recv_bufsize -= size;
    }
  }
  for (i = 0; i < num_sends; i++) {
    comm_type = &((comm_pkg)->send_types[i]);
    MPI_Isend(send_buffers[i], (comm_type)->bufsize * sizeof(double), MPI_BYTE, (comm_type)->proc, 0, comm, &(requests[j++]));
    if ((comm_pkg)->first_send) {
      size = ((((comm_type)->num_entries * sizeof(int)) + ((comm_type)->num_entries * sizeof(hypre_Box))) / sizeof(double)) + 1;
      (comm_type)->bufsize -= size;
      (comm_pkg)->send_bufsize -= size;
    }
  }
  hypre_ExchangeLocalData(comm_pkg, send_data, recv_data);
  if ((comm_pkg)->first_send) {
    comm_type = (comm_pkg)->copy_from_type;
    hypre_Free((char*)((comm_type)->rem_boxnums)), (comm_type)->rem_boxnums = (void*)0;
    hypre_Free((char*)((comm_type)->rem_boxes)), (comm_type)->rem_boxes = (void*)0;
    (comm_pkg)->first_send = 0;
  }
  comm_handle = (hypre_CommHandle*)(hypre_MAlloc((unsigned)(sizeof(hypre_CommHandle) * 1)));
  (comm_handle)->comm_pkg = comm_pkg;
  (comm_handle)->send_data = send_data;
  (comm_handle)->recv_data = recv_data;
  (comm_handle)->num_requests = num_requests;
  (comm_handle)->requests = requests;
  (comm_handle)->status = status;
  (comm_handle)->send_buffers = send_buffers;
  (comm_handle)->recv_buffers = recv_buffers;
  *comm_handle_ptr = comm_handle;
  return ierr;
}
int hypre_FinalizeCommunication(hypre_CommHandle* comm_handle) {
  int ierr = 0;
  hypre_CommPkg* comm_pkg = (comm_handle)->comm_pkg;
  double** send_buffers = (comm_handle)->send_buffers;
  double** recv_buffers = (comm_handle)->recv_buffers;
  int num_sends = (comm_pkg)->num_sends;
  int num_recvs = (comm_pkg)->num_recvs;
  hypre_CommType* comm_type;
  hypre_CommEntryType* comm_entry;
  int num_entries;
  int* length_array;
  int length;
  int* stride_array;
  int stride;
  double* iptr;
  double* jptr;
  double* kptr;
  double* lptr;
  double* dptr;
  int* qptr;
  int* boxnums;
  hypre_Box* boxes;
  int i;
  int j;
  int ii;
  int jj;
  int kk;
  int ll;
  if ((comm_handle)->num_requests) {
    MPI_Waitall((comm_handle)->num_requests, (comm_handle)->requests, (comm_handle)->status);
  }
  for (i = 0; i < num_recvs; i++) {
    comm_type = &((comm_pkg)->recv_types[i]);
    num_entries = (comm_type)->num_entries;
    dptr = (double*)(recv_buffers[i]);
    if ((comm_pkg)->first_recv) {
      qptr = (int*)(recv_buffers[i]);
      boxnums = (int*)qptr;
      qptr += num_entries;
      boxes = (hypre_Box*)qptr;
      hypre_CommTypeSetEntries(comm_type, boxnums, boxes, (comm_pkg)->recv_stride, (comm_pkg)->num_values, (comm_pkg)->recv_data_space, (comm_pkg)->recv_data_offsets);
      dptr += (((num_entries * sizeof(int)) + (num_entries * sizeof(hypre_Box))) / sizeof(double)) + 1;
    }
    for (j = 0; j < num_entries; j++) {
      comm_entry = &((comm_type)->entries[j]);
      length_array = (comm_entry)->length_array;
      stride_array = (comm_entry)->stride_array;
      lptr = (comm_handle)->recv_data + (comm_entry)->offset;
      for (ll = 0; ll < (length_array[3]); ll++) {
        kptr = lptr;
        for (kk = 0; kk < (length_array[2]); kk++) {
          jptr = kptr;
          for (jj = 0; jj < (length_array[1]); jj++) {
            if ((stride_array[0]) == 1) {
              memcpy(jptr, dptr, (length_array[0]) * sizeof(double));
            }
            else {
              iptr = jptr;
              length = length_array[0];
              stride = stride_array[0];
              for (ii = 0; ii < length; ii++) {
                *iptr = dptr[ii];
                iptr += stride;
              }
            }
            dptr += length_array[0];
            jptr += stride_array[1];
          }
          kptr += stride_array[2];
        }
        lptr += stride_array[3];
      }
    }
  }
  (comm_pkg)->first_recv = 0;
  hypre_Free((char*)((comm_handle)->requests)), (comm_handle)->requests = (void*)0;
  hypre_Free((char*)((comm_handle)->status)), (comm_handle)->status = (void*)0;
  if (num_sends > 0) {
    hypre_Free((char*)(send_buffers[0])), send_buffers[0] = (void*)0;
  }
  if (num_recvs > 0) {
    hypre_Free((char*)(recv_buffers[0])), recv_buffers[0] = (void*)0;
  }
  hypre_Free((char*)send_buffers), send_buffers = (void*)0;
  hypre_Free((char*)recv_buffers), recv_buffers = (void*)0;
  hypre_Free((char*)comm_handle), comm_handle = (void*)0;
  return ierr;
}
int hypre_ExchangeLocalData(hypre_CommPkg* comm_pkg, double* send_data, double* recv_data) {
  hypre_CommType* copy_from_type;
  hypre_CommType* copy_to_type;
  hypre_CommEntryType* copy_from_entry;
  hypre_CommEntryType* copy_to_entry;
  double* from_dp;
  int* from_stride_array;
  int from_i;
  double* to_dp;
  int* to_stride_array;
  int to_i;
  int* length_array;
  int i0;
  int i1;
  int i2;
  int i3;
  int i;
  int ierr = 0;
  copy_from_type = (comm_pkg)->copy_from_type;
  copy_to_type = (comm_pkg)->copy_to_type;
  for (i = 0; i < (copy_from_type)->num_entries; i++) {
    copy_from_entry = &((copy_from_type)->entries[i]);
    copy_to_entry = &((copy_to_type)->entries[i]);
    from_dp = send_data + (copy_from_entry)->offset;
    to_dp = recv_data + (copy_to_entry)->offset;
    if (to_dp != from_dp) {
      length_array = (copy_from_entry)->length_array;
      from_stride_array = (copy_from_entry)->stride_array;
      to_stride_array = (copy_to_entry)->stride_array;
      for (i3 = 0; i3 < (length_array[3]); i3++) {
        for (i2 = 0; i2 < (length_array[2]); i2++) {
          for (i1 = 0; i1 < (length_array[1]); i1++) {
            from_i = ((i3 * (from_stride_array[3])) + (i2 * (from_stride_array[2]))) + (i1 * (from_stride_array[1]));
            to_i = ((i3 * (to_stride_array[3])) + (i2 * (to_stride_array[2]))) + (i1 * (to_stride_array[1]));
            for (i0 = 0; i0 < (length_array[0]); i0++) {
              to_dp[to_i] = from_dp[from_i];
              from_i += from_stride_array[0];
              to_i += to_stride_array[0];
            }
          }
        }
      }
    }
  }
  return ierr;
}
int hypre_CommPkgDestroy(hypre_CommPkg* comm_pkg) {
  int ierr = 0;
  hypre_CommType* comm_types;
  if (comm_pkg) {
    comm_types = (comm_pkg)->copy_to_type;
    hypre_Free((char*)((comm_types)->entries)), (comm_types)->entries = (void*)0;
    hypre_Free((char*)((comm_types)->loc_boxnums)), (comm_types)->loc_boxnums = (void*)0;
    hypre_Free((char*)((comm_types)->rem_boxnums)), (comm_types)->rem_boxnums = (void*)0;
    hypre_Free((char*)((comm_types)->loc_boxes)), (comm_types)->loc_boxes = (void*)0;
    hypre_Free((char*)((comm_types)->rem_boxes)), (comm_types)->rem_boxes = (void*)0;
    hypre_Free((char*)comm_types), comm_types = (void*)0;
    comm_types = (comm_pkg)->copy_from_type;
    hypre_Free((char*)((comm_types)->entries)), (comm_types)->entries = (void*)0;
    hypre_Free((char*)((comm_types)->loc_boxnums)), (comm_types)->loc_boxnums = (void*)0;
    hypre_Free((char*)((comm_types)->rem_boxnums)), (comm_types)->rem_boxnums = (void*)0;
    hypre_Free((char*)((comm_types)->loc_boxes)), (comm_types)->loc_boxes = (void*)0;
    hypre_Free((char*)((comm_types)->rem_boxes)), (comm_types)->rem_boxes = (void*)0;
    hypre_Free((char*)comm_types), comm_types = (void*)0;
    hypre_Free((char*)((comm_pkg)->recv_data_offsets)), (comm_pkg)->recv_data_offsets = (void*)0;
    hypre_BoxArrayDestroy((comm_pkg)->recv_data_space);
    hypre_Free((char*)comm_pkg), comm_pkg = (void*)0;
  }
  return ierr;
}
//====================== struct_grid.c =====================
int hypre_StructGridCreate(MPI_Comm comm, int dim, hypre_StructGrid** grid_ptr) {
  hypre_StructGrid* grid;
  int i;
  grid = (hypre_StructGrid*)(hypre_MAlloc((unsigned)(sizeof(hypre_StructGrid) * 1)));
  (grid)->comm = comm;
  (grid)->dim = dim;
  (grid)->boxes = hypre_BoxArrayCreate(0);
  (grid)->ids = (void*)0;
  (grid)->neighbors = (void*)0;
  (grid)->max_distance = 2;
  (grid)->bounding_box = (void*)0;
  (grid)->local_size = 0;
  (grid)->global_size = 0;
  (grid)->periodic[0] = 0, (grid)->periodic[1] = 0, (grid)->periodic[2] = 0;
  (grid)->ref_count = 1;
  (grid)->ghlocal_size = 0;
  for (i = 0; i < 6; i++) {
    (grid)->num_ghost[i] = 1;
  }
  *grid_ptr = grid;
  return 0;
}
int hypre_StructGridRef(hypre_StructGrid* grid, hypre_StructGrid** grid_ref) {
  (grid)->ref_count++;
  *grid_ref = grid;
  return 0;
}
int hypre_StructGridDestroy(hypre_StructGrid* grid) {
  int ierr = 0;
  if (grid) {
    (grid)->ref_count--;
    if ((grid)->ref_count == 0) {
      hypre_BoxDestroy((grid)->bounding_box);
      hypre_BoxNeighborsDestroy((grid)->neighbors);
      hypre_Free((char*)((grid)->ids)), (grid)->ids = (void*)0;
      hypre_BoxArrayDestroy((grid)->boxes);
      hypre_Free((char*)grid), grid = (void*)0;
    }
  }
  return ierr;
}
int hypre_StructGridSetPeriodic(hypre_StructGrid* grid, hypre_Index periodic) {
  int ierr = 0;
  (grid)->periodic[0] = periodic[0], (grid)->periodic[1] = periodic[1], (grid)->periodic[2] = periodic[2];
  return ierr;
}
int hypre_StructGridSetExtents(hypre_StructGrid* grid, hypre_Index ilower, hypre_Index iupper) {
  int ierr = 0;
  hypre_Box* box;
  box = hypre_BoxCreate();
  hypre_BoxSetExtents(box, ilower, iupper);
  hypre_AppendBox(box, (grid)->boxes);
  hypre_BoxDestroy(box);
  return ierr;
}
int hypre_StructGridSetBoxes(hypre_StructGrid* grid, hypre_BoxArray* boxes) {
  int ierr = 0;
  hypre_Free((char*)((grid)->boxes)), (grid)->boxes = (void*)0;
  (grid)->boxes = boxes;
  return ierr;
}
int hypre_StructGridAssemble(hypre_StructGrid* grid) {
  int ierr = 0;
  MPI_Comm comm = (grid)->comm;
  int dim = (grid)->dim;
  hypre_BoxArray* boxes = (grid)->boxes;
  int* ids;
  hypre_BoxNeighbors* neighbors = (grid)->neighbors;
  int max_distance = (grid)->max_distance;
  hypre_Box* bounding_box = (grid)->bounding_box;
  hypre_IndexRef periodic = (grid)->periodic;
  hypre_Box* box;
  hypre_BoxArray* all_boxes;
  int* all_procs;
  int* all_ids;
  int first_local;
  int num_local;
  int size;
  int prune;
  int i;
  int d;
  int idmin;
  int idmax;
  int* numghost;
  int ghostsize;
  hypre_Box* ghostbox;
  prune = 1;
  if (neighbors == (void*)0) {
    hypre_GatherAllBoxes(comm, boxes, &(all_boxes), &(all_procs), &(first_local));
    bounding_box = hypre_BoxCreate();
    for (d = 0; d < dim; d++) {
      idmin = (&((all_boxes)->boxes[0]))->imin[d];
      idmax = (&((all_boxes)->boxes[0]))->imax[d];
      for (i = 0; i < (all_boxes)->size; i++) {
        box = &((all_boxes)->boxes[i]);
        idmin = idmin < ((box)->imin[d]) ? idmin : (box)->imin[d];
        idmax = idmax < ((box)->imax[d]) ? (box)->imax[d] : idmax;
      }
      (bounding_box)->imin[d] = idmin;
      (bounding_box)->imax[d] = idmax;
    }
    for (d = dim; d < 3; d++) {
      (bounding_box)->imin[d] = 0;
      (bounding_box)->imax[d] = 0;
    }
    (grid)->bounding_box = bounding_box;
    size = 0;
    for (i = 0; i < (all_boxes)->size; i++) {
      box = &((all_boxes)->boxes[i]);
      size += ((0 < ((((box)->imax[0]) - ((box)->imin[0])) + 1) ? (((box)->imax[0]) - ((box)->imin[0])) + 1 : 0) * (0 < ((((box)->imax[1]) - ((box)->imin[1])) + 1) ? (((box)->imax[1]) - ((box)->imin[1])) + 1 : 0)) * (0 < ((((box)->imax[2]) - ((box)->imin[2])) + 1) ? (((box)->imax[2]) - ((box)->imin[2])) + 1 : 0);
    }
    (grid)->global_size = size;
  }
  if (neighbors == (void*)0) {
    all_ids = (int*)(hypre_MAlloc((unsigned)(sizeof(int) * (all_boxes)->size)));
    for (i = 0; i < (all_boxes)->size; i++) {
      all_ids[i] = i;
    }
    num_local = (boxes)->size;
    hypre_BoxNeighborsCreate(all_boxes, all_procs, all_ids, first_local, num_local, &(neighbors));
    (grid)->neighbors = neighbors;
    ids = (int*)(hypre_MAlloc((unsigned)(sizeof(int) * (boxes)->size)));
    for (i = 0; i < (boxes)->size; i++) {
      ids[i] = all_ids[first_local + i];
    }
    (grid)->ids = ids;
    prune = 1;
  }
  hypre_BoxNeighborsAssemble(neighbors, periodic, max_distance, prune);
  size = 0;
  ghostsize = 0;
  for (i = 0; i < (boxes)->size; i++) {
    box = &((boxes)->boxes[i]);
    size += ((0 < ((((box)->imax[0]) - ((box)->imin[0])) + 1) ? (((box)->imax[0]) - ((box)->imin[0])) + 1 : 0) * (0 < ((((box)->imax[1]) - ((box)->imin[1])) + 1) ? (((box)->imax[1]) - ((box)->imin[1])) + 1 : 0)) * (0 < ((((box)->imax[2]) - ((box)->imin[2])) + 1) ? (((box)->imax[2]) - ((box)->imin[2])) + 1 : 0);
  }
  (grid)->local_size = size;
  numghost = (grid)->num_ghost;
  ghostsize = 0;
  ghostbox = hypre_BoxCreate();
  for (i = 0; i < (boxes)->size; i++) {
    box = &((boxes)->boxes[i]);
    (ghostbox)->imin[0] = (box)->imin[0], (ghostbox)->imin[1] = (box)->imin[1], (ghostbox)->imin[2] = (box)->imin[2], (ghostbox)->imax[0] = (box)->imax[0], (ghostbox)->imax[1] = (box)->imax[1], (ghostbox)->imax[2] = (box)->imax[2];
    hypre_BoxExpand(ghostbox, numghost);
    ghostsize += ((0 < ((((ghostbox)->imax[0]) - ((ghostbox)->imin[0])) + 1) ? (((ghostbox)->imax[0]) - ((ghostbox)->imin[0])) + 1 : 0) * (0 < ((((ghostbox)->imax[1]) - ((ghostbox)->imin[1])) + 1) ? (((ghostbox)->imax[1]) - ((ghostbox)->imin[1])) + 1 : 0)) * (0 < ((((ghostbox)->imax[2]) - ((ghostbox)->imin[2])) + 1) ? (((ghostbox)->imax[2]) - ((ghostbox)->imin[2])) + 1 : 0);
  }
  (grid)->ghlocal_size = ghostsize;
  hypre_BoxDestroy(ghostbox);
  return ierr;
}
int hypre_GatherAllBoxes(MPI_Comm comm, hypre_BoxArray* boxes, hypre_BoxArray** all_boxes_ptr, int** all_procs_ptr, int* first_local_ptr) {
  hypre_BoxArray* all_boxes;
  int* all_procs;
  int first_local;
  int all_boxes_size;
  hypre_Box* box;
  hypre_Index imin;
  hypre_Index imax;
  int num_all_procs;
  int my_rank;
  int* sendbuf;
  int sendcount;
  int* recvbuf;
  int* recvcounts;
  int* displs;
  int recvbuf_size;
  int i;
  int p;
  int b;
  int d;
  int ierr = 0;
  MPI_Comm_size(comm, &(num_all_procs));
  MPI_Comm_rank(comm, &(my_rank));
  sendcount = 7 * (boxes)->size;
  recvcounts = (int*)(hypre_MAlloc((unsigned)(sizeof(int) * num_all_procs)));
  displs = (int*)(hypre_MAlloc((unsigned)(sizeof(int) * num_all_procs)));
  MPI_Allgather(&(sendcount), 1, MPI_INT, recvcounts, 1, MPI_INT, comm);
  displs[0] = 0;
  recvbuf_size = recvcounts[0];
  for (p = 1; p < num_all_procs; p++) {
    displs[p] = (displs[p - 1]) + (recvcounts[p - 1]);
    recvbuf_size += recvcounts[p];
  }
  sendbuf = (int*)(hypre_MAlloc((unsigned)(sizeof(int) * sendcount)));
  recvbuf = (int*)(hypre_MAlloc((unsigned)(sizeof(int) * recvbuf_size)));
  i = 0;
  for (b = 0; b < (boxes)->size; b++) {
    sendbuf[i++] = my_rank;
    box = &((boxes)->boxes[b]);
    for (d = 0; d < 3; d++) {
      sendbuf[i++] = (box)->imin[d];
      sendbuf[i++] = (box)->imax[d];
    }
  }
  MPI_Allgatherv(sendbuf, sendcount, MPI_INT, recvbuf, recvcounts, displs, MPI_INT, comm);
  all_boxes_size = recvbuf_size / 7;
  all_boxes = hypre_BoxArrayCreate(all_boxes_size);
  all_procs = (int*)(hypre_MAlloc((unsigned)(sizeof(int) * all_boxes_size)));
  first_local = -1;
  i = 0;
  b = 0;
  box = hypre_BoxCreate();
  while (i < recvbuf_size) {
    all_procs[b] = recvbuf[i++];
    for (d = 0; d < 3; d++) {
      imin[d] = recvbuf[i++];
      imax[d] = recvbuf[i++];
    }
    hypre_BoxSetExtents(box, imin, imax);
    (&((all_boxes)->boxes[b]))->imin[0] = (box)->imin[0], (&((all_boxes)->boxes[b]))->imin[1] = (box)->imin[1], (&((all_boxes)->boxes[b]))->imin[2] = (box)->imin[2], (&((all_boxes)->boxes[b]))->imax[0] = (box)->imax[0], (&((all_boxes)->boxes[b]))->imax[1] = (box)->imax[1], (&((all_boxes)->boxes[b]))->imax[2] = (box)->imax[2];
    if ((first_local < 0) && ((all_procs[b]) == my_rank)) {
      first_local = b;
    }
    b++;
  }
  hypre_BoxDestroy(box);
  hypre_Free((char*)sendbuf), sendbuf = (void*)0;
  hypre_Free((char*)recvbuf), recvbuf = (void*)0;
  hypre_Free((char*)recvcounts), recvcounts = (void*)0;
  hypre_Free((char*)displs), displs = (void*)0;
  *all_boxes_ptr = all_boxes;
  *all_procs_ptr = all_procs;
  *first_local_ptr = first_local;
  return ierr;
}
int hypre_ComputeBoxnums(hypre_BoxArray* boxes, int* procs, int** boxnums_ptr) {
  int ierr = 0;
  int* boxnums;
  int num_boxes;
  int p;
  int b;
  int boxnum;
  num_boxes = (boxes)->size;
  boxnums = (int*)(hypre_MAlloc((unsigned)(sizeof(int) * num_boxes)));
  p = -1;
  for (b = 0; b < num_boxes; b++) {
    if ((procs[b]) != p) {
      boxnum = 0;
      p = procs[b];
    }
    boxnums[b] = boxnum;
    boxnum++;
  }
  *boxnums_ptr = boxnums;
  return ierr;
}
int hypre_StructGridPrint(FILE* file, hypre_StructGrid* grid) {
  int ierr = 0;
  hypre_BoxArray* boxes;
  hypre_Box* box;
  int i;
  fprintf(file, "%d\n", (grid)->dim);
  boxes = (grid)->boxes;
  fprintf(file, "%d\n", (boxes)->size);
  for (i = 0; i < (boxes)->size; i++) {
    box = &((boxes)->boxes[i]);
    fprintf(file, "%d:  (%d, %d, %d)  x  (%d, %d, %d)\n", i, (box)->imin[0], (box)->imin[1], (box)->imin[2], (box)->imax[0], (box)->imax[1], (box)->imax[2]);
  }
  return ierr;
}
//======================= struct_io.c ======================
int hypre_PrintBoxArrayData(FILE* file, hypre_BoxArray* box_array, hypre_BoxArray* data_space, int num_values, double* data) {
  int ierr = 0;
  hypre_Box* box;
  hypre_Box* data_box;
  int data_box_volume;
  int datai;
  hypre_Index loop_size;
  hypre_IndexRef start;
  hypre_Index stride;
  int i;
  int j;
  int loopi;
  int loopj;
  int loopk;
  stride[0] = 1, stride[1] = 1, stride[2] = 1;
  for (i = 0; i < (box_array)->size; i++) {
    box = &((box_array)->boxes[i]);
    data_box = &((data_space)->boxes[i]);
    start = (box)->imin;
    data_box_volume = ((0 < ((((data_box)->imax[0]) - ((data_box)->imin[0])) + 1) ? (((data_box)->imax[0]) - ((data_box)->imin[0])) + 1 : 0) * (0 < ((((data_box)->imax[1]) - ((data_box)->imin[1])) + 1) ? (((data_box)->imax[1]) - ((data_box)->imin[1])) + 1 : 0)) * (0 < ((((data_box)->imax[2]) - ((data_box)->imin[2])) + 1) ? (((data_box)->imax[2]) - ((data_box)->imin[2])) + 1 : 0);
    hypre_BoxGetSize(box, loop_size);
    {
      int hypre__i1start = ((start[0]) - ((data_box)->imin[0])) + ((((start[1]) - ((data_box)->imin[1])) + (((start[2]) - ((data_box)->imin[2])) * (0 < ((((data_box)->imax[1]) - ((data_box)->imin[1])) + 1) ? (((data_box)->imax[1]) - ((data_box)->imin[1])) + 1 : 0))) * (0 < ((((data_box)->imax[0]) - ((data_box)->imin[0])) + 1) ? (((data_box)->imax[0]) - ((data_box)->imin[0])) + 1 : 0));
      int hypre__sx1 = stride[0];
      int hypre__sy1 = (stride[1]) * (0 < ((((data_box)->imax[0]) - ((data_box)->imin[0])) + 1) ? (((data_box)->imax[0]) - ((data_box)->imin[0])) + 1 : 0);
      int hypre__sz1 = ((stride[2]) * (0 < ((((data_box)->imax[0]) - ((data_box)->imin[0])) + 1) ? (((data_box)->imax[0]) - ((data_box)->imin[0])) + 1 : 0)) * (0 < ((((data_box)->imax[1]) - ((data_box)->imin[1])) + 1) ? (((data_box)->imax[1]) - ((data_box)->imin[1])) + 1 : 0);
      int hypre__nx = loop_size[0];
      int hypre__ny = loop_size[1];
      int hypre__nz = loop_size[2];
      int hypre__mx = hypre__nx;
      int hypre__my = hypre__ny;
      int hypre__mz = hypre__nz;
      int hypre__dir;
      int hypre__max;
      int hypre__div;
      int hypre__mod;
      int hypre__block;
      int hypre__num_blocks;
      hypre__dir = 0;
      hypre__max = hypre__nx;
      if (hypre__ny > hypre__max) {
        hypre__dir = 1;
        hypre__max = hypre__ny;
      }
      if (hypre__nz > hypre__max) {
        hypre__dir = 2;
        hypre__max = hypre__nz;
      }
      hypre__num_blocks = 1;
      if (hypre__max < hypre__num_blocks) {
        hypre__num_blocks = hypre__max;
      }
      if (hypre__num_blocks > 0) {
        hypre__div = hypre__max / hypre__num_blocks;
        hypre__mod = hypre__max % hypre__num_blocks;
      }
      ;
      ;
      for (hypre__block = 0; hypre__block < hypre__num_blocks; hypre__block++) {
        loopi = 0;
        loopj = 0;
        loopk = 0;
        hypre__nx = hypre__mx;
        hypre__ny = hypre__my;
        hypre__nz = hypre__mz;
        if (hypre__num_blocks > 1) {
          if (hypre__dir == 0) {
            loopi = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
            hypre__nx = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
          }
          else
            if (hypre__dir == 1) {
              loopj = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
              hypre__ny = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
            }
            else
              if (hypre__dir == 2) {
                loopk = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                hypre__nz = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
              }
        }
        ;
        datai = ((hypre__i1start + (loopi * hypre__sx1)) + (loopj * hypre__sy1)) + (loopk * hypre__sz1);
        for (loopk = 0; loopk < hypre__nz; loopk++) {
          for (loopj = 0; loopj < hypre__ny; loopj++) {
            for (loopi = 0; loopi < hypre__nx; loopi++) {
              {
                for (j = 0; j < num_values; j++) {
                  fprintf(file, "%d: (%d, %d, %d; %d) %.14e\n", i, (start[0]) + loopi, (start[1]) + loopj, (start[2]) + loopk, j, data[datai + (j * data_box_volume)]);
                }
              }
              datai += hypre__sx1;
            }
            datai += hypre__sy1 - (hypre__nx * hypre__sx1);
          }
          datai += hypre__sz1 - (hypre__ny * hypre__sy1);
        }
      }
    }
    ;
    data += num_values * data_box_volume;
  }
  return ierr;
}
int hypre_PrintCCVDBoxArrayData(FILE* file, hypre_BoxArray* box_array, hypre_BoxArray* data_space, int num_values, int center_rank, int stencil_size, int* symm_elements, double* data) {
  int ierr = 0;
  hypre_Box* box;
  hypre_Box* data_box;
  int data_box_volume;
  int datai;
  hypre_Index loop_size;
  hypre_IndexRef start;
  hypre_Index stride;
  int i;
  int j;
  int loopi;
  int loopj;
  int loopk;
  stride[0] = 1, stride[1] = 1, stride[2] = 1;
  for (j = 0; j < stencil_size; ++j) {
    if (((symm_elements[j]) < 0) && (j != center_rank)) {
      fprintf(file, "*: (*, *, *; %d) %.14e\n", j, data[0]);
    }
    ++data;
  }
  for (i = 0; i < (box_array)->size; i++) {
    box = &((box_array)->boxes[i]);
    data_box = &((data_space)->boxes[i]);
    start = (box)->imin;
    data_box_volume = ((0 < ((((data_box)->imax[0]) - ((data_box)->imin[0])) + 1) ? (((data_box)->imax[0]) - ((data_box)->imin[0])) + 1 : 0) * (0 < ((((data_box)->imax[1]) - ((data_box)->imin[1])) + 1) ? (((data_box)->imax[1]) - ((data_box)->imin[1])) + 1 : 0)) * (0 < ((((data_box)->imax[2]) - ((data_box)->imin[2])) + 1) ? (((data_box)->imax[2]) - ((data_box)->imin[2])) + 1 : 0);
    hypre_BoxGetSize(box, loop_size);
    {
      int hypre__i1start = ((start[0]) - ((data_box)->imin[0])) + ((((start[1]) - ((data_box)->imin[1])) + (((start[2]) - ((data_box)->imin[2])) * (0 < ((((data_box)->imax[1]) - ((data_box)->imin[1])) + 1) ? (((data_box)->imax[1]) - ((data_box)->imin[1])) + 1 : 0))) * (0 < ((((data_box)->imax[0]) - ((data_box)->imin[0])) + 1) ? (((data_box)->imax[0]) - ((data_box)->imin[0])) + 1 : 0));
      int hypre__sx1 = stride[0];
      int hypre__sy1 = (stride[1]) * (0 < ((((data_box)->imax[0]) - ((data_box)->imin[0])) + 1) ? (((data_box)->imax[0]) - ((data_box)->imin[0])) + 1 : 0);
      int hypre__sz1 = ((stride[2]) * (0 < ((((data_box)->imax[0]) - ((data_box)->imin[0])) + 1) ? (((data_box)->imax[0]) - ((data_box)->imin[0])) + 1 : 0)) * (0 < ((((data_box)->imax[1]) - ((data_box)->imin[1])) + 1) ? (((data_box)->imax[1]) - ((data_box)->imin[1])) + 1 : 0);
      int hypre__nx = loop_size[0];
      int hypre__ny = loop_size[1];
      int hypre__nz = loop_size[2];
      int hypre__mx = hypre__nx;
      int hypre__my = hypre__ny;
      int hypre__mz = hypre__nz;
      int hypre__dir;
      int hypre__max;
      int hypre__div;
      int hypre__mod;
      int hypre__block;
      int hypre__num_blocks;
      hypre__dir = 0;
      hypre__max = hypre__nx;
      if (hypre__ny > hypre__max) {
        hypre__dir = 1;
        hypre__max = hypre__ny;
      }
      if (hypre__nz > hypre__max) {
        hypre__dir = 2;
        hypre__max = hypre__nz;
      }
      hypre__num_blocks = 1;
      if (hypre__max < hypre__num_blocks) {
        hypre__num_blocks = hypre__max;
      }
      if (hypre__num_blocks > 0) {
        hypre__div = hypre__max / hypre__num_blocks;
        hypre__mod = hypre__max % hypre__num_blocks;
      }
      ;
      ;
      for (hypre__block = 0; hypre__block < hypre__num_blocks; hypre__block++) {
        loopi = 0;
        loopj = 0;
        loopk = 0;
        hypre__nx = hypre__mx;
        hypre__ny = hypre__my;
        hypre__nz = hypre__mz;
        if (hypre__num_blocks > 1) {
          if (hypre__dir == 0) {
            loopi = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
            hypre__nx = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
          }
          else
            if (hypre__dir == 1) {
              loopj = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
              hypre__ny = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
            }
            else
              if (hypre__dir == 2) {
                loopk = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                hypre__nz = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
              }
        }
        ;
        datai = ((hypre__i1start + (loopi * hypre__sx1)) + (loopj * hypre__sy1)) + (loopk * hypre__sz1);
        for (loopk = 0; loopk < hypre__nz; loopk++) {
          for (loopj = 0; loopj < hypre__ny; loopj++) {
            for (loopi = 0; loopi < hypre__nx; loopi++) {
              {
                fprintf(file, "%d: (%d, %d, %d; %d) %.14e\n", i, (start[0]) + loopi, (start[1]) + loopj, (start[2]) + loopk, center_rank, data[datai]);
              }
              datai += hypre__sx1;
            }
            datai += hypre__sy1 - (hypre__nx * hypre__sx1);
          }
          datai += hypre__sz1 - (hypre__ny * hypre__sy1);
        }
      }
    }
    ;
    data += data_box_volume;
  }
  return ierr;
}
int hypre_PrintCCBoxArrayData(FILE* file, hypre_BoxArray* box_array, hypre_BoxArray* data_space, int num_values, double* data) {
  int ierr = 0;
  hypre_Box* box;
  int datai;
  hypre_IndexRef start;
  int i;
  int j;
  for (i = 0; i < (box_array)->size; i++) {
    box = &((box_array)->boxes[i]);
    start = (box)->imin;
    datai = 0;
    for (j = 0; j < num_values; j++) {
      fprintf(file, "*: (*, *, *; %d) %.14e\n", j, data[datai + j]);
    }
    data += num_values;
  }
  return ierr;
}
//===================== struct_matrix.c ====================
double* hypre_StructMatrixExtractPointerByIndex(hypre_StructMatrix* matrix, int b, hypre_Index index) {
  hypre_StructStencil* stencil;
  int rank;
  stencil = (matrix)->stencil;
  rank = hypre_StructStencilElementRank(stencil, index);
  if (rank >= 0)
    return (matrix)->data + ((matrix)->data_indices[b][rank]);
  else
    return (void*)0;
}
hypre_StructMatrix* hypre_StructMatrixCreate(MPI_Comm comm, hypre_StructGrid* grid, hypre_StructStencil* user_stencil) {
  hypre_StructMatrix* matrix;
  int ndim = (grid)->dim;
  int i;
  matrix = (hypre_StructMatrix*)(hypre_CAlloc((unsigned)1, (unsigned)(sizeof(hypre_StructMatrix))));
  (matrix)->comm = comm;
  hypre_StructGridRef(grid, &((matrix)->grid));
  (matrix)->user_stencil = hypre_StructStencilRef(user_stencil);
  (matrix)->data_alloced = 1;
  (matrix)->ref_count = 1;
  (matrix)->symmetric = 0;
  (matrix)->constant_coefficient = 0;
  for (i = 0; i < 6; i++) {
    (matrix)->num_ghost[i] = 0;
    (matrix)->add_num_ghost[i] = 0;
  }
  for (i = 0; i < ndim; i++) {
    (matrix)->num_ghost[2 * i] = 1;
    (matrix)->num_ghost[(2 * i) + 1] = 1;
    (matrix)->add_num_ghost[2 * i] = 1;
    (matrix)->add_num_ghost[(2 * i) + 1] = 1;
  }
  (matrix)->OffProcAdd = 0;
  return matrix;
}
hypre_StructMatrix* hypre_StructMatrixRef(hypre_StructMatrix* matrix) {
  (matrix)->ref_count++;
  return matrix;
}
int hypre_StructMatrixDestroy(hypre_StructMatrix* matrix) {
  int i;
  int ierr = 0;
  if (matrix) {
    (matrix)->ref_count--;
    if ((matrix)->ref_count == 0) {
      if ((matrix)->data_alloced) {
        hypre_Free((char*)((matrix)->data)), (matrix)->data = (void*)0;
      }
      hypre_CommPkgDestroy((matrix)->comm_pkg);
      for (i = 0; i < ((matrix)->data_space)->size; i++)
        hypre_Free((char*)((matrix)->data_indices[i])), (matrix)->data_indices[i] = (void*)0;
      hypre_Free((char*)((matrix)->data_indices)), (matrix)->data_indices = (void*)0;
      hypre_BoxArrayDestroy((matrix)->data_space);
      hypre_Free((char*)((matrix)->symm_elements)), (matrix)->symm_elements = (void*)0;
      hypre_StructStencilDestroy((matrix)->user_stencil);
      hypre_StructStencilDestroy((matrix)->stencil);
      hypre_StructGridDestroy((matrix)->grid);
      hypre_Free((char*)matrix), matrix = (void*)0;
    }
  }
  return ierr;
}
int hypre_StructMatrixInitializeShell(hypre_StructMatrix* matrix) {
  int ierr = 0;
  hypre_StructGrid* grid;
  hypre_StructStencil* user_stencil;
  hypre_StructStencil* stencil;
  hypre_Index* stencil_shape;
  int stencil_size;
  int num_values;
  int* symm_elements;
  int constant_coefficient;
  int* num_ghost;
  int  extra_ghost[] = {0, 0, 0, 0, 0, 0};
  hypre_BoxArray* data_space;
  hypre_BoxArray* boxes;
  hypre_Box* box;
  hypre_Box* data_box;
  int** data_indices;
  int data_size;
  int data_box_volume;
  int i;
  int j;
  int d;
  grid = (matrix)->grid;
  if ((matrix)->stencil == (void*)0) {
    user_stencil = (matrix)->user_stencil;
    if ((matrix)->symmetric) {
      hypre_StructStencilSymmetrize(user_stencil, &(stencil), &(symm_elements));
      num_values = ((stencil)->size + 1) / 2;
    }
    else {
      stencil = hypre_StructStencilRef(user_stencil);
      num_values = (stencil)->size;
      symm_elements = (int*)(hypre_MAlloc((unsigned)(sizeof(int) * num_values)));
      for (i = 0; i < num_values; i++) {
        symm_elements[i] = -1;
      }
    }
    (matrix)->stencil = stencil;
    (matrix)->symm_elements = symm_elements;
    (matrix)->num_values = num_values;
  }
  num_ghost = (matrix)->num_ghost;
  stencil = (matrix)->stencil;
  stencil_shape = (stencil)->shape;
  stencil_size = (stencil)->size;
  symm_elements = (matrix)->symm_elements;
  for (i = 0; i < stencil_size; i++) {
    if ((symm_elements[i]) >= 0) {
      for (d = 0; d < 3; d++) {
        extra_ghost[2 * d] = (extra_ghost[2 * d]) < (-(stencil_shape[i][d])) ? -(stencil_shape[i][d]) : extra_ghost[2 * d];
        extra_ghost[(2 * d) + 1] = (extra_ghost[(2 * d) + 1]) < (stencil_shape[i][d]) ? stencil_shape[i][d] : extra_ghost[(2 * d) + 1];
      }
    }
  }
  for (d = 0; d < 3; d++) {
    num_ghost[2 * d] += extra_ghost[2 * d];
    num_ghost[(2 * d) + 1] += extra_ghost[(2 * d) + 1];
  }
  if ((matrix)->data_space == (void*)0) {
    boxes = (grid)->boxes;
    data_space = hypre_BoxArrayCreate((boxes)->size);
    for (i = 0; i < (boxes)->size; i++) {
      box = &((boxes)->boxes[i]);
      data_box = &((data_space)->boxes[i]);
      (data_box)->imin[0] = (box)->imin[0], (data_box)->imin[1] = (box)->imin[1], (data_box)->imin[2] = (box)->imin[2], (data_box)->imax[0] = (box)->imax[0], (data_box)->imax[1] = (box)->imax[1], (data_box)->imax[2] = (box)->imax[2];
      for (d = 0; d < 3; d++) {
        ((data_box)->imin[d]) -= (num_ghost[2 * d]);
        (data_box)->imax[d] += num_ghost[(2 * d) + 1];
      }
    }
    (matrix)->data_space = data_space;
  }
  if ((matrix)->data_indices == (void*)0) {
    data_space = (matrix)->data_space;
    data_indices = (int**)(hypre_CAlloc((unsigned)((data_space)->size), (unsigned)(sizeof(int*))));
    constant_coefficient = (matrix)->constant_coefficient;
    data_size = 0;
    if (constant_coefficient == 0) {
      for (i = 0; i < (data_space)->size; i++) {
        data_box = &((data_space)->boxes[i]);
        data_box_volume = ((0 < ((((data_box)->imax[0]) - ((data_box)->imin[0])) + 1) ? (((data_box)->imax[0]) - ((data_box)->imin[0])) + 1 : 0) * (0 < ((((data_box)->imax[1]) - ((data_box)->imin[1])) + 1) ? (((data_box)->imax[1]) - ((data_box)->imin[1])) + 1 : 0)) * (0 < ((((data_box)->imax[2]) - ((data_box)->imin[2])) + 1) ? (((data_box)->imax[2]) - ((data_box)->imin[2])) + 1 : 0);
        data_indices[i] = (int*)(hypre_CAlloc((unsigned)stencil_size, (unsigned)(sizeof(int))));
        for (j = 0; j < stencil_size; j++) {
          if ((symm_elements[j]) < 0) {
            data_indices[i][j] = data_size;
            data_size += data_box_volume;
          }
        }
        for (j = 0; j < stencil_size; j++) {
          if ((symm_elements[j]) >= 0) {
            data_indices[i][j] = (data_indices[i][symm_elements[j]]) + ((stencil_shape[j][0]) + (((stencil_shape[j][1]) + ((stencil_shape[j][2]) * (0 < ((((data_box)->imax[1]) - ((data_box)->imin[1])) + 1) ? (((data_box)->imax[1]) - ((data_box)->imin[1])) + 1 : 0))) * (0 < ((((data_box)->imax[0]) - ((data_box)->imin[0])) + 1) ? (((data_box)->imax[0]) - ((data_box)->imin[0])) + 1 : 0)));
          }
        }
      }
    }
    else
      if (constant_coefficient == 1) {
        for (i = 0; i < (data_space)->size; i++) {
          data_box = &((data_space)->boxes[i]);
          data_box_volume = ((0 < ((((data_box)->imax[0]) - ((data_box)->imin[0])) + 1) ? (((data_box)->imax[0]) - ((data_box)->imin[0])) + 1 : 0) * (0 < ((((data_box)->imax[1]) - ((data_box)->imin[1])) + 1) ? (((data_box)->imax[1]) - ((data_box)->imin[1])) + 1 : 0)) * (0 < ((((data_box)->imax[2]) - ((data_box)->imin[2])) + 1) ? (((data_box)->imax[2]) - ((data_box)->imin[2])) + 1 : 0);
          data_indices[i] = (int*)(hypre_CAlloc((unsigned)stencil_size, (unsigned)(sizeof(int))));
          for (j = 0; j < stencil_size; j++) {
            if ((symm_elements[j]) < 0) {
              data_indices[i][j] = data_size;
              ++data_size;
            }
          }
          for (j = 0; j < stencil_size; j++) {
            if ((symm_elements[j]) >= 0) {
              data_indices[i][j] = data_indices[i][symm_elements[j]];
            }
          }
        }
      }
      else {
        if (!(constant_coefficient == 2)) {
          fprintf(stderr, "hypre_assert failed: %s\n", "constant_coefficient == 2");
          hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/struct_mv/struct_matrix.c", 908, 1);
        }
        ;
        data_size += stencil_size;
        for (i = 0; i < (data_space)->size; i++) {
          data_box = &((data_space)->boxes[i]);
          data_box_volume = ((0 < ((((data_box)->imax[0]) - ((data_box)->imin[0])) + 1) ? (((data_box)->imax[0]) - ((data_box)->imin[0])) + 1 : 0) * (0 < ((((data_box)->imax[1]) - ((data_box)->imin[1])) + 1) ? (((data_box)->imax[1]) - ((data_box)->imin[1])) + 1 : 0)) * (0 < ((((data_box)->imax[2]) - ((data_box)->imin[2])) + 1) ? (((data_box)->imax[2]) - ((data_box)->imin[2])) + 1 : 0);
          data_indices[i] = (int*)(hypre_CAlloc((unsigned)stencil_size, (unsigned)(sizeof(int))));
          for (j = 0; j < stencil_size; j++) {
            if ((symm_elements[j]) < 0) {
              if ((((stencil_shape[j][0]) == 0) && ((stencil_shape[j][1]) == 0)) && ((stencil_shape[j][2]) == 0)) {
                data_indices[i][j] = data_size;
                data_size += data_box_volume;
              }
              else {
                data_indices[i][j] = j;
              }
            }
          }
          for (j = 0; j < stencil_size; j++) {
            if ((symm_elements[j]) >= 0) {
              if ((((stencil_shape[j][0]) == 0) && ((stencil_shape[j][1]) == 0)) && ((stencil_shape[j][2]) == 0)) {
                data_indices[i][j] = (data_indices[i][symm_elements[j]]) + ((stencil_shape[j][0]) + (((stencil_shape[j][1]) + ((stencil_shape[j][2]) * (0 < ((((data_box)->imax[1]) - ((data_box)->imin[1])) + 1) ? (((data_box)->imax[1]) - ((data_box)->imin[1])) + 1 : 0))) * (0 < ((((data_box)->imax[0]) - ((data_box)->imin[0])) + 1) ? (((data_box)->imax[0]) - ((data_box)->imin[0])) + 1 : 0)));
              }
              else {
                data_indices[i][j] = data_indices[i][symm_elements[j]];
              }
            }
          }
        }
      }
    (matrix)->data_indices = data_indices;
    (matrix)->data_size = data_size;
  }
  (matrix)->global_size = (grid)->global_size * stencil_size;
  return ierr;
}
int hypre_StructMatrixInitializeData(hypre_StructMatrix* matrix, double* data) {
  int ierr = 0;
  hypre_BoxArray* data_boxes;
  hypre_Box* data_box;
  hypre_Index loop_size;
  hypre_Index index;
  hypre_IndexRef start;
  hypre_Index stride;
  double* datap;
  int datai;
  int constant_coefficient;
  int i;
  int loopi;
  int loopj;
  int loopk;
  (matrix)->data = data;
  (matrix)->data_alloced = 0;
  constant_coefficient = (matrix)->constant_coefficient;
  index[0] = 0, index[1] = 0, index[2] = 0;
  stride[0] = 1, stride[1] = 1, stride[2] = 1;
  data_boxes = (matrix)->data_space;
  for (i = 0; i < (data_boxes)->size; i++) {
    datap = hypre_StructMatrixExtractPointerByIndex(matrix, i, index);
    if (datap) {
      data_box = &((data_boxes)->boxes[i]);
      start = (data_box)->imin;
      if (constant_coefficient == 1) {
        datai = 0;
        datap[datai] = 1.0;
      }
      else {
        hypre_BoxGetSize(data_box, loop_size);
        {
          int hypre__i1start = ((start[0]) - ((data_box)->imin[0])) + ((((start[1]) - ((data_box)->imin[1])) + (((start[2]) - ((data_box)->imin[2])) * (0 < ((((data_box)->imax[1]) - ((data_box)->imin[1])) + 1) ? (((data_box)->imax[1]) - ((data_box)->imin[1])) + 1 : 0))) * (0 < ((((data_box)->imax[0]) - ((data_box)->imin[0])) + 1) ? (((data_box)->imax[0]) - ((data_box)->imin[0])) + 1 : 0));
          int hypre__sx1 = stride[0];
          int hypre__sy1 = (stride[1]) * (0 < ((((data_box)->imax[0]) - ((data_box)->imin[0])) + 1) ? (((data_box)->imax[0]) - ((data_box)->imin[0])) + 1 : 0);
          int hypre__sz1 = ((stride[2]) * (0 < ((((data_box)->imax[0]) - ((data_box)->imin[0])) + 1) ? (((data_box)->imax[0]) - ((data_box)->imin[0])) + 1 : 0)) * (0 < ((((data_box)->imax[1]) - ((data_box)->imin[1])) + 1) ? (((data_box)->imax[1]) - ((data_box)->imin[1])) + 1 : 0);
          int hypre__nx = loop_size[0];
          int hypre__ny = loop_size[1];
          int hypre__nz = loop_size[2];
          int hypre__mx = hypre__nx;
          int hypre__my = hypre__ny;
          int hypre__mz = hypre__nz;
          int hypre__dir;
          int hypre__max;
          int hypre__div;
          int hypre__mod;
          int hypre__block;
          int hypre__num_blocks;
          hypre__dir = 0;
          hypre__max = hypre__nx;
          if (hypre__ny > hypre__max) {
            hypre__dir = 1;
            hypre__max = hypre__ny;
          }
          if (hypre__nz > hypre__max) {
            hypre__dir = 2;
            hypre__max = hypre__nz;
          }
          hypre__num_blocks = 1;
          if (hypre__max < hypre__num_blocks) {
            hypre__num_blocks = hypre__max;
          }
          if (hypre__num_blocks > 0) {
            hypre__div = hypre__max / hypre__num_blocks;
            hypre__mod = hypre__max % hypre__num_blocks;
          }
          ;
          ;
          for (hypre__block = 0; hypre__block < hypre__num_blocks; hypre__block++) {
            loopi = 0;
            loopj = 0;
            loopk = 0;
            hypre__nx = hypre__mx;
            hypre__ny = hypre__my;
            hypre__nz = hypre__mz;
            if (hypre__num_blocks > 1) {
              if (hypre__dir == 0) {
                loopi = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                hypre__nx = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
              }
              else
                if (hypre__dir == 1) {
                  loopj = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                  hypre__ny = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                }
                else
                  if (hypre__dir == 2) {
                    loopk = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                    hypre__nz = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                  }
            }
            ;
            datai = ((hypre__i1start + (loopi * hypre__sx1)) + (loopj * hypre__sy1)) + (loopk * hypre__sz1);
            for (loopk = 0; loopk < hypre__nz; loopk++) {
              for (loopj = 0; loopj < hypre__ny; loopj++) {
                for (loopi = 0; loopi < hypre__nx; loopi++) {
                  {
                    datap[datai] = 1.0;
                  }
                  datai += hypre__sx1;
                }
                datai += hypre__sy1 - (hypre__nx * hypre__sx1);
              }
              datai += hypre__sz1 - (hypre__ny * hypre__sy1);
            }
          }
        }
        ;
      }
    }
  }
  return ierr;
}
int hypre_StructMatrixInitialize(hypre_StructMatrix* matrix) {
  int ierr = 0;
  double* data;
  ierr = hypre_StructMatrixInitializeShell(matrix);
  data = (matrix)->data;
  data = (double*)(hypre_CAlloc((unsigned)((matrix)->data_size), (unsigned)(sizeof(double))));
  hypre_StructMatrixInitializeData(matrix, data);
  (matrix)->data_alloced = 1;
  return ierr;
}
int hypre_StructMatrixSetValues(hypre_StructMatrix* matrix, hypre_Index grid_index, int num_stencil_indices, int* stencil_indices, double* values, int action) {
  int ierr = 0;
  MPI_Comm comm = (matrix)->comm;
  hypre_BoxArray* boxes;
  hypre_Box* box;
  hypre_Index center_index;
  hypre_StructStencil* stencil;
  int center_rank;
  int constant_coefficient;
  double* matp;
  int i;
  int s;
  int found;
  int true = 1;
  int false = 0;
  int nprocs;
  MPI_Comm_size(comm, &(nprocs));
  boxes = ((matrix)->grid)->boxes;
  constant_coefficient = (matrix)->constant_coefficient;
  found = true;
  for (i = 0; i < (boxes)->size; i++) {
    box = &((boxes)->boxes[i]);
    if (constant_coefficient == 1) {
      ++ierr;
      if (action > 0) {
        for (s = 0; s < num_stencil_indices; s++) {
          matp = (matrix)->data + ((matrix)->data_indices[i][stencil_indices[s]]);
          *matp += values[s];
        }
      }
      else
        if (action > (-1)) {
          for (s = 0; s < num_stencil_indices; s++) {
            matp = (matrix)->data + ((matrix)->data_indices[i][stencil_indices[s]]);
            *matp = values[s];
          }
        }
        else {
          for (s = 0; s < num_stencil_indices; s++) {
            matp = (matrix)->data + ((matrix)->data_indices[i][stencil_indices[s]]);
            values[s] = *matp;
          }
        }
    }
    else
      if (constant_coefficient == 2) {
        center_index[0] = 0, center_index[1] = 0, center_index[2] = 0;
        stencil = (matrix)->stencil;
        center_rank = hypre_StructStencilElementRank(stencil, center_index);
        found = false;
        if (action > 0) {
          for (s = 0; s < num_stencil_indices; s++) {
            if ((stencil_indices[s]) == center_rank) {
              if (((((((grid_index[0]) >= ((box)->imin[0])) && ((grid_index[0]) <= ((box)->imax[0]))) && ((grid_index[1]) >= ((box)->imin[1]))) && ((grid_index[1]) <= ((box)->imax[1]))) && ((grid_index[2]) >= ((box)->imin[2]))) && ((grid_index[2]) <= ((box)->imax[2]))) {
                matp = ((matrix)->data + ((matrix)->data_indices[i][stencil_indices[s]])) + (((grid_index[0]) - ((&(((matrix)->data_space)->boxes[i]))->imin[0])) + ((((grid_index[1]) - ((&(((matrix)->data_space)->boxes[i]))->imin[1])) + (((grid_index[2]) - ((&(((matrix)->data_space)->boxes[i]))->imin[2])) * (0 < ((((&(((matrix)->data_space)->boxes[i]))->imax[1]) - ((&(((matrix)->data_space)->boxes[i]))->imin[1])) + 1) ? (((&(((matrix)->data_space)->boxes[i]))->imax[1]) - ((&(((matrix)->data_space)->boxes[i]))->imin[1])) + 1 : 0))) * (0 < ((((&(((matrix)->data_space)->boxes[i]))->imax[0]) - ((&(((matrix)->data_space)->boxes[i]))->imin[0])) + 1) ? (((&(((matrix)->data_space)->boxes[i]))->imax[0]) - ((&(((matrix)->data_space)->boxes[i]))->imin[0])) + 1 : 0)));
                *matp += values[s];
                found = true;
              }
            }
            else {
              ++ierr;
              matp = (matrix)->data + ((matrix)->data_indices[i][stencil_indices[s]]);
              *matp += values[s];
              found = true;
            }
          }
        }
        else
          if (action > (-1)) {
            for (s = 0; s < num_stencil_indices; s++) {
              if ((stencil_indices[s]) == center_rank) {
                if (((((((grid_index[0]) >= ((box)->imin[0])) && ((grid_index[0]) <= ((box)->imax[0]))) && ((grid_index[1]) >= ((box)->imin[1]))) && ((grid_index[1]) <= ((box)->imax[1]))) && ((grid_index[2]) >= ((box)->imin[2]))) && ((grid_index[2]) <= ((box)->imax[2]))) {
                  matp = ((matrix)->data + ((matrix)->data_indices[i][stencil_indices[s]])) + (((grid_index[0]) - ((&(((matrix)->data_space)->boxes[i]))->imin[0])) + ((((grid_index[1]) - ((&(((matrix)->data_space)->boxes[i]))->imin[1])) + (((grid_index[2]) - ((&(((matrix)->data_space)->boxes[i]))->imin[2])) * (0 < ((((&(((matrix)->data_space)->boxes[i]))->imax[1]) - ((&(((matrix)->data_space)->boxes[i]))->imin[1])) + 1) ? (((&(((matrix)->data_space)->boxes[i]))->imax[1]) - ((&(((matrix)->data_space)->boxes[i]))->imin[1])) + 1 : 0))) * (0 < ((((&(((matrix)->data_space)->boxes[i]))->imax[0]) - ((&(((matrix)->data_space)->boxes[i]))->imin[0])) + 1) ? (((&(((matrix)->data_space)->boxes[i]))->imax[0]) - ((&(((matrix)->data_space)->boxes[i]))->imin[0])) + 1 : 0)));
                  *matp = values[s];
                  found = true;
                }
              }
              else {
                ++ierr;
                matp = (matrix)->data + ((matrix)->data_indices[i][stencil_indices[s]]);
                *matp += values[s];
                found = true;
              }
            }
          }
          else {
            found = true;
            for (s = 0; s < num_stencil_indices; s++) {
              if ((stencil_indices[s]) == center_rank) {
                if (((((((grid_index[0]) >= ((box)->imin[0])) && ((grid_index[0]) <= ((box)->imax[0]))) && ((grid_index[1]) >= ((box)->imin[1]))) && ((grid_index[1]) <= ((box)->imax[1]))) && ((grid_index[2]) >= ((box)->imin[2]))) && ((grid_index[2]) <= ((box)->imax[2]))) {
                  matp = ((matrix)->data + ((matrix)->data_indices[i][stencil_indices[s]])) + (((grid_index[0]) - ((&(((matrix)->data_space)->boxes[i]))->imin[0])) + ((((grid_index[1]) - ((&(((matrix)->data_space)->boxes[i]))->imin[1])) + (((grid_index[2]) - ((&(((matrix)->data_space)->boxes[i]))->imin[2])) * (0 < ((((&(((matrix)->data_space)->boxes[i]))->imax[1]) - ((&(((matrix)->data_space)->boxes[i]))->imin[1])) + 1) ? (((&(((matrix)->data_space)->boxes[i]))->imax[1]) - ((&(((matrix)->data_space)->boxes[i]))->imin[1])) + 1 : 0))) * (0 < ((((&(((matrix)->data_space)->boxes[i]))->imax[0]) - ((&(((matrix)->data_space)->boxes[i]))->imin[0])) + 1) ? (((&(((matrix)->data_space)->boxes[i]))->imax[0]) - ((&(((matrix)->data_space)->boxes[i]))->imin[0])) + 1 : 0)));
                  *matp += values[s];
                }
              }
              else {
                ++ierr;
                matp = (matrix)->data + ((matrix)->data_indices[i][stencil_indices[s]]);
                values[s] = *matp;
              }
            }
          }
      }
      else {
        found = false;
        if (((((((grid_index[0]) >= ((box)->imin[0])) && ((grid_index[0]) <= ((box)->imax[0]))) && ((grid_index[1]) >= ((box)->imin[1]))) && ((grid_index[1]) <= ((box)->imax[1]))) && ((grid_index[2]) >= ((box)->imin[2]))) && ((grid_index[2]) <= ((box)->imax[2]))) {
          if (action > 0) {
            for (s = 0; s < num_stencil_indices; s++) {
              matp = ((matrix)->data + ((matrix)->data_indices[i][stencil_indices[s]])) + (((grid_index[0]) - ((&(((matrix)->data_space)->boxes[i]))->imin[0])) + ((((grid_index[1]) - ((&(((matrix)->data_space)->boxes[i]))->imin[1])) + (((grid_index[2]) - ((&(((matrix)->data_space)->boxes[i]))->imin[2])) * (0 < ((((&(((matrix)->data_space)->boxes[i]))->imax[1]) - ((&(((matrix)->data_space)->boxes[i]))->imin[1])) + 1) ? (((&(((matrix)->data_space)->boxes[i]))->imax[1]) - ((&(((matrix)->data_space)->boxes[i]))->imin[1])) + 1 : 0))) * (0 < ((((&(((matrix)->data_space)->boxes[i]))->imax[0]) - ((&(((matrix)->data_space)->boxes[i]))->imin[0])) + 1) ? (((&(((matrix)->data_space)->boxes[i]))->imax[0]) - ((&(((matrix)->data_space)->boxes[i]))->imin[0])) + 1 : 0)));
              *matp += values[s];
            }
          }
          else
            if (action > (-1)) {
              for (s = 0; s < num_stencil_indices; s++) {
                matp = ((matrix)->data + ((matrix)->data_indices[i][stencil_indices[s]])) + (((grid_index[0]) - ((&(((matrix)->data_space)->boxes[i]))->imin[0])) + ((((grid_index[1]) - ((&(((matrix)->data_space)->boxes[i]))->imin[1])) + (((grid_index[2]) - ((&(((matrix)->data_space)->boxes[i]))->imin[2])) * (0 < ((((&(((matrix)->data_space)->boxes[i]))->imax[1]) - ((&(((matrix)->data_space)->boxes[i]))->imin[1])) + 1) ? (((&(((matrix)->data_space)->boxes[i]))->imax[1]) - ((&(((matrix)->data_space)->boxes[i]))->imin[1])) + 1 : 0))) * (0 < ((((&(((matrix)->data_space)->boxes[i]))->imax[0]) - ((&(((matrix)->data_space)->boxes[i]))->imin[0])) + 1) ? (((&(((matrix)->data_space)->boxes[i]))->imax[0]) - ((&(((matrix)->data_space)->boxes[i]))->imin[0])) + 1 : 0)));
                *matp = values[s];
              }
            }
            else {
              for (s = 0; s < num_stencil_indices; s++) {
                matp = ((matrix)->data + ((matrix)->data_indices[i][stencil_indices[s]])) + (((grid_index[0]) - ((&(((matrix)->data_space)->boxes[i]))->imin[0])) + ((((grid_index[1]) - ((&(((matrix)->data_space)->boxes[i]))->imin[1])) + (((grid_index[2]) - ((&(((matrix)->data_space)->boxes[i]))->imin[2])) * (0 < ((((&(((matrix)->data_space)->boxes[i]))->imax[1]) - ((&(((matrix)->data_space)->boxes[i]))->imin[1])) + 1) ? (((&(((matrix)->data_space)->boxes[i]))->imax[1]) - ((&(((matrix)->data_space)->boxes[i]))->imin[1])) + 1 : 0))) * (0 < ((((&(((matrix)->data_space)->boxes[i]))->imax[0]) - ((&(((matrix)->data_space)->boxes[i]))->imin[0])) + 1) ? (((&(((matrix)->data_space)->boxes[i]))->imax[0]) - ((&(((matrix)->data_space)->boxes[i]))->imin[0])) + 1 : 0)));
                values[s] = *matp;
              }
            }
          found = true;
        }
      }
  }
  if (((!found) && (action > 0)) && (nprocs > 1)) {
    hypre_Box* orig_box;
    int* add_num_ghost = (matrix)->add_num_ghost;
    int j;
    for (i = 0; i < (boxes)->size; i++) {
      orig_box = &((boxes)->boxes[i]);
      box = hypre_BoxDuplicate(orig_box);
      for (j = 0; j < 3; j++) {
        ((box)->imin[j]) -= (add_num_ghost[2 * j]);
        (box)->imax[j] += add_num_ghost[(2 * j) + 1];
      }
      if (constant_coefficient == 2) {
        center_index[0] = 0, center_index[1] = 0, center_index[2] = 0;
        stencil = (matrix)->stencil;
        center_rank = hypre_StructStencilElementRank(stencil, center_index);
        if (((((((grid_index[0]) >= ((box)->imin[0])) && ((grid_index[0]) <= ((box)->imax[0]))) && ((grid_index[1]) >= ((box)->imin[1]))) && ((grid_index[1]) <= ((box)->imax[1]))) && ((grid_index[2]) >= ((box)->imin[2]))) && ((grid_index[2]) <= ((box)->imax[2]))) {
          matp = ((matrix)->data + ((matrix)->data_indices[i][stencil_indices[center_rank]])) + (((grid_index[0]) - ((&(((matrix)->data_space)->boxes[i]))->imin[0])) + ((((grid_index[1]) - ((&(((matrix)->data_space)->boxes[i]))->imin[1])) + (((grid_index[2]) - ((&(((matrix)->data_space)->boxes[i]))->imin[2])) * (0 < ((((&(((matrix)->data_space)->boxes[i]))->imax[1]) - ((&(((matrix)->data_space)->boxes[i]))->imin[1])) + 1) ? (((&(((matrix)->data_space)->boxes[i]))->imax[1]) - ((&(((matrix)->data_space)->boxes[i]))->imin[1])) + 1 : 0))) * (0 < ((((&(((matrix)->data_space)->boxes[i]))->imax[0]) - ((&(((matrix)->data_space)->boxes[i]))->imin[0])) + 1) ? (((&(((matrix)->data_space)->boxes[i]))->imax[0]) - ((&(((matrix)->data_space)->boxes[i]))->imin[0])) + 1 : 0)));
          *matp += values[s];
          found = true;
        }
      }
      else {
        if (((((((grid_index[0]) >= ((box)->imin[0])) && ((grid_index[0]) <= ((box)->imax[0]))) && ((grid_index[1]) >= ((box)->imin[1]))) && ((grid_index[1]) <= ((box)->imax[1]))) && ((grid_index[2]) >= ((box)->imin[2]))) && ((grid_index[2]) <= ((box)->imax[2]))) {
          for (s = 0; s < num_stencil_indices; s++) {
            matp = ((matrix)->data + ((matrix)->data_indices[i][stencil_indices[s]])) + (((grid_index[0]) - ((&(((matrix)->data_space)->boxes[i]))->imin[0])) + ((((grid_index[1]) - ((&(((matrix)->data_space)->boxes[i]))->imin[1])) + (((grid_index[2]) - ((&(((matrix)->data_space)->boxes[i]))->imin[2])) * (0 < ((((&(((matrix)->data_space)->boxes[i]))->imax[1]) - ((&(((matrix)->data_space)->boxes[i]))->imin[1])) + 1) ? (((&(((matrix)->data_space)->boxes[i]))->imax[1]) - ((&(((matrix)->data_space)->boxes[i]))->imin[1])) + 1 : 0))) * (0 < ((((&(((matrix)->data_space)->boxes[i]))->imax[0]) - ((&(((matrix)->data_space)->boxes[i]))->imin[0])) + 1) ? (((&(((matrix)->data_space)->boxes[i]))->imax[0]) - ((&(((matrix)->data_space)->boxes[i]))->imin[0])) + 1 : 0)));
            *matp += values[s];
          }
          found = true;
        }
      }
      if (found)
        break;
    }
    if (found) {
      (matrix)->OffProcAdd = 1;
    }
    else {
      printf("not found- grid_index off the extended matrix grid\n");
    }
  }
  return ierr;
}
int hypre_StructMatrixSetBoxValues(hypre_StructMatrix* matrix, hypre_Box* value_box, int num_stencil_indices, int* stencil_indices, double* values, int action) {
  int ierr = 0;
  MPI_Comm comm = (matrix)->comm;
  int* add_num_ghost = (matrix)->add_num_ghost;
  hypre_BoxArray* grid_boxes;
  hypre_Box* grid_box;
  hypre_BoxArray* box_array1;
  hypre_BoxArray* box_array2;
  hypre_BoxArray* tmp_box_array;
  hypre_BoxArray* value_boxarray;
  hypre_BoxArrayArray* box_aarray;
  hypre_Box* box;
  hypre_Box* tmp_box;
  hypre_Box* orig_box;
  hypre_Box* vbox;
  hypre_Index center_index;
  hypre_StructStencil* stencil;
  int center_rank;
  hypre_BoxArray* data_space;
  hypre_Box* data_box;
  hypre_IndexRef data_start;
  hypre_Index data_stride;
  int datai;
  double* datap;
  int constant_coefficient;
  hypre_Box* dval_box;
  hypre_Index dval_start;
  hypre_Index dval_stride;
  int dvali;
  hypre_Index loop_size;
  int i;
  int j;
  int k;
  int s;
  int vol_vbox;
  int vol_iboxes;
  int vol_offproc;
  int loopi;
  int loopj;
  int loopk;
  int nprocs;
  MPI_Comm_size(comm, &(nprocs));
  constant_coefficient = (matrix)->constant_coefficient;
  vol_vbox = ((0 < ((((value_box)->imax[0]) - ((value_box)->imin[0])) + 1) ? (((value_box)->imax[0]) - ((value_box)->imin[0])) + 1 : 0) * (0 < ((((value_box)->imax[1]) - ((value_box)->imin[1])) + 1) ? (((value_box)->imax[1]) - ((value_box)->imin[1])) + 1 : 0)) * (0 < ((((value_box)->imax[2]) - ((value_box)->imin[2])) + 1) ? (((value_box)->imax[2]) - ((value_box)->imin[2])) + 1 : 0);
  vol_iboxes = 0;
  grid_boxes = ((matrix)->grid)->boxes;
  box_array1 = hypre_BoxArrayCreate((grid_boxes)->size);
  box = hypre_BoxCreate();
  for (i = 0; i < (grid_boxes)->size; i++) {
    grid_box = &((grid_boxes)->boxes[i]);
    hypre_IntersectBoxes(value_box, grid_box, box);
    (&((box_array1)->boxes[i]))->imin[0] = (box)->imin[0], (&((box_array1)->boxes[i]))->imin[1] = (box)->imin[1], (&((box_array1)->boxes[i]))->imin[2] = (box)->imin[2], (&((box_array1)->boxes[i]))->imax[0] = (box)->imax[0], (&((box_array1)->boxes[i]))->imax[1] = (box)->imax[1], (&((box_array1)->boxes[i]))->imax[2] = (box)->imax[2];
    vol_iboxes += ((0 < ((((box)->imax[0]) - ((box)->imin[0])) + 1) ? (((box)->imax[0]) - ((box)->imin[0])) + 1 : 0) * (0 < ((((box)->imax[1]) - ((box)->imin[1])) + 1) ? (((box)->imax[1]) - ((box)->imin[1])) + 1 : 0)) * (0 < ((((box)->imax[2]) - ((box)->imin[2])) + 1) ? (((box)->imax[2]) - ((box)->imin[2])) + 1 : 0);
  }
  vol_offproc = 0;
  if (((vol_vbox > vol_iboxes) && (action > 0)) && (nprocs > 1)) {
    box_aarray = hypre_BoxArrayArrayCreate((grid_boxes)->size);
    value_boxarray = hypre_BoxArrayCreate(0);
    hypre_AppendBox(value_box, value_boxarray);
    for (i = 0; i < (grid_boxes)->size; i++) {
      tmp_box_array = hypre_BoxArrayCreate(0);
      orig_box = &((grid_boxes)->boxes[i]);
      tmp_box = hypre_BoxDuplicate(orig_box);
      for (j = 0; j < 3; j++) {
        ((tmp_box)->imin[j]) -= (add_num_ghost[2 * j]);
        (tmp_box)->imax[j] += add_num_ghost[(2 * j) + 1];
      }
      hypre_SubtractBoxes(tmp_box, orig_box, tmp_box_array);
      hypre_BoxDestroy(tmp_box);
      box_array2 = (box_aarray)->box_arrays[i];
      for (j = 0; j < (tmp_box_array)->size; j++) {
        tmp_box = &((tmp_box_array)->boxes[j]);
        for (k = 0; k < (value_boxarray)->size; k++) {
          vbox = &((value_boxarray)->boxes[k]);
          hypre_IntersectBoxes(vbox, tmp_box, box);
          hypre_AppendBox(box, box_array2);
          vol_offproc += ((0 < ((((box)->imax[0]) - ((box)->imin[0])) + 1) ? (((box)->imax[0]) - ((box)->imin[0])) + 1 : 0) * (0 < ((((box)->imax[1]) - ((box)->imin[1])) + 1) ? (((box)->imax[1]) - ((box)->imin[1])) + 1 : 0)) * (0 < ((((box)->imax[2]) - ((box)->imin[2])) + 1) ? (((box)->imax[2]) - ((box)->imin[2])) + 1 : 0);
        }
      }
      hypre_SubtractBoxArrays(value_boxarray, box_array2, tmp_box_array);
      hypre_BoxArrayDestroy(tmp_box_array);
    }
    if (!vol_offproc) {
      hypre_BoxArrayArrayDestroy(box_aarray);
    }
    else {
      (matrix)->OffProcAdd = 1;
    }
    hypre_BoxArrayDestroy(value_boxarray);
  }
  hypre_BoxDestroy(box);
  if (box_array1) {
    data_space = (matrix)->data_space;
    data_stride[0] = 1, data_stride[1] = 1, data_stride[2] = 1;
    dval_box = hypre_BoxDuplicate(value_box);
    ((dval_box)->imin[0]) -= num_stencil_indices;
    ((dval_box)->imax[0]) -= num_stencil_indices;
    (dval_box)->imax[0] += num_stencil_indices - 1;
    dval_stride[0] = num_stencil_indices, dval_stride[1] = 1, dval_stride[2] = 1;
    for (i = 0; i < (box_array1)->size; i++) {
      box = &((box_array1)->boxes[i]);
      data_box = &((data_space)->boxes[i]);
      if (box) {
        data_start = (box)->imin;
        dval_start[0] = data_start[0], dval_start[1] = data_start[1], dval_start[2] = data_start[2];
        (dval_start[0]) -= num_stencil_indices;
        if (constant_coefficient == 2) {
          center_index[0] = 0, center_index[1] = 0, center_index[2] = 0;
          stencil = (matrix)->stencil;
          center_rank = hypre_StructStencilElementRank(stencil, center_index);
        }
        for (s = 0; s < num_stencil_indices; s++) {
          datap = (matrix)->data + ((matrix)->data_indices[i][stencil_indices[s]]);
          if ((constant_coefficient == 1) || ((constant_coefficient == 2) && ((stencil_indices[s]) != center_rank))) {
            ++ierr;
            hypre_BoxGetSize(box, loop_size);
            if (action > 0) {
              datai = 0;
              dvali = ((dval_start[0]) - ((dval_box)->imin[0])) + ((((dval_start[1]) - ((dval_box)->imin[1])) + (((dval_start[2]) - ((dval_box)->imin[2])) * (0 < ((((dval_box)->imax[1]) - ((dval_box)->imin[1])) + 1) ? (((dval_box)->imax[1]) - ((dval_box)->imin[1])) + 1 : 0))) * (0 < ((((dval_box)->imax[0]) - ((dval_box)->imin[0])) + 1) ? (((dval_box)->imax[0]) - ((dval_box)->imin[0])) + 1 : 0));
              datap[datai] += values[dvali];
            }
            else
              if (action > (-1)) {
                datai = 0;
                dvali = ((dval_start[0]) - ((dval_box)->imin[0])) + ((((dval_start[1]) - ((dval_box)->imin[1])) + (((dval_start[2]) - ((dval_box)->imin[2])) * (0 < ((((dval_box)->imax[1]) - ((dval_box)->imin[1])) + 1) ? (((dval_box)->imax[1]) - ((dval_box)->imin[1])) + 1 : 0))) * (0 < ((((dval_box)->imax[0]) - ((dval_box)->imin[0])) + 1) ? (((dval_box)->imax[0]) - ((dval_box)->imin[0])) + 1 : 0));
                datap[datai] = values[dvali];
              }
              else {
                datai = 0;
                dvali = ((dval_start[0]) - ((dval_box)->imin[0])) + ((((dval_start[1]) - ((dval_box)->imin[1])) + (((dval_start[2]) - ((dval_box)->imin[2])) * (0 < ((((dval_box)->imax[1]) - ((dval_box)->imin[1])) + 1) ? (((dval_box)->imax[1]) - ((dval_box)->imin[1])) + 1 : 0))) * (0 < ((((dval_box)->imax[0]) - ((dval_box)->imin[0])) + 1) ? (((dval_box)->imax[0]) - ((dval_box)->imin[0])) + 1 : 0));
                values[dvali] = datap[datai];
                if (action == (-1)) {
                  datap[datai] = 0;
                }
              }
          }
          else {
            hypre_BoxGetSize(box, loop_size);
            if (action > 0) {
              {
                int hypre__i1start = ((data_start[0]) - ((data_box)->imin[0])) + ((((data_start[1]) - ((data_box)->imin[1])) + (((data_start[2]) - ((data_box)->imin[2])) * (0 < ((((data_box)->imax[1]) - ((data_box)->imin[1])) + 1) ? (((data_box)->imax[1]) - ((data_box)->imin[1])) + 1 : 0))) * (0 < ((((data_box)->imax[0]) - ((data_box)->imin[0])) + 1) ? (((data_box)->imax[0]) - ((data_box)->imin[0])) + 1 : 0));
                int hypre__i2start = ((dval_start[0]) - ((dval_box)->imin[0])) + ((((dval_start[1]) - ((dval_box)->imin[1])) + (((dval_start[2]) - ((dval_box)->imin[2])) * (0 < ((((dval_box)->imax[1]) - ((dval_box)->imin[1])) + 1) ? (((dval_box)->imax[1]) - ((dval_box)->imin[1])) + 1 : 0))) * (0 < ((((dval_box)->imax[0]) - ((dval_box)->imin[0])) + 1) ? (((dval_box)->imax[0]) - ((dval_box)->imin[0])) + 1 : 0));
                int hypre__sx1 = data_stride[0];
                int hypre__sy1 = (data_stride[1]) * (0 < ((((data_box)->imax[0]) - ((data_box)->imin[0])) + 1) ? (((data_box)->imax[0]) - ((data_box)->imin[0])) + 1 : 0);
                int hypre__sz1 = ((data_stride[2]) * (0 < ((((data_box)->imax[0]) - ((data_box)->imin[0])) + 1) ? (((data_box)->imax[0]) - ((data_box)->imin[0])) + 1 : 0)) * (0 < ((((data_box)->imax[1]) - ((data_box)->imin[1])) + 1) ? (((data_box)->imax[1]) - ((data_box)->imin[1])) + 1 : 0);
                int hypre__sx2 = dval_stride[0];
                int hypre__sy2 = (dval_stride[1]) * (0 < ((((dval_box)->imax[0]) - ((dval_box)->imin[0])) + 1) ? (((dval_box)->imax[0]) - ((dval_box)->imin[0])) + 1 : 0);
                int hypre__sz2 = ((dval_stride[2]) * (0 < ((((dval_box)->imax[0]) - ((dval_box)->imin[0])) + 1) ? (((dval_box)->imax[0]) - ((dval_box)->imin[0])) + 1 : 0)) * (0 < ((((dval_box)->imax[1]) - ((dval_box)->imin[1])) + 1) ? (((dval_box)->imax[1]) - ((dval_box)->imin[1])) + 1 : 0);
                int hypre__nx = loop_size[0];
                int hypre__ny = loop_size[1];
                int hypre__nz = loop_size[2];
                int hypre__mx = hypre__nx;
                int hypre__my = hypre__ny;
                int hypre__mz = hypre__nz;
                int hypre__dir;
                int hypre__max;
                int hypre__div;
                int hypre__mod;
                int hypre__block;
                int hypre__num_blocks;
                hypre__dir = 0;
                hypre__max = hypre__nx;
                if (hypre__ny > hypre__max) {
                  hypre__dir = 1;
                  hypre__max = hypre__ny;
                }
                if (hypre__nz > hypre__max) {
                  hypre__dir = 2;
                  hypre__max = hypre__nz;
                }
                hypre__num_blocks = 1;
                if (hypre__max < hypre__num_blocks) {
                  hypre__num_blocks = hypre__max;
                }
                if (hypre__num_blocks > 0) {
                  hypre__div = hypre__max / hypre__num_blocks;
                  hypre__mod = hypre__max % hypre__num_blocks;
                }
                ;
                ;
                for (hypre__block = 0; hypre__block < hypre__num_blocks; hypre__block++) {
                  loopi = 0;
                  loopj = 0;
                  loopk = 0;
                  hypre__nx = hypre__mx;
                  hypre__ny = hypre__my;
                  hypre__nz = hypre__mz;
                  if (hypre__num_blocks > 1) {
                    if (hypre__dir == 0) {
                      loopi = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                      hypre__nx = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                    }
                    else
                      if (hypre__dir == 1) {
                        loopj = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                        hypre__ny = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                      }
                      else
                        if (hypre__dir == 2) {
                          loopk = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                          hypre__nz = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                        }
                  }
                  ;
                  datai = ((hypre__i1start + (loopi * hypre__sx1)) + (loopj * hypre__sy1)) + (loopk * hypre__sz1);
                  dvali = ((hypre__i2start + (loopi * hypre__sx2)) + (loopj * hypre__sy2)) + (loopk * hypre__sz2);
                  for (loopk = 0; loopk < hypre__nz; loopk++) {
                    for (loopj = 0; loopj < hypre__ny; loopj++) {
                      for (loopi = 0; loopi < hypre__nx; loopi++) {
                        {
                          datap[datai] += values[dvali];
                        }
                        datai += hypre__sx1;
                        dvali += hypre__sx2;
                      }
                      datai += hypre__sy1 - (hypre__nx * hypre__sx1);
                      dvali += hypre__sy2 - (hypre__nx * hypre__sx2);
                    }
                    datai += hypre__sz1 - (hypre__ny * hypre__sy1);
                    dvali += hypre__sz2 - (hypre__ny * hypre__sy2);
                  }
                }
              }
              ;
            }
            else
              if (action > (-1)) {
                {
                  int hypre__i1start = ((data_start[0]) - ((data_box)->imin[0])) + ((((data_start[1]) - ((data_box)->imin[1])) + (((data_start[2]) - ((data_box)->imin[2])) * (0 < ((((data_box)->imax[1]) - ((data_box)->imin[1])) + 1) ? (((data_box)->imax[1]) - ((data_box)->imin[1])) + 1 : 0))) * (0 < ((((data_box)->imax[0]) - ((data_box)->imin[0])) + 1) ? (((data_box)->imax[0]) - ((data_box)->imin[0])) + 1 : 0));
                  int hypre__i2start = ((dval_start[0]) - ((dval_box)->imin[0])) + ((((dval_start[1]) - ((dval_box)->imin[1])) + (((dval_start[2]) - ((dval_box)->imin[2])) * (0 < ((((dval_box)->imax[1]) - ((dval_box)->imin[1])) + 1) ? (((dval_box)->imax[1]) - ((dval_box)->imin[1])) + 1 : 0))) * (0 < ((((dval_box)->imax[0]) - ((dval_box)->imin[0])) + 1) ? (((dval_box)->imax[0]) - ((dval_box)->imin[0])) + 1 : 0));
                  int hypre__sx1 = data_stride[0];
                  int hypre__sy1 = (data_stride[1]) * (0 < ((((data_box)->imax[0]) - ((data_box)->imin[0])) + 1) ? (((data_box)->imax[0]) - ((data_box)->imin[0])) + 1 : 0);
                  int hypre__sz1 = ((data_stride[2]) * (0 < ((((data_box)->imax[0]) - ((data_box)->imin[0])) + 1) ? (((data_box)->imax[0]) - ((data_box)->imin[0])) + 1 : 0)) * (0 < ((((data_box)->imax[1]) - ((data_box)->imin[1])) + 1) ? (((data_box)->imax[1]) - ((data_box)->imin[1])) + 1 : 0);
                  int hypre__sx2 = dval_stride[0];
                  int hypre__sy2 = (dval_stride[1]) * (0 < ((((dval_box)->imax[0]) - ((dval_box)->imin[0])) + 1) ? (((dval_box)->imax[0]) - ((dval_box)->imin[0])) + 1 : 0);
                  int hypre__sz2 = ((dval_stride[2]) * (0 < ((((dval_box)->imax[0]) - ((dval_box)->imin[0])) + 1) ? (((dval_box)->imax[0]) - ((dval_box)->imin[0])) + 1 : 0)) * (0 < ((((dval_box)->imax[1]) - ((dval_box)->imin[1])) + 1) ? (((dval_box)->imax[1]) - ((dval_box)->imin[1])) + 1 : 0);
                  int hypre__nx = loop_size[0];
                  int hypre__ny = loop_size[1];
                  int hypre__nz = loop_size[2];
                  int hypre__mx = hypre__nx;
                  int hypre__my = hypre__ny;
                  int hypre__mz = hypre__nz;
                  int hypre__dir;
                  int hypre__max;
                  int hypre__div;
                  int hypre__mod;
                  int hypre__block;
                  int hypre__num_blocks;
                  hypre__dir = 0;
                  hypre__max = hypre__nx;
                  if (hypre__ny > hypre__max) {
                    hypre__dir = 1;
                    hypre__max = hypre__ny;
                  }
                  if (hypre__nz > hypre__max) {
                    hypre__dir = 2;
                    hypre__max = hypre__nz;
                  }
                  hypre__num_blocks = 1;
                  if (hypre__max < hypre__num_blocks) {
                    hypre__num_blocks = hypre__max;
                  }
                  if (hypre__num_blocks > 0) {
                    hypre__div = hypre__max / hypre__num_blocks;
                    hypre__mod = hypre__max % hypre__num_blocks;
                  }
                  ;
                  ;
                  for (hypre__block = 0; hypre__block < hypre__num_blocks; hypre__block++) {
                    loopi = 0;
                    loopj = 0;
                    loopk = 0;
                    hypre__nx = hypre__mx;
                    hypre__ny = hypre__my;
                    hypre__nz = hypre__mz;
                    if (hypre__num_blocks > 1) {
                      if (hypre__dir == 0) {
                        loopi = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                        hypre__nx = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                      }
                      else
                        if (hypre__dir == 1) {
                          loopj = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                          hypre__ny = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                        }
                        else
                          if (hypre__dir == 2) {
                            loopk = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                            hypre__nz = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                          }
                    }
                    ;
                    datai = ((hypre__i1start + (loopi * hypre__sx1)) + (loopj * hypre__sy1)) + (loopk * hypre__sz1);
                    dvali = ((hypre__i2start + (loopi * hypre__sx2)) + (loopj * hypre__sy2)) + (loopk * hypre__sz2);
                    for (loopk = 0; loopk < hypre__nz; loopk++) {
                      for (loopj = 0; loopj < hypre__ny; loopj++) {
                        for (loopi = 0; loopi < hypre__nx; loopi++) {
                          {
                            datap[datai] = values[dvali];
                          }
                          datai += hypre__sx1;
                          dvali += hypre__sx2;
                        }
                        datai += hypre__sy1 - (hypre__nx * hypre__sx1);
                        dvali += hypre__sy2 - (hypre__nx * hypre__sx2);
                      }
                      datai += hypre__sz1 - (hypre__ny * hypre__sy1);
                      dvali += hypre__sz2 - (hypre__ny * hypre__sy2);
                    }
                  }
                }
                ;
              }
              else {
                {
                  int hypre__i1start = ((data_start[0]) - ((data_box)->imin[0])) + ((((data_start[1]) - ((data_box)->imin[1])) + (((data_start[2]) - ((data_box)->imin[2])) * (0 < ((((data_box)->imax[1]) - ((data_box)->imin[1])) + 1) ? (((data_box)->imax[1]) - ((data_box)->imin[1])) + 1 : 0))) * (0 < ((((data_box)->imax[0]) - ((data_box)->imin[0])) + 1) ? (((data_box)->imax[0]) - ((data_box)->imin[0])) + 1 : 0));
                  int hypre__i2start = ((dval_start[0]) - ((dval_box)->imin[0])) + ((((dval_start[1]) - ((dval_box)->imin[1])) + (((dval_start[2]) - ((dval_box)->imin[2])) * (0 < ((((dval_box)->imax[1]) - ((dval_box)->imin[1])) + 1) ? (((dval_box)->imax[1]) - ((dval_box)->imin[1])) + 1 : 0))) * (0 < ((((dval_box)->imax[0]) - ((dval_box)->imin[0])) + 1) ? (((dval_box)->imax[0]) - ((dval_box)->imin[0])) + 1 : 0));
                  int hypre__sx1 = data_stride[0];
                  int hypre__sy1 = (data_stride[1]) * (0 < ((((data_box)->imax[0]) - ((data_box)->imin[0])) + 1) ? (((data_box)->imax[0]) - ((data_box)->imin[0])) + 1 : 0);
                  int hypre__sz1 = ((data_stride[2]) * (0 < ((((data_box)->imax[0]) - ((data_box)->imin[0])) + 1) ? (((data_box)->imax[0]) - ((data_box)->imin[0])) + 1 : 0)) * (0 < ((((data_box)->imax[1]) - ((data_box)->imin[1])) + 1) ? (((data_box)->imax[1]) - ((data_box)->imin[1])) + 1 : 0);
                  int hypre__sx2 = dval_stride[0];
                  int hypre__sy2 = (dval_stride[1]) * (0 < ((((dval_box)->imax[0]) - ((dval_box)->imin[0])) + 1) ? (((dval_box)->imax[0]) - ((dval_box)->imin[0])) + 1 : 0);
                  int hypre__sz2 = ((dval_stride[2]) * (0 < ((((dval_box)->imax[0]) - ((dval_box)->imin[0])) + 1) ? (((dval_box)->imax[0]) - ((dval_box)->imin[0])) + 1 : 0)) * (0 < ((((dval_box)->imax[1]) - ((dval_box)->imin[1])) + 1) ? (((dval_box)->imax[1]) - ((dval_box)->imin[1])) + 1 : 0);
                  int hypre__nx = loop_size[0];
                  int hypre__ny = loop_size[1];
                  int hypre__nz = loop_size[2];
                  int hypre__mx = hypre__nx;
                  int hypre__my = hypre__ny;
                  int hypre__mz = hypre__nz;
                  int hypre__dir;
                  int hypre__max;
                  int hypre__div;
                  int hypre__mod;
                  int hypre__block;
                  int hypre__num_blocks;
                  hypre__dir = 0;
                  hypre__max = hypre__nx;
                  if (hypre__ny > hypre__max) {
                    hypre__dir = 1;
                    hypre__max = hypre__ny;
                  }
                  if (hypre__nz > hypre__max) {
                    hypre__dir = 2;
                    hypre__max = hypre__nz;
                  }
                  hypre__num_blocks = 1;
                  if (hypre__max < hypre__num_blocks) {
                    hypre__num_blocks = hypre__max;
                  }
                  if (hypre__num_blocks > 0) {
                    hypre__div = hypre__max / hypre__num_blocks;
                    hypre__mod = hypre__max % hypre__num_blocks;
                  }
                  ;
                  ;
                  for (hypre__block = 0; hypre__block < hypre__num_blocks; hypre__block++) {
                    loopi = 0;
                    loopj = 0;
                    loopk = 0;
                    hypre__nx = hypre__mx;
                    hypre__ny = hypre__my;
                    hypre__nz = hypre__mz;
                    if (hypre__num_blocks > 1) {
                      if (hypre__dir == 0) {
                        loopi = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                        hypre__nx = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                      }
                      else
                        if (hypre__dir == 1) {
                          loopj = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                          hypre__ny = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                        }
                        else
                          if (hypre__dir == 2) {
                            loopk = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                            hypre__nz = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                          }
                    }
                    ;
                    datai = ((hypre__i1start + (loopi * hypre__sx1)) + (loopj * hypre__sy1)) + (loopk * hypre__sz1);
                    dvali = ((hypre__i2start + (loopi * hypre__sx2)) + (loopj * hypre__sy2)) + (loopk * hypre__sz2);
                    for (loopk = 0; loopk < hypre__nz; loopk++) {
                      for (loopj = 0; loopj < hypre__ny; loopj++) {
                        for (loopi = 0; loopi < hypre__nx; loopi++) {
                          {
                            values[dvali] = datap[datai];
                            if (action == (-1)) {
                              datap[datai] = 0;
                            }
                          }
                          datai += hypre__sx1;
                          dvali += hypre__sx2;
                        }
                        datai += hypre__sy1 - (hypre__nx * hypre__sx1);
                        dvali += hypre__sy2 - (hypre__nx * hypre__sx2);
                      }
                      datai += hypre__sz1 - (hypre__ny * hypre__sy1);
                      dvali += hypre__sz2 - (hypre__ny * hypre__sy2);
                    }
                  }
                }
                ;
              }
          }
          dval_start[0]++;
        }
      }
    }
    hypre_BoxDestroy(dval_box);
  }
  hypre_BoxArrayDestroy(box_array1);
  if (vol_offproc) {
    data_space = (matrix)->data_space;
    data_stride[0] = 1, data_stride[1] = 1, data_stride[2] = 1;
    dval_box = hypre_BoxDuplicate(value_box);
    ((dval_box)->imin[0]) -= num_stencil_indices;
    ((dval_box)->imax[0]) -= num_stencil_indices;
    (dval_box)->imax[0] += num_stencil_indices - 1;
    dval_stride[0] = num_stencil_indices, dval_stride[1] = 1, dval_stride[2] = 1;
    for (i = 0; i < (data_space)->size; i++) {
      data_box = &((data_space)->boxes[i]);
      box_array2 = (box_aarray)->box_arrays[i];
      for (j = 0; j < (box_array2)->size; j++) {
        box = &((box_array2)->boxes[j]);
        if (box) {
          data_start = (box)->imin;
          dval_start[0] = data_start[0], dval_start[1] = data_start[1], dval_start[2] = data_start[2];
          (dval_start[0]) -= num_stencil_indices;
          if (constant_coefficient == 2) {
            center_index[0] = 0, center_index[1] = 0, center_index[2] = 0;
            stencil = (matrix)->stencil;
            center_rank = hypre_StructStencilElementRank(stencil, center_index);
          }
          for (s = 0; s < num_stencil_indices; s++) {
            datap = (matrix)->data + ((matrix)->data_indices[i][stencil_indices[s]]);
            if ((constant_coefficient == 0) || ((constant_coefficient == 2) && ((stencil_indices[s]) == center_rank))) {
              hypre_BoxGetSize(box, loop_size);
              {
                int hypre__i1start = ((data_start[0]) - ((data_box)->imin[0])) + ((((data_start[1]) - ((data_box)->imin[1])) + (((data_start[2]) - ((data_box)->imin[2])) * (0 < ((((data_box)->imax[1]) - ((data_box)->imin[1])) + 1) ? (((data_box)->imax[1]) - ((data_box)->imin[1])) + 1 : 0))) * (0 < ((((data_box)->imax[0]) - ((data_box)->imin[0])) + 1) ? (((data_box)->imax[0]) - ((data_box)->imin[0])) + 1 : 0));
                int hypre__i2start = ((dval_start[0]) - ((dval_box)->imin[0])) + ((((dval_start[1]) - ((dval_box)->imin[1])) + (((dval_start[2]) - ((dval_box)->imin[2])) * (0 < ((((dval_box)->imax[1]) - ((dval_box)->imin[1])) + 1) ? (((dval_box)->imax[1]) - ((dval_box)->imin[1])) + 1 : 0))) * (0 < ((((dval_box)->imax[0]) - ((dval_box)->imin[0])) + 1) ? (((dval_box)->imax[0]) - ((dval_box)->imin[0])) + 1 : 0));
                int hypre__sx1 = data_stride[0];
                int hypre__sy1 = (data_stride[1]) * (0 < ((((data_box)->imax[0]) - ((data_box)->imin[0])) + 1) ? (((data_box)->imax[0]) - ((data_box)->imin[0])) + 1 : 0);
                int hypre__sz1 = ((data_stride[2]) * (0 < ((((data_box)->imax[0]) - ((data_box)->imin[0])) + 1) ? (((data_box)->imax[0]) - ((data_box)->imin[0])) + 1 : 0)) * (0 < ((((data_box)->imax[1]) - ((data_box)->imin[1])) + 1) ? (((data_box)->imax[1]) - ((data_box)->imin[1])) + 1 : 0);
                int hypre__sx2 = dval_stride[0];
                int hypre__sy2 = (dval_stride[1]) * (0 < ((((dval_box)->imax[0]) - ((dval_box)->imin[0])) + 1) ? (((dval_box)->imax[0]) - ((dval_box)->imin[0])) + 1 : 0);
                int hypre__sz2 = ((dval_stride[2]) * (0 < ((((dval_box)->imax[0]) - ((dval_box)->imin[0])) + 1) ? (((dval_box)->imax[0]) - ((dval_box)->imin[0])) + 1 : 0)) * (0 < ((((dval_box)->imax[1]) - ((dval_box)->imin[1])) + 1) ? (((dval_box)->imax[1]) - ((dval_box)->imin[1])) + 1 : 0);
                int hypre__nx = loop_size[0];
                int hypre__ny = loop_size[1];
                int hypre__nz = loop_size[2];
                int hypre__mx = hypre__nx;
                int hypre__my = hypre__ny;
                int hypre__mz = hypre__nz;
                int hypre__dir;
                int hypre__max;
                int hypre__div;
                int hypre__mod;
                int hypre__block;
                int hypre__num_blocks;
                hypre__dir = 0;
                hypre__max = hypre__nx;
                if (hypre__ny > hypre__max) {
                  hypre__dir = 1;
                  hypre__max = hypre__ny;
                }
                if (hypre__nz > hypre__max) {
                  hypre__dir = 2;
                  hypre__max = hypre__nz;
                }
                hypre__num_blocks = 1;
                if (hypre__max < hypre__num_blocks) {
                  hypre__num_blocks = hypre__max;
                }
                if (hypre__num_blocks > 0) {
                  hypre__div = hypre__max / hypre__num_blocks;
                  hypre__mod = hypre__max % hypre__num_blocks;
                }
                ;
                ;
                for (hypre__block = 0; hypre__block < hypre__num_blocks; hypre__block++) {
                  loopi = 0;
                  loopj = 0;
                  loopk = 0;
                  hypre__nx = hypre__mx;
                  hypre__ny = hypre__my;
                  hypre__nz = hypre__mz;
                  if (hypre__num_blocks > 1) {
                    if (hypre__dir == 0) {
                      loopi = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                      hypre__nx = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                    }
                    else
                      if (hypre__dir == 1) {
                        loopj = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                        hypre__ny = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                      }
                      else
                        if (hypre__dir == 2) {
                          loopk = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                          hypre__nz = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                        }
                  }
                  ;
                  datai = ((hypre__i1start + (loopi * hypre__sx1)) + (loopj * hypre__sy1)) + (loopk * hypre__sz1);
                  dvali = ((hypre__i2start + (loopi * hypre__sx2)) + (loopj * hypre__sy2)) + (loopk * hypre__sz2);
                  for (loopk = 0; loopk < hypre__nz; loopk++) {
                    for (loopj = 0; loopj < hypre__ny; loopj++) {
                      for (loopi = 0; loopi < hypre__nx; loopi++) {
                        {
                          datap[datai] += values[dvali];
                        }
                        datai += hypre__sx1;
                        dvali += hypre__sx2;
                      }
                      datai += hypre__sy1 - (hypre__nx * hypre__sx1);
                      dvali += hypre__sy2 - (hypre__nx * hypre__sx2);
                    }
                    datai += hypre__sz1 - (hypre__ny * hypre__sy1);
                    dvali += hypre__sz2 - (hypre__ny * hypre__sy2);
                  }
                }
              }
              ;
            }
            dval_start[0]++;
          }
        }
      }
    }
    hypre_BoxDestroy(dval_box);
    hypre_BoxArrayArrayDestroy(box_aarray);
  }
  return ierr;
}
int hypre_StructMatrixAssemble(hypre_StructMatrix* matrix) {
  int ierr = 0;
  int* num_ghost = (matrix)->num_ghost;
  int comm_num_values;
  int mat_num_values;
  int constant_coefficient;
  int stencil_size;
  hypre_StructStencil* stencil;
  hypre_CommInfo* comm_info;
  hypre_CommPkg* comm_pkg;
  hypre_CommHandle* comm_handle;
  int data_initial_offset = 0;
  double* matrix_data = (matrix)->data;
  double* matrix_data_comm = matrix_data;
  int sum_OffProcAdd;
  int OffProcAdd = (matrix)->OffProcAdd;
  hypre_Box* data_box;
  hypre_Box* box;
  hypre_Index loop_size;
  hypre_IndexRef start;
  hypre_Index unit_stride;
  int i;
  int j;
  int loopi;
  int loopj;
  int loopk;
  sum_OffProcAdd = 0;
  MPI_Allreduce(&(OffProcAdd), &(sum_OffProcAdd), 1, MPI_INT, _SUM, (matrix)->comm);
  constant_coefficient = (matrix)->constant_coefficient;
  mat_num_values = (matrix)->num_values;
  if (constant_coefficient == 0) {
    comm_num_values = mat_num_values;
  }
  else
    if (constant_coefficient == 1) {
      comm_num_values = 0;
    }
    else {
      comm_num_values = 1;
      stencil = (matrix)->stencil;
      stencil_size = (stencil)->size;
      data_initial_offset = stencil_size;
      matrix_data_comm = &(matrix_data[data_initial_offset]);
    }
  comm_pkg = (matrix)->comm_pkg;
  if (!comm_pkg) {
    hypre_CreateCommInfoFromNumGhost((matrix)->grid, num_ghost, &(comm_info));
    hypre_CommPkgCreate(comm_info, (matrix)->data_space, (matrix)->data_space, comm_num_values, (matrix)->comm, &(comm_pkg));
    (matrix)->comm_pkg = comm_pkg;
    if (sum_OffProcAdd) {
      hypre_CommInfo* add_comm_info;
      hypre_CommInfo* inv_comm_info;
      hypre_CommPkg* inv_comm_pkg;
      int* add_num_ghost = (matrix)->add_num_ghost;
      hypre_BoxArrayArray* send_boxes;
      hypre_BoxArrayArray* recv_boxes;
      int** send_procs;
      int** recv_procs;
      int** send_rboxnums;
      int** recv_rboxnums;
      hypre_BoxArrayArray* send_rboxes;
      hypre_BoxArray* box_array;
      hypre_BoxArray* recv_array;
      double* data;
      hypre_CommHandle* inv_comm_handle;
      double* data_matrix;
      double* comm_data;
      int center_rank;
      int s;
      int xi;
      hypre_CreateCommInfoFromNumGhost((matrix)->grid, add_num_ghost, &(add_comm_info));
      send_boxes = hypre_BoxArrayArrayDuplicate((add_comm_info)->recv_boxes);
      recv_boxes = hypre_BoxArrayArrayDuplicate((add_comm_info)->send_boxes);
      send_rboxes = hypre_BoxArrayArrayDuplicate(send_boxes);
      send_procs = (int**)(hypre_CAlloc((unsigned)((send_boxes)->size), (unsigned)(sizeof(int*))));
      recv_procs = (int**)(hypre_CAlloc((unsigned)((recv_boxes)->size), (unsigned)(sizeof(int*))));
      send_rboxnums = (int**)(hypre_CAlloc((unsigned)((send_boxes)->size), (unsigned)(sizeof(int*))));
      recv_rboxnums = (int**)(hypre_CAlloc((unsigned)((recv_boxes)->size), (unsigned)(sizeof(int*))));
      for (i = 0; i < (send_boxes)->size; i++) {
        box_array = (send_boxes)->box_arrays[i];
        send_procs[i] = (int*)(hypre_CAlloc((unsigned)((box_array)->size), (unsigned)(sizeof(int))));
        memcpy(send_procs[i], (add_comm_info)->recv_processes[i], (box_array)->size * sizeof(int));
        send_rboxnums[i] = (int*)(hypre_CAlloc((unsigned)((box_array)->size), (unsigned)(sizeof(int))));
        memcpy(send_rboxnums[i], (add_comm_info)->recv_rboxnums[i], (box_array)->size * sizeof(int));
      }
      for (i = 0; i < (recv_boxes)->size; i++) {
        box_array = (recv_boxes)->box_arrays[i];
        recv_procs[i] = (int*)(hypre_CAlloc((unsigned)((box_array)->size), (unsigned)(sizeof(int))));
        memcpy(recv_procs[i], (add_comm_info)->send_processes[i], (box_array)->size * sizeof(int));
        recv_rboxnums[i] = (int*)(hypre_CAlloc((unsigned)((box_array)->size), (unsigned)(sizeof(int))));
        memcpy(recv_rboxnums[i], (add_comm_info)->send_rboxnums[i], (box_array)->size * sizeof(int));
      }
      hypre_CommInfoCreate(send_boxes, recv_boxes, send_procs, recv_procs, send_rboxnums, recv_rboxnums, send_rboxes, &(inv_comm_info));
      hypre_CommPkgCreate(inv_comm_info, (matrix)->data_space, (matrix)->data_space, comm_num_values, (matrix)->comm, &(inv_comm_pkg));
      data = (double*)(hypre_CAlloc((unsigned)((matrix)->data_size), (unsigned)(sizeof(double))));
      hypre_InitializeCommunication(inv_comm_pkg, (matrix)->data, data, &(inv_comm_handle));
      hypre_FinalizeCommunication(inv_comm_handle);
      stencil = (matrix)->stencil;
      stencil_size = (stencil)->size;
      unit_stride[0] = 0, unit_stride[1] = 0, unit_stride[2] = 0;
      center_rank = hypre_StructStencilElementRank(stencil, unit_stride);
      unit_stride[0] = 1, unit_stride[1] = 1, unit_stride[2] = 1;
      box_array = ((matrix)->grid)->boxes;
      for (i = 0; i < (box_array)->size; i++) {
        recv_array = ((add_comm_info)->send_boxes)->box_arrays[i];
        data_box = &(((matrix)->data_space)->boxes[i]);
        for (s = 0; s < stencil_size; s++) {
          data_matrix = (matrix)->data + ((matrix)->data_indices[i][s]);
          comm_data = data + ((matrix)->data_indices[i][s]);
          for (j = 0; j < (recv_array)->size; j++) {
            box = &((recv_array)->boxes[j]);
            start = (box)->imin;
            hypre_BoxGetSize(box, loop_size);
            if (s != center_rank) {
              {
                int hypre__i1start = ((start[0]) - ((data_box)->imin[0])) + ((((start[1]) - ((data_box)->imin[1])) + (((start[2]) - ((data_box)->imin[2])) * (0 < ((((data_box)->imax[1]) - ((data_box)->imin[1])) + 1) ? (((data_box)->imax[1]) - ((data_box)->imin[1])) + 1 : 0))) * (0 < ((((data_box)->imax[0]) - ((data_box)->imin[0])) + 1) ? (((data_box)->imax[0]) - ((data_box)->imin[0])) + 1 : 0));
                int hypre__sx1 = unit_stride[0];
                int hypre__sy1 = (unit_stride[1]) * (0 < ((((data_box)->imax[0]) - ((data_box)->imin[0])) + 1) ? (((data_box)->imax[0]) - ((data_box)->imin[0])) + 1 : 0);
                int hypre__sz1 = ((unit_stride[2]) * (0 < ((((data_box)->imax[0]) - ((data_box)->imin[0])) + 1) ? (((data_box)->imax[0]) - ((data_box)->imin[0])) + 1 : 0)) * (0 < ((((data_box)->imax[1]) - ((data_box)->imin[1])) + 1) ? (((data_box)->imax[1]) - ((data_box)->imin[1])) + 1 : 0);
                int hypre__nx = loop_size[0];
                int hypre__ny = loop_size[1];
                int hypre__nz = loop_size[2];
                int hypre__mx = hypre__nx;
                int hypre__my = hypre__ny;
                int hypre__mz = hypre__nz;
                int hypre__dir;
                int hypre__max;
                int hypre__div;
                int hypre__mod;
                int hypre__block;
                int hypre__num_blocks;
                hypre__dir = 0;
                hypre__max = hypre__nx;
                if (hypre__ny > hypre__max) {
                  hypre__dir = 1;
                  hypre__max = hypre__ny;
                }
                if (hypre__nz > hypre__max) {
                  hypre__dir = 2;
                  hypre__max = hypre__nz;
                }
                hypre__num_blocks = 1;
                if (hypre__max < hypre__num_blocks) {
                  hypre__num_blocks = hypre__max;
                }
                if (hypre__num_blocks > 0) {
                  hypre__div = hypre__max / hypre__num_blocks;
                  hypre__mod = hypre__max % hypre__num_blocks;
                }
                ;
                for (hypre__block = 0; hypre__block < hypre__num_blocks; hypre__block++) {
                  loopi = 0;
                  loopj = 0;
                  loopk = 0;
                  hypre__nx = hypre__mx;
                  hypre__ny = hypre__my;
                  hypre__nz = hypre__mz;
                  if (hypre__num_blocks > 1) {
                    if (hypre__dir == 0) {
                      loopi = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                      hypre__nx = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                    }
                    else
                      if (hypre__dir == 1) {
                        loopj = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                        hypre__ny = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                      }
                      else
                        if (hypre__dir == 2) {
                          loopk = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                          hypre__nz = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                        }
                  }
                  ;
                  xi = ((hypre__i1start + (loopi * hypre__sx1)) + (loopj * hypre__sy1)) + (loopk * hypre__sz1);
                  for (loopk = 0; loopk < hypre__nz; loopk++) {
                    for (loopj = 0; loopj < hypre__ny; loopj++) {
                      for (loopi = 0; loopi < hypre__nx; loopi++) {
                        {
                          data_matrix[xi] += comm_data[xi];
                        }
                        xi += hypre__sx1;
                      }
                      xi += hypre__sy1 - (hypre__nx * hypre__sx1);
                    }
                    xi += hypre__sz1 - (hypre__ny * hypre__sy1);
                  }
                }
              }
              ;
            }
            else {
              {
                int hypre__i1start = ((start[0]) - ((data_box)->imin[0])) + ((((start[1]) - ((data_box)->imin[1])) + (((start[2]) - ((data_box)->imin[2])) * (0 < ((((data_box)->imax[1]) - ((data_box)->imin[1])) + 1) ? (((data_box)->imax[1]) - ((data_box)->imin[1])) + 1 : 0))) * (0 < ((((data_box)->imax[0]) - ((data_box)->imin[0])) + 1) ? (((data_box)->imax[0]) - ((data_box)->imin[0])) + 1 : 0));
                int hypre__sx1 = unit_stride[0];
                int hypre__sy1 = (unit_stride[1]) * (0 < ((((data_box)->imax[0]) - ((data_box)->imin[0])) + 1) ? (((data_box)->imax[0]) - ((data_box)->imin[0])) + 1 : 0);
                int hypre__sz1 = ((unit_stride[2]) * (0 < ((((data_box)->imax[0]) - ((data_box)->imin[0])) + 1) ? (((data_box)->imax[0]) - ((data_box)->imin[0])) + 1 : 0)) * (0 < ((((data_box)->imax[1]) - ((data_box)->imin[1])) + 1) ? (((data_box)->imax[1]) - ((data_box)->imin[1])) + 1 : 0);
                int hypre__nx = loop_size[0];
                int hypre__ny = loop_size[1];
                int hypre__nz = loop_size[2];
                int hypre__mx = hypre__nx;
                int hypre__my = hypre__ny;
                int hypre__mz = hypre__nz;
                int hypre__dir;
                int hypre__max;
                int hypre__div;
                int hypre__mod;
                int hypre__block;
                int hypre__num_blocks;
                hypre__dir = 0;
                hypre__max = hypre__nx;
                if (hypre__ny > hypre__max) {
                  hypre__dir = 1;
                  hypre__max = hypre__ny;
                }
                if (hypre__nz > hypre__max) {
                  hypre__dir = 2;
                  hypre__max = hypre__nz;
                }
                hypre__num_blocks = 1;
                if (hypre__max < hypre__num_blocks) {
                  hypre__num_blocks = hypre__max;
                }
                if (hypre__num_blocks > 0) {
                  hypre__div = hypre__max / hypre__num_blocks;
                  hypre__mod = hypre__max % hypre__num_blocks;
                }
                ;
                for (hypre__block = 0; hypre__block < hypre__num_blocks; hypre__block++) {
                  loopi = 0;
                  loopj = 0;
                  loopk = 0;
                  hypre__nx = hypre__mx;
                  hypre__ny = hypre__my;
                  hypre__nz = hypre__mz;
                  if (hypre__num_blocks > 1) {
                    if (hypre__dir == 0) {
                      loopi = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                      hypre__nx = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                    }
                    else
                      if (hypre__dir == 1) {
                        loopj = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                        hypre__ny = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                      }
                      else
                        if (hypre__dir == 2) {
                          loopk = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                          hypre__nz = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                        }
                  }
                  ;
                  xi = ((hypre__i1start + (loopi * hypre__sx1)) + (loopj * hypre__sy1)) + (loopk * hypre__sz1);
                  for (loopk = 0; loopk < hypre__nz; loopk++) {
                    for (loopj = 0; loopj < hypre__ny; loopj++) {
                      for (loopi = 0; loopi < hypre__nx; loopi++) {
                        {
                          if ((comm_data[xi]) != 1.0) {
                            data_matrix[xi] += comm_data[xi];
                          }
                        }
                        xi += hypre__sx1;
                      }
                      xi += hypre__sy1 - (hypre__nx * hypre__sx1);
                    }
                    xi += hypre__sz1 - (hypre__ny * hypre__sy1);
                  }
                }
              }
              ;
            }
          }
        }
      }
      hypre_Free((char*)data), data = (void*)0;
      hypre_CommPkgDestroy(inv_comm_pkg);
      hypre_CommInfoDestroy(add_comm_info);
    }
  }
  if (constant_coefficient != 1) {
    hypre_InitializeCommunication(comm_pkg, matrix_data_comm, matrix_data_comm, &(comm_handle));
    hypre_FinalizeCommunication(comm_handle);
  }
  return ierr;
}
int hypre_StructMatrixSetNumGhost(hypre_StructMatrix* matrix, int* num_ghost) {
  int ierr = 0;
  int i;
  for (i = 0; i < 6; i++)
    (matrix)->num_ghost[i] = num_ghost[i];
  return ierr;
}
int hypre_StructMatrixPrint(char* filename, hypre_StructMatrix* matrix, int all) {
  int ierr = 0;
  FILE* file;
  char  new_filename[255];
  hypre_StructGrid* grid;
  hypre_BoxArray* boxes;
  hypre_StructStencil* stencil;
  hypre_Index* stencil_shape;
  int stencil_size;
  hypre_Index center_index;
  int num_values;
  hypre_BoxArray* data_space;
  int* symm_elements;
  int i;
  int j;
  int constant_coefficient;
  int center_rank;
  int myid;
  constant_coefficient = (matrix)->constant_coefficient;
  MPI_Comm_rank((matrix)->comm, &(myid));
  sprintf(new_filename, "%s.%05d", filename, myid);
  if ((file = fopen(new_filename, "w")) == (void*)0) {
    printf("Error: can't open output file %s\n", new_filename);
    exit(1);
  }
  fprintf(file, "StructMatrix\n");
  fprintf(file, "\nSymmetric: %d\n", (matrix)->symmetric);
  fprintf(file, "\nConstantCoefficient: %d\n", (matrix)->constant_coefficient);
  fprintf(file, "\nGrid:\n");
  grid = (matrix)->grid;
  hypre_StructGridPrint(file, grid);
  fprintf(file, "\nStencil:\n");
  stencil = (matrix)->stencil;
  stencil_shape = (stencil)->shape;
  num_values = (matrix)->num_values;
  symm_elements = (matrix)->symm_elements;
  fprintf(file, "%d\n", num_values);
  stencil_size = (stencil)->size;
  j = 0;
  for (i = 0; i < stencil_size; i++) {
    if ((symm_elements[i]) < 0) {
      fprintf(file, "%d: %d %d %d\n", j++, stencil_shape[i][0], stencil_shape[i][1], stencil_shape[i][2]);
    }
  }
  data_space = (matrix)->data_space;
  if (all)
    boxes = data_space;
  else
    boxes = (grid)->boxes;
  fprintf(file, "\nData:\n");
  if (constant_coefficient == 1) {
    hypre_PrintCCBoxArrayData(file, boxes, data_space, num_values, (matrix)->data);
  }
  else
    if (constant_coefficient == 2) {
      center_index[0] = 0, center_index[1] = 0, center_index[2] = 0;
      center_rank = hypre_StructStencilElementRank(stencil, center_index);
      hypre_PrintCCVDBoxArrayData(file, boxes, data_space, num_values, center_rank, stencil_size, symm_elements, (matrix)->data);
    }
    else {
      hypre_PrintBoxArrayData(file, boxes, data_space, num_values, (matrix)->data);
    }
  fflush(file);
  fclose(file);
  return ierr;
}
//===================== struct_matvec.c ====================
typedef struct $anon_struct_11$TU102{
  hypre_StructMatrix* A;
  hypre_StructVector* x;
  hypre_ComputePkg* compute_pkg;
} hypre_StructMatvecData;
void* hypre_StructMatvecCreate() {
  hypre_StructMatvecData* matvec_data;
  matvec_data = (hypre_StructMatvecData*)(hypre_CAlloc((unsigned)1, (unsigned)(sizeof(hypre_StructMatvecData))));
  return (void*)matvec_data;
}
int hypre_StructMatvecSetup(void* matvec_vdata, hypre_StructMatrix* A, hypre_StructVector* x) {
  int ierr = 0;
  hypre_StructMatvecData* matvec_data = matvec_vdata;
  hypre_StructGrid* grid;
  hypre_StructStencil* stencil;
  hypre_ComputeInfo* compute_info;
  hypre_ComputePkg* compute_pkg;
  grid = (A)->grid;
  stencil = (A)->stencil;
  hypre_CreateComputeInfo(grid, stencil, &(compute_info));
  hypre_ComputePkgCreate(compute_info, (x)->data_space, 1, grid, &(compute_pkg));
  (matvec_data)->A = hypre_StructMatrixRef(A);
  (matvec_data)->x = hypre_StructVectorRef(x);
  (matvec_data)->compute_pkg = compute_pkg;
  return ierr;
}
int hypre_StructMatvecCompute(void* matvec_vdata, double alpha, hypre_StructMatrix* A, hypre_StructVector* x, double beta, hypre_StructVector* y) {
  int ierr = 0;
  hypre_StructMatvecData* matvec_data = matvec_vdata;
  hypre_ComputePkg* compute_pkg;
  hypre_CommHandle* comm_handle;
  hypre_BoxArrayArray* compute_box_aa;
  hypre_Box* y_data_box;
  int yi;
  double* xp;
  double* yp;
  hypre_BoxArray* boxes;
  hypre_Box* box;
  hypre_Index loop_size;
  hypre_IndexRef start;
  hypre_IndexRef stride;
  int constant_coefficient;
  double temp;
  int compute_i;
  int i;
  int loopi;
  int loopj;
  int loopk;
  constant_coefficient = (A)->constant_coefficient;
  if (constant_coefficient == 1)
    hypre_StructVectorClearBoundGhostValues(x);
  compute_pkg = (matvec_data)->compute_pkg;
  stride = (compute_pkg)->stride;
  if (alpha == 0.0) {
    boxes = ((A)->grid)->boxes;
    for (i = 0; i < (boxes)->size; i++) {
      box = &((boxes)->boxes[i]);
      start = (box)->imin;
      y_data_box = &(((y)->data_space)->boxes[i]);
      yp = (y)->data + ((y)->data_indices[i]);
      hypre_BoxGetSize(box, loop_size);
      {
        int hypre__i1start = ((start[0]) - ((y_data_box)->imin[0])) + ((((start[1]) - ((y_data_box)->imin[1])) + (((start[2]) - ((y_data_box)->imin[2])) * (0 < ((((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1) ? (((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1 : 0))) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0));
        int hypre__sx1 = stride[0];
        int hypre__sy1 = (stride[1]) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0);
        int hypre__sz1 = ((stride[2]) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0)) * (0 < ((((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1) ? (((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1 : 0);
        int hypre__nx = loop_size[0];
        int hypre__ny = loop_size[1];
        int hypre__nz = loop_size[2];
        int hypre__mx = hypre__nx;
        int hypre__my = hypre__ny;
        int hypre__mz = hypre__nz;
        int hypre__dir;
        int hypre__max;
        int hypre__div;
        int hypre__mod;
        int hypre__block;
        int hypre__num_blocks;
        hypre__dir = 0;
        hypre__max = hypre__nx;
        if (hypre__ny > hypre__max) {
          hypre__dir = 1;
          hypre__max = hypre__ny;
        }
        if (hypre__nz > hypre__max) {
          hypre__dir = 2;
          hypre__max = hypre__nz;
        }
        hypre__num_blocks = 1;
        if (hypre__max < hypre__num_blocks) {
          hypre__num_blocks = hypre__max;
        }
        if (hypre__num_blocks > 0) {
          hypre__div = hypre__max / hypre__num_blocks;
          hypre__mod = hypre__max % hypre__num_blocks;
        }
        ;
        ;
        for (hypre__block = 0; hypre__block < hypre__num_blocks; hypre__block++) {
          loopi = 0;
          loopj = 0;
          loopk = 0;
          hypre__nx = hypre__mx;
          hypre__ny = hypre__my;
          hypre__nz = hypre__mz;
          if (hypre__num_blocks > 1) {
            if (hypre__dir == 0) {
              loopi = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
              hypre__nx = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
            }
            else
              if (hypre__dir == 1) {
                loopj = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                hypre__ny = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
              }
              else
                if (hypre__dir == 2) {
                  loopk = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                  hypre__nz = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                }
          }
          ;
          yi = ((hypre__i1start + (loopi * hypre__sx1)) + (loopj * hypre__sy1)) + (loopk * hypre__sz1);
          for (loopk = 0; loopk < hypre__nz; loopk++) {
            for (loopj = 0; loopj < hypre__ny; loopj++) {
              for (loopi = 0; loopi < hypre__nx; loopi++) {
                {
                  (yp[yi]) -= beta;
                }
                yi += hypre__sx1;
              }
              yi += hypre__sy1 - (hypre__nx * hypre__sx1);
            }
            yi += hypre__sz1 - (hypre__ny * hypre__sy1);
          }
        }
      }
      ;
    }
    return ierr;
  }
  for (compute_i = 0; compute_i < 2; compute_i++) {
    switch (compute_i) {
      case 0:
{
        xp = (x)->data;
        hypre_InitializeIndtComputations(compute_pkg, xp, &(comm_handle));
        compute_box_aa = (compute_pkg)->indt_boxes;
        if (constant_coefficient == 1) {
          temp = beta;
        }
        else {
          temp = beta / alpha;
        }
        if (temp != 1.0) {
          boxes = ((A)->grid)->boxes;
          for (i = 0; i < (boxes)->size; i++) {
            box = &((boxes)->boxes[i]);
            start = (box)->imin;
            y_data_box = &(((y)->data_space)->boxes[i]);
            yp = (y)->data + ((y)->data_indices[i]);
            if (temp == 0.0) {
              hypre_BoxGetSize(box, loop_size);
              {
                int hypre__i1start = ((start[0]) - ((y_data_box)->imin[0])) + ((((start[1]) - ((y_data_box)->imin[1])) + (((start[2]) - ((y_data_box)->imin[2])) * (0 < ((((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1) ? (((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1 : 0))) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0));
                int hypre__sx1 = stride[0];
                int hypre__sy1 = (stride[1]) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0);
                int hypre__sz1 = ((stride[2]) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0)) * (0 < ((((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1) ? (((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1 : 0);
                int hypre__nx = loop_size[0];
                int hypre__ny = loop_size[1];
                int hypre__nz = loop_size[2];
                int hypre__mx = hypre__nx;
                int hypre__my = hypre__ny;
                int hypre__mz = hypre__nz;
                int hypre__dir;
                int hypre__max;
                int hypre__div;
                int hypre__mod;
                int hypre__block;
                int hypre__num_blocks;
                hypre__dir = 0;
                hypre__max = hypre__nx;
                if (hypre__ny > hypre__max) {
                  hypre__dir = 1;
                  hypre__max = hypre__ny;
                }
                if (hypre__nz > hypre__max) {
                  hypre__dir = 2;
                  hypre__max = hypre__nz;
                }
                hypre__num_blocks = 1;
                if (hypre__max < hypre__num_blocks) {
                  hypre__num_blocks = hypre__max;
                }
                if (hypre__num_blocks > 0) {
                  hypre__div = hypre__max / hypre__num_blocks;
                  hypre__mod = hypre__max % hypre__num_blocks;
                }
                ;
                ;
                for (hypre__block = 0; hypre__block < hypre__num_blocks; hypre__block++) {
                  loopi = 0;
                  loopj = 0;
                  loopk = 0;
                  hypre__nx = hypre__mx;
                  hypre__ny = hypre__my;
                  hypre__nz = hypre__mz;
                  if (hypre__num_blocks > 1) {
                    if (hypre__dir == 0) {
                      loopi = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                      hypre__nx = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                    }
                    else
                      if (hypre__dir == 1) {
                        loopj = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                        hypre__ny = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                      }
                      else
                        if (hypre__dir == 2) {
                          loopk = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                          hypre__nz = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                        }
                  }
                  ;
                  yi = ((hypre__i1start + (loopi * hypre__sx1)) + (loopj * hypre__sy1)) + (loopk * hypre__sz1);
                  for (loopk = 0; loopk < hypre__nz; loopk++) {
                    for (loopj = 0; loopj < hypre__ny; loopj++) {
                      for (loopi = 0; loopi < hypre__nx; loopi++) {
                        {
                          yp[yi] = 0.0;
                        }
                        yi += hypre__sx1;
                      }
                      yi += hypre__sy1 - (hypre__nx * hypre__sx1);
                    }
                    yi += hypre__sz1 - (hypre__ny * hypre__sy1);
                  }
                }
              }
              ;
            }
            else {
              hypre_BoxGetSize(box, loop_size);
              {
                int hypre__i1start = ((start[0]) - ((y_data_box)->imin[0])) + ((((start[1]) - ((y_data_box)->imin[1])) + (((start[2]) - ((y_data_box)->imin[2])) * (0 < ((((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1) ? (((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1 : 0))) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0));
                int hypre__sx1 = stride[0];
                int hypre__sy1 = (stride[1]) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0);
                int hypre__sz1 = ((stride[2]) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0)) * (0 < ((((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1) ? (((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1 : 0);
                int hypre__nx = loop_size[0];
                int hypre__ny = loop_size[1];
                int hypre__nz = loop_size[2];
                int hypre__mx = hypre__nx;
                int hypre__my = hypre__ny;
                int hypre__mz = hypre__nz;
                int hypre__dir;
                int hypre__max;
                int hypre__div;
                int hypre__mod;
                int hypre__block;
                int hypre__num_blocks;
                hypre__dir = 0;
                hypre__max = hypre__nx;
                if (hypre__ny > hypre__max) {
                  hypre__dir = 1;
                  hypre__max = hypre__ny;
                }
                if (hypre__nz > hypre__max) {
                  hypre__dir = 2;
                  hypre__max = hypre__nz;
                }
                hypre__num_blocks = 1;
                if (hypre__max < hypre__num_blocks) {
                  hypre__num_blocks = hypre__max;
                }
                if (hypre__num_blocks > 0) {
                  hypre__div = hypre__max / hypre__num_blocks;
                  hypre__mod = hypre__max % hypre__num_blocks;
                }
                ;
                ;
                for (hypre__block = 0; hypre__block < hypre__num_blocks; hypre__block++) {
                  loopi = 0;
                  loopj = 0;
                  loopk = 0;
                  hypre__nx = hypre__mx;
                  hypre__ny = hypre__my;
                  hypre__nz = hypre__mz;
                  if (hypre__num_blocks > 1) {
                    if (hypre__dir == 0) {
                      loopi = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                      hypre__nx = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                    }
                    else
                      if (hypre__dir == 1) {
                        loopj = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                        hypre__ny = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                      }
                      else
                        if (hypre__dir == 2) {
                          loopk = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                          hypre__nz = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                        }
                  }
                  ;
                  yi = ((hypre__i1start + (loopi * hypre__sx1)) + (loopj * hypre__sy1)) + (loopk * hypre__sz1);
                  for (loopk = 0; loopk < hypre__nz; loopk++) {
                    for (loopj = 0; loopj < hypre__ny; loopj++) {
                      for (loopi = 0; loopi < hypre__nx; loopi++) {
                        {
                          (yp[yi]) -= temp;
                        }
                        yi += hypre__sx1;
                      }
                      yi += hypre__sy1 - (hypre__nx * hypre__sx1);
                    }
                    yi += hypre__sz1 - (hypre__ny * hypre__sy1);
                  }
                }
              }
              ;
            }
          }
        }
      }
        break;
      case 1:
{
        hypre_FinalizeIndtComputations(comm_handle);
        compute_box_aa = (compute_pkg)->dept_boxes;
      }
        break;
    }
    switch (constant_coefficient) {
      case 0:
{
        ierr += hypre_StructMatvecCC0(alpha, A, x, y, compute_box_aa, stride);
        break;
      }
      case 1:
{
        ierr += hypre_StructMatvecCC1(alpha, A, x, y, compute_box_aa, stride);
        break;
      }
      case 2:
{
        ierr += hypre_StructMatvecCC2(alpha, A, x, y, compute_box_aa, stride);
        break;
      }
    }
  }
  return ierr;
}
int hypre_StructMatvecCC0(double alpha, hypre_StructMatrix* A, hypre_StructVector* x, hypre_StructVector* y, hypre_BoxArrayArray* compute_box_aa, hypre_IndexRef stride) {
  int i;
  int j;
  int si;
  int ierr = 0;
  double* Ap0;
  double* Ap1;
  double* Ap2;
  double* Ap3;
  double* Ap4;
  double* Ap5;
  double* Ap6;
  int xoff0;
  int xoff1;
  int xoff2;
  int xoff3;
  int xoff4;
  int xoff5;
  int xoff6;
  int Ai;
  int xi;
  hypre_BoxArray* compute_box_a;
  hypre_Box* compute_box;
  hypre_Box* A_data_box;
  hypre_Box* x_data_box;
  hypre_StructStencil* stencil;
  hypre_Index* stencil_shape;
  int stencil_size;
  hypre_Box* y_data_box;
  double* xp;
  double* yp;
  int depth;
  hypre_Index loop_size;
  int loopi;
  int loopj;
  int loopk;
  hypre_IndexRef start;
  int yi;
  stencil = (A)->stencil;
  stencil_shape = (stencil)->shape;
  stencil_size = (stencil)->size;
  for (i = 0; i < (compute_box_aa)->size; i++) {
    compute_box_a = (compute_box_aa)->box_arrays[i];
    A_data_box = &(((A)->data_space)->boxes[i]);
    x_data_box = &(((x)->data_space)->boxes[i]);
    y_data_box = &(((y)->data_space)->boxes[i]);
    xp = (x)->data + ((x)->data_indices[i]);
    yp = (y)->data + ((y)->data_indices[i]);
    for (j = 0; j < (compute_box_a)->size; j++) {
      compute_box = &((compute_box_a)->boxes[j]);
      hypre_BoxGetSize(compute_box, loop_size);
      start = (compute_box)->imin;
      for (si = 0; si < stencil_size; si += 7) {
        depth = 7 < (stencil_size - si) ? 7 : stencil_size - si;
        switch (depth) {
          case 7:
            Ap0 = (A)->data + ((A)->data_indices[i][si + 0]);
            Ap1 = (A)->data + ((A)->data_indices[i][si + 1]);
            Ap2 = (A)->data + ((A)->data_indices[i][si + 2]);
            Ap3 = (A)->data + ((A)->data_indices[i][si + 3]);
            Ap4 = (A)->data + ((A)->data_indices[i][si + 4]);
            Ap5 = (A)->data + ((A)->data_indices[i][si + 5]);
            Ap6 = (A)->data + ((A)->data_indices[i][si + 6]);
            xoff0 = (stencil_shape[si + 0][0]) + (((stencil_shape[si + 0][1]) + ((stencil_shape[si + 0][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            xoff1 = (stencil_shape[si + 1][0]) + (((stencil_shape[si + 1][1]) + ((stencil_shape[si + 1][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            xoff2 = (stencil_shape[si + 2][0]) + (((stencil_shape[si + 2][1]) + ((stencil_shape[si + 2][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            xoff3 = (stencil_shape[si + 3][0]) + (((stencil_shape[si + 3][1]) + ((stencil_shape[si + 3][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            xoff4 = (stencil_shape[si + 4][0]) + (((stencil_shape[si + 4][1]) + ((stencil_shape[si + 4][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            xoff5 = (stencil_shape[si + 5][0]) + (((stencil_shape[si + 5][1]) + ((stencil_shape[si + 5][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            xoff6 = (stencil_shape[si + 6][0]) + (((stencil_shape[si + 6][1]) + ((stencil_shape[si + 6][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            {
              int hypre__i1start = ((start[0]) - ((A_data_box)->imin[0])) + ((((start[1]) - ((A_data_box)->imin[1])) + (((start[2]) - ((A_data_box)->imin[2])) * (0 < ((((A_data_box)->imax[1]) - ((A_data_box)->imin[1])) + 1) ? (((A_data_box)->imax[1]) - ((A_data_box)->imin[1])) + 1 : 0))) * (0 < ((((A_data_box)->imax[0]) - ((A_data_box)->imin[0])) + 1) ? (((A_data_box)->imax[0]) - ((A_data_box)->imin[0])) + 1 : 0));
              int hypre__i2start = ((start[0]) - ((x_data_box)->imin[0])) + ((((start[1]) - ((x_data_box)->imin[1])) + (((start[2]) - ((x_data_box)->imin[2])) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
              int hypre__i3start = ((start[0]) - ((y_data_box)->imin[0])) + ((((start[1]) - ((y_data_box)->imin[1])) + (((start[2]) - ((y_data_box)->imin[2])) * (0 < ((((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1) ? (((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1 : 0))) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0));
              int hypre__sx1 = stride[0];
              int hypre__sy1 = (stride[1]) * (0 < ((((A_data_box)->imax[0]) - ((A_data_box)->imin[0])) + 1) ? (((A_data_box)->imax[0]) - ((A_data_box)->imin[0])) + 1 : 0);
              int hypre__sz1 = ((stride[2]) * (0 < ((((A_data_box)->imax[0]) - ((A_data_box)->imin[0])) + 1) ? (((A_data_box)->imax[0]) - ((A_data_box)->imin[0])) + 1 : 0)) * (0 < ((((A_data_box)->imax[1]) - ((A_data_box)->imin[1])) + 1) ? (((A_data_box)->imax[1]) - ((A_data_box)->imin[1])) + 1 : 0);
              int hypre__sx2 = stride[0];
              int hypre__sy2 = (stride[1]) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0);
              int hypre__sz2 = ((stride[2]) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0)) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0);
              int hypre__sx3 = stride[0];
              int hypre__sy3 = (stride[1]) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0);
              int hypre__sz3 = ((stride[2]) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0)) * (0 < ((((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1) ? (((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1 : 0);
              int hypre__nx = loop_size[0];
              int hypre__ny = loop_size[1];
              int hypre__nz = loop_size[2];
              int hypre__mx = hypre__nx;
              int hypre__my = hypre__ny;
              int hypre__mz = hypre__nz;
              int hypre__dir;
              int hypre__max;
              int hypre__div;
              int hypre__mod;
              int hypre__block;
              int hypre__num_blocks;
              hypre__dir = 0;
              hypre__max = hypre__nx;
              if (hypre__ny > hypre__max) {
                hypre__dir = 1;
                hypre__max = hypre__ny;
              }
              if (hypre__nz > hypre__max) {
                hypre__dir = 2;
                hypre__max = hypre__nz;
              }
              hypre__num_blocks = 1;
              if (hypre__max < hypre__num_blocks) {
                hypre__num_blocks = hypre__max;
              }
              if (hypre__num_blocks > 0) {
                hypre__div = hypre__max / hypre__num_blocks;
                hypre__mod = hypre__max % hypre__num_blocks;
              }
              ;
              ;
              for (hypre__block = 0; hypre__block < hypre__num_blocks; hypre__block++) {
                loopi = 0;
                loopj = 0;
                loopk = 0;
                hypre__nx = hypre__mx;
                hypre__ny = hypre__my;
                hypre__nz = hypre__mz;
                if (hypre__num_blocks > 1) {
                  if (hypre__dir == 0) {
                    loopi = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                    hypre__nx = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                  }
                  else
                    if (hypre__dir == 1) {
                      loopj = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                      hypre__ny = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                    }
                    else
                      if (hypre__dir == 2) {
                        loopk = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                        hypre__nz = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                      }
                }
                ;
                Ai = ((hypre__i1start + (loopi * hypre__sx1)) + (loopj * hypre__sy1)) + (loopk * hypre__sz1);
                xi = ((hypre__i2start + (loopi * hypre__sx2)) + (loopj * hypre__sy2)) + (loopk * hypre__sz2);
                yi = ((hypre__i3start + (loopi * hypre__sx3)) + (loopj * hypre__sy3)) + (loopk * hypre__sz3);
                for (loopk = 0; loopk < hypre__nz; loopk++) {
                  for (loopj = 0; loopj < hypre__ny; loopj++) {
                    for (loopi = 0; loopi < hypre__nx; loopi++) {
                      {
                        yp[yi] += (((((((Ap0[Ai]) * (xp[xi + xoff0])) + ((Ap1[Ai]) * (xp[xi + xoff1]))) + ((Ap2[Ai]) * (xp[xi + xoff2]))) + ((Ap3[Ai]) * (xp[xi + xoff3]))) + ((Ap4[Ai]) * (xp[xi + xoff4]))) + ((Ap5[Ai]) * (xp[xi + xoff5]))) + ((Ap6[Ai]) * (xp[xi + xoff6]));
                      }
                      Ai += hypre__sx1;
                      xi += hypre__sx2;
                      yi += hypre__sx3;
                    }
                    Ai += hypre__sy1 - (hypre__nx * hypre__sx1);
                    xi += hypre__sy2 - (hypre__nx * hypre__sx2);
                    yi += hypre__sy3 - (hypre__nx * hypre__sx3);
                  }
                  Ai += hypre__sz1 - (hypre__ny * hypre__sy1);
                  xi += hypre__sz2 - (hypre__ny * hypre__sy2);
                  yi += hypre__sz3 - (hypre__ny * hypre__sy3);
                }
              }
            }
            ;
            break;
          case 6:
            Ap0 = (A)->data + ((A)->data_indices[i][si + 0]);
            Ap1 = (A)->data + ((A)->data_indices[i][si + 1]);
            Ap2 = (A)->data + ((A)->data_indices[i][si + 2]);
            Ap3 = (A)->data + ((A)->data_indices[i][si + 3]);
            Ap4 = (A)->data + ((A)->data_indices[i][si + 4]);
            Ap5 = (A)->data + ((A)->data_indices[i][si + 5]);
            xoff0 = (stencil_shape[si + 0][0]) + (((stencil_shape[si + 0][1]) + ((stencil_shape[si + 0][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            xoff1 = (stencil_shape[si + 1][0]) + (((stencil_shape[si + 1][1]) + ((stencil_shape[si + 1][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            xoff2 = (stencil_shape[si + 2][0]) + (((stencil_shape[si + 2][1]) + ((stencil_shape[si + 2][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            xoff3 = (stencil_shape[si + 3][0]) + (((stencil_shape[si + 3][1]) + ((stencil_shape[si + 3][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            xoff4 = (stencil_shape[si + 4][0]) + (((stencil_shape[si + 4][1]) + ((stencil_shape[si + 4][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            xoff5 = (stencil_shape[si + 5][0]) + (((stencil_shape[si + 5][1]) + ((stencil_shape[si + 5][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            {
              int hypre__i1start = ((start[0]) - ((A_data_box)->imin[0])) + ((((start[1]) - ((A_data_box)->imin[1])) + (((start[2]) - ((A_data_box)->imin[2])) * (0 < ((((A_data_box)->imax[1]) - ((A_data_box)->imin[1])) + 1) ? (((A_data_box)->imax[1]) - ((A_data_box)->imin[1])) + 1 : 0))) * (0 < ((((A_data_box)->imax[0]) - ((A_data_box)->imin[0])) + 1) ? (((A_data_box)->imax[0]) - ((A_data_box)->imin[0])) + 1 : 0));
              int hypre__i2start = ((start[0]) - ((x_data_box)->imin[0])) + ((((start[1]) - ((x_data_box)->imin[1])) + (((start[2]) - ((x_data_box)->imin[2])) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
              int hypre__i3start = ((start[0]) - ((y_data_box)->imin[0])) + ((((start[1]) - ((y_data_box)->imin[1])) + (((start[2]) - ((y_data_box)->imin[2])) * (0 < ((((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1) ? (((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1 : 0))) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0));
              int hypre__sx1 = stride[0];
              int hypre__sy1 = (stride[1]) * (0 < ((((A_data_box)->imax[0]) - ((A_data_box)->imin[0])) + 1) ? (((A_data_box)->imax[0]) - ((A_data_box)->imin[0])) + 1 : 0);
              int hypre__sz1 = ((stride[2]) * (0 < ((((A_data_box)->imax[0]) - ((A_data_box)->imin[0])) + 1) ? (((A_data_box)->imax[0]) - ((A_data_box)->imin[0])) + 1 : 0)) * (0 < ((((A_data_box)->imax[1]) - ((A_data_box)->imin[1])) + 1) ? (((A_data_box)->imax[1]) - ((A_data_box)->imin[1])) + 1 : 0);
              int hypre__sx2 = stride[0];
              int hypre__sy2 = (stride[1]) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0);
              int hypre__sz2 = ((stride[2]) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0)) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0);
              int hypre__sx3 = stride[0];
              int hypre__sy3 = (stride[1]) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0);
              int hypre__sz3 = ((stride[2]) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0)) * (0 < ((((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1) ? (((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1 : 0);
              int hypre__nx = loop_size[0];
              int hypre__ny = loop_size[1];
              int hypre__nz = loop_size[2];
              int hypre__mx = hypre__nx;
              int hypre__my = hypre__ny;
              int hypre__mz = hypre__nz;
              int hypre__dir;
              int hypre__max;
              int hypre__div;
              int hypre__mod;
              int hypre__block;
              int hypre__num_blocks;
              hypre__dir = 0;
              hypre__max = hypre__nx;
              if (hypre__ny > hypre__max) {
                hypre__dir = 1;
                hypre__max = hypre__ny;
              }
              if (hypre__nz > hypre__max) {
                hypre__dir = 2;
                hypre__max = hypre__nz;
              }
              hypre__num_blocks = 1;
              if (hypre__max < hypre__num_blocks) {
                hypre__num_blocks = hypre__max;
              }
              if (hypre__num_blocks > 0) {
                hypre__div = hypre__max / hypre__num_blocks;
                hypre__mod = hypre__max % hypre__num_blocks;
              }
              ;
              ;
              for (hypre__block = 0; hypre__block < hypre__num_blocks; hypre__block++) {
                loopi = 0;
                loopj = 0;
                loopk = 0;
                hypre__nx = hypre__mx;
                hypre__ny = hypre__my;
                hypre__nz = hypre__mz;
                if (hypre__num_blocks > 1) {
                  if (hypre__dir == 0) {
                    loopi = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                    hypre__nx = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                  }
                  else
                    if (hypre__dir == 1) {
                      loopj = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                      hypre__ny = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                    }
                    else
                      if (hypre__dir == 2) {
                        loopk = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                        hypre__nz = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                      }
                }
                ;
                Ai = ((hypre__i1start + (loopi * hypre__sx1)) + (loopj * hypre__sy1)) + (loopk * hypre__sz1);
                xi = ((hypre__i2start + (loopi * hypre__sx2)) + (loopj * hypre__sy2)) + (loopk * hypre__sz2);
                yi = ((hypre__i3start + (loopi * hypre__sx3)) + (loopj * hypre__sy3)) + (loopk * hypre__sz3);
                for (loopk = 0; loopk < hypre__nz; loopk++) {
                  for (loopj = 0; loopj < hypre__ny; loopj++) {
                    for (loopi = 0; loopi < hypre__nx; loopi++) {
                      {
                        yp[yi] += ((((((Ap0[Ai]) * (xp[xi + xoff0])) + ((Ap1[Ai]) * (xp[xi + xoff1]))) + ((Ap2[Ai]) * (xp[xi + xoff2]))) + ((Ap3[Ai]) * (xp[xi + xoff3]))) + ((Ap4[Ai]) * (xp[xi + xoff4]))) + ((Ap5[Ai]) * (xp[xi + xoff5]));
                      }
                      Ai += hypre__sx1;
                      xi += hypre__sx2;
                      yi += hypre__sx3;
                    }
                    Ai += hypre__sy1 - (hypre__nx * hypre__sx1);
                    xi += hypre__sy2 - (hypre__nx * hypre__sx2);
                    yi += hypre__sy3 - (hypre__nx * hypre__sx3);
                  }
                  Ai += hypre__sz1 - (hypre__ny * hypre__sy1);
                  xi += hypre__sz2 - (hypre__ny * hypre__sy2);
                  yi += hypre__sz3 - (hypre__ny * hypre__sy3);
                }
              }
            }
            ;
            break;
          case 5:
            Ap0 = (A)->data + ((A)->data_indices[i][si + 0]);
            Ap1 = (A)->data + ((A)->data_indices[i][si + 1]);
            Ap2 = (A)->data + ((A)->data_indices[i][si + 2]);
            Ap3 = (A)->data + ((A)->data_indices[i][si + 3]);
            Ap4 = (A)->data + ((A)->data_indices[i][si + 4]);
            xoff0 = (stencil_shape[si + 0][0]) + (((stencil_shape[si + 0][1]) + ((stencil_shape[si + 0][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            xoff1 = (stencil_shape[si + 1][0]) + (((stencil_shape[si + 1][1]) + ((stencil_shape[si + 1][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            xoff2 = (stencil_shape[si + 2][0]) + (((stencil_shape[si + 2][1]) + ((stencil_shape[si + 2][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            xoff3 = (stencil_shape[si + 3][0]) + (((stencil_shape[si + 3][1]) + ((stencil_shape[si + 3][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            xoff4 = (stencil_shape[si + 4][0]) + (((stencil_shape[si + 4][1]) + ((stencil_shape[si + 4][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            {
              int hypre__i1start = ((start[0]) - ((A_data_box)->imin[0])) + ((((start[1]) - ((A_data_box)->imin[1])) + (((start[2]) - ((A_data_box)->imin[2])) * (0 < ((((A_data_box)->imax[1]) - ((A_data_box)->imin[1])) + 1) ? (((A_data_box)->imax[1]) - ((A_data_box)->imin[1])) + 1 : 0))) * (0 < ((((A_data_box)->imax[0]) - ((A_data_box)->imin[0])) + 1) ? (((A_data_box)->imax[0]) - ((A_data_box)->imin[0])) + 1 : 0));
              int hypre__i2start = ((start[0]) - ((x_data_box)->imin[0])) + ((((start[1]) - ((x_data_box)->imin[1])) + (((start[2]) - ((x_data_box)->imin[2])) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
              int hypre__i3start = ((start[0]) - ((y_data_box)->imin[0])) + ((((start[1]) - ((y_data_box)->imin[1])) + (((start[2]) - ((y_data_box)->imin[2])) * (0 < ((((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1) ? (((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1 : 0))) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0));
              int hypre__sx1 = stride[0];
              int hypre__sy1 = (stride[1]) * (0 < ((((A_data_box)->imax[0]) - ((A_data_box)->imin[0])) + 1) ? (((A_data_box)->imax[0]) - ((A_data_box)->imin[0])) + 1 : 0);
              int hypre__sz1 = ((stride[2]) * (0 < ((((A_data_box)->imax[0]) - ((A_data_box)->imin[0])) + 1) ? (((A_data_box)->imax[0]) - ((A_data_box)->imin[0])) + 1 : 0)) * (0 < ((((A_data_box)->imax[1]) - ((A_data_box)->imin[1])) + 1) ? (((A_data_box)->imax[1]) - ((A_data_box)->imin[1])) + 1 : 0);
              int hypre__sx2 = stride[0];
              int hypre__sy2 = (stride[1]) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0);
              int hypre__sz2 = ((stride[2]) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0)) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0);
              int hypre__sx3 = stride[0];
              int hypre__sy3 = (stride[1]) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0);
              int hypre__sz3 = ((stride[2]) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0)) * (0 < ((((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1) ? (((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1 : 0);
              int hypre__nx = loop_size[0];
              int hypre__ny = loop_size[1];
              int hypre__nz = loop_size[2];
              int hypre__mx = hypre__nx;
              int hypre__my = hypre__ny;
              int hypre__mz = hypre__nz;
              int hypre__dir;
              int hypre__max;
              int hypre__div;
              int hypre__mod;
              int hypre__block;
              int hypre__num_blocks;
              hypre__dir = 0;
              hypre__max = hypre__nx;
              if (hypre__ny > hypre__max) {
                hypre__dir = 1;
                hypre__max = hypre__ny;
              }
              if (hypre__nz > hypre__max) {
                hypre__dir = 2;
                hypre__max = hypre__nz;
              }
              hypre__num_blocks = 1;
              if (hypre__max < hypre__num_blocks) {
                hypre__num_blocks = hypre__max;
              }
              if (hypre__num_blocks > 0) {
                hypre__div = hypre__max / hypre__num_blocks;
                hypre__mod = hypre__max % hypre__num_blocks;
              }
              ;
              ;
              for (hypre__block = 0; hypre__block < hypre__num_blocks; hypre__block++) {
                loopi = 0;
                loopj = 0;
                loopk = 0;
                hypre__nx = hypre__mx;
                hypre__ny = hypre__my;
                hypre__nz = hypre__mz;
                if (hypre__num_blocks > 1) {
                  if (hypre__dir == 0) {
                    loopi = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                    hypre__nx = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                  }
                  else
                    if (hypre__dir == 1) {
                      loopj = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                      hypre__ny = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                    }
                    else
                      if (hypre__dir == 2) {
                        loopk = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                        hypre__nz = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                      }
                }
                ;
                Ai = ((hypre__i1start + (loopi * hypre__sx1)) + (loopj * hypre__sy1)) + (loopk * hypre__sz1);
                xi = ((hypre__i2start + (loopi * hypre__sx2)) + (loopj * hypre__sy2)) + (loopk * hypre__sz2);
                yi = ((hypre__i3start + (loopi * hypre__sx3)) + (loopj * hypre__sy3)) + (loopk * hypre__sz3);
                for (loopk = 0; loopk < hypre__nz; loopk++) {
                  for (loopj = 0; loopj < hypre__ny; loopj++) {
                    for (loopi = 0; loopi < hypre__nx; loopi++) {
                      {
                        yp[yi] += (((((Ap0[Ai]) * (xp[xi + xoff0])) + ((Ap1[Ai]) * (xp[xi + xoff1]))) + ((Ap2[Ai]) * (xp[xi + xoff2]))) + ((Ap3[Ai]) * (xp[xi + xoff3]))) + ((Ap4[Ai]) * (xp[xi + xoff4]));
                      }
                      Ai += hypre__sx1;
                      xi += hypre__sx2;
                      yi += hypre__sx3;
                    }
                    Ai += hypre__sy1 - (hypre__nx * hypre__sx1);
                    xi += hypre__sy2 - (hypre__nx * hypre__sx2);
                    yi += hypre__sy3 - (hypre__nx * hypre__sx3);
                  }
                  Ai += hypre__sz1 - (hypre__ny * hypre__sy1);
                  xi += hypre__sz2 - (hypre__ny * hypre__sy2);
                  yi += hypre__sz3 - (hypre__ny * hypre__sy3);
                }
              }
            }
            ;
            break;
          case 4:
            Ap0 = (A)->data + ((A)->data_indices[i][si + 0]);
            Ap1 = (A)->data + ((A)->data_indices[i][si + 1]);
            Ap2 = (A)->data + ((A)->data_indices[i][si + 2]);
            Ap3 = (A)->data + ((A)->data_indices[i][si + 3]);
            xoff0 = (stencil_shape[si + 0][0]) + (((stencil_shape[si + 0][1]) + ((stencil_shape[si + 0][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            xoff1 = (stencil_shape[si + 1][0]) + (((stencil_shape[si + 1][1]) + ((stencil_shape[si + 1][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            xoff2 = (stencil_shape[si + 2][0]) + (((stencil_shape[si + 2][1]) + ((stencil_shape[si + 2][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            xoff3 = (stencil_shape[si + 3][0]) + (((stencil_shape[si + 3][1]) + ((stencil_shape[si + 3][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            {
              int hypre__i1start = ((start[0]) - ((A_data_box)->imin[0])) + ((((start[1]) - ((A_data_box)->imin[1])) + (((start[2]) - ((A_data_box)->imin[2])) * (0 < ((((A_data_box)->imax[1]) - ((A_data_box)->imin[1])) + 1) ? (((A_data_box)->imax[1]) - ((A_data_box)->imin[1])) + 1 : 0))) * (0 < ((((A_data_box)->imax[0]) - ((A_data_box)->imin[0])) + 1) ? (((A_data_box)->imax[0]) - ((A_data_box)->imin[0])) + 1 : 0));
              int hypre__i2start = ((start[0]) - ((x_data_box)->imin[0])) + ((((start[1]) - ((x_data_box)->imin[1])) + (((start[2]) - ((x_data_box)->imin[2])) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
              int hypre__i3start = ((start[0]) - ((y_data_box)->imin[0])) + ((((start[1]) - ((y_data_box)->imin[1])) + (((start[2]) - ((y_data_box)->imin[2])) * (0 < ((((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1) ? (((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1 : 0))) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0));
              int hypre__sx1 = stride[0];
              int hypre__sy1 = (stride[1]) * (0 < ((((A_data_box)->imax[0]) - ((A_data_box)->imin[0])) + 1) ? (((A_data_box)->imax[0]) - ((A_data_box)->imin[0])) + 1 : 0);
              int hypre__sz1 = ((stride[2]) * (0 < ((((A_data_box)->imax[0]) - ((A_data_box)->imin[0])) + 1) ? (((A_data_box)->imax[0]) - ((A_data_box)->imin[0])) + 1 : 0)) * (0 < ((((A_data_box)->imax[1]) - ((A_data_box)->imin[1])) + 1) ? (((A_data_box)->imax[1]) - ((A_data_box)->imin[1])) + 1 : 0);
              int hypre__sx2 = stride[0];
              int hypre__sy2 = (stride[1]) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0);
              int hypre__sz2 = ((stride[2]) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0)) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0);
              int hypre__sx3 = stride[0];
              int hypre__sy3 = (stride[1]) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0);
              int hypre__sz3 = ((stride[2]) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0)) * (0 < ((((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1) ? (((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1 : 0);
              int hypre__nx = loop_size[0];
              int hypre__ny = loop_size[1];
              int hypre__nz = loop_size[2];
              int hypre__mx = hypre__nx;
              int hypre__my = hypre__ny;
              int hypre__mz = hypre__nz;
              int hypre__dir;
              int hypre__max;
              int hypre__div;
              int hypre__mod;
              int hypre__block;
              int hypre__num_blocks;
              hypre__dir = 0;
              hypre__max = hypre__nx;
              if (hypre__ny > hypre__max) {
                hypre__dir = 1;
                hypre__max = hypre__ny;
              }
              if (hypre__nz > hypre__max) {
                hypre__dir = 2;
                hypre__max = hypre__nz;
              }
              hypre__num_blocks = 1;
              if (hypre__max < hypre__num_blocks) {
                hypre__num_blocks = hypre__max;
              }
              if (hypre__num_blocks > 0) {
                hypre__div = hypre__max / hypre__num_blocks;
                hypre__mod = hypre__max % hypre__num_blocks;
              }
              ;
              ;
              for (hypre__block = 0; hypre__block < hypre__num_blocks; hypre__block++) {
                loopi = 0;
                loopj = 0;
                loopk = 0;
                hypre__nx = hypre__mx;
                hypre__ny = hypre__my;
                hypre__nz = hypre__mz;
                if (hypre__num_blocks > 1) {
                  if (hypre__dir == 0) {
                    loopi = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                    hypre__nx = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                  }
                  else
                    if (hypre__dir == 1) {
                      loopj = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                      hypre__ny = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                    }
                    else
                      if (hypre__dir == 2) {
                        loopk = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                        hypre__nz = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                      }
                }
                ;
                Ai = ((hypre__i1start + (loopi * hypre__sx1)) + (loopj * hypre__sy1)) + (loopk * hypre__sz1);
                xi = ((hypre__i2start + (loopi * hypre__sx2)) + (loopj * hypre__sy2)) + (loopk * hypre__sz2);
                yi = ((hypre__i3start + (loopi * hypre__sx3)) + (loopj * hypre__sy3)) + (loopk * hypre__sz3);
                for (loopk = 0; loopk < hypre__nz; loopk++) {
                  for (loopj = 0; loopj < hypre__ny; loopj++) {
                    for (loopi = 0; loopi < hypre__nx; loopi++) {
                      {
                        yp[yi] += ((((Ap0[Ai]) * (xp[xi + xoff0])) + ((Ap1[Ai]) * (xp[xi + xoff1]))) + ((Ap2[Ai]) * (xp[xi + xoff2]))) + ((Ap3[Ai]) * (xp[xi + xoff3]));
                      }
                      Ai += hypre__sx1;
                      xi += hypre__sx2;
                      yi += hypre__sx3;
                    }
                    Ai += hypre__sy1 - (hypre__nx * hypre__sx1);
                    xi += hypre__sy2 - (hypre__nx * hypre__sx2);
                    yi += hypre__sy3 - (hypre__nx * hypre__sx3);
                  }
                  Ai += hypre__sz1 - (hypre__ny * hypre__sy1);
                  xi += hypre__sz2 - (hypre__ny * hypre__sy2);
                  yi += hypre__sz3 - (hypre__ny * hypre__sy3);
                }
              }
            }
            ;
            break;
          case 3:
            Ap0 = (A)->data + ((A)->data_indices[i][si + 0]);
            Ap1 = (A)->data + ((A)->data_indices[i][si + 1]);
            Ap2 = (A)->data + ((A)->data_indices[i][si + 2]);
            xoff0 = (stencil_shape[si + 0][0]) + (((stencil_shape[si + 0][1]) + ((stencil_shape[si + 0][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            xoff1 = (stencil_shape[si + 1][0]) + (((stencil_shape[si + 1][1]) + ((stencil_shape[si + 1][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            xoff2 = (stencil_shape[si + 2][0]) + (((stencil_shape[si + 2][1]) + ((stencil_shape[si + 2][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            {
              int hypre__i1start = ((start[0]) - ((A_data_box)->imin[0])) + ((((start[1]) - ((A_data_box)->imin[1])) + (((start[2]) - ((A_data_box)->imin[2])) * (0 < ((((A_data_box)->imax[1]) - ((A_data_box)->imin[1])) + 1) ? (((A_data_box)->imax[1]) - ((A_data_box)->imin[1])) + 1 : 0))) * (0 < ((((A_data_box)->imax[0]) - ((A_data_box)->imin[0])) + 1) ? (((A_data_box)->imax[0]) - ((A_data_box)->imin[0])) + 1 : 0));
              int hypre__i2start = ((start[0]) - ((x_data_box)->imin[0])) + ((((start[1]) - ((x_data_box)->imin[1])) + (((start[2]) - ((x_data_box)->imin[2])) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
              int hypre__i3start = ((start[0]) - ((y_data_box)->imin[0])) + ((((start[1]) - ((y_data_box)->imin[1])) + (((start[2]) - ((y_data_box)->imin[2])) * (0 < ((((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1) ? (((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1 : 0))) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0));
              int hypre__sx1 = stride[0];
              int hypre__sy1 = (stride[1]) * (0 < ((((A_data_box)->imax[0]) - ((A_data_box)->imin[0])) + 1) ? (((A_data_box)->imax[0]) - ((A_data_box)->imin[0])) + 1 : 0);
              int hypre__sz1 = ((stride[2]) * (0 < ((((A_data_box)->imax[0]) - ((A_data_box)->imin[0])) + 1) ? (((A_data_box)->imax[0]) - ((A_data_box)->imin[0])) + 1 : 0)) * (0 < ((((A_data_box)->imax[1]) - ((A_data_box)->imin[1])) + 1) ? (((A_data_box)->imax[1]) - ((A_data_box)->imin[1])) + 1 : 0);
              int hypre__sx2 = stride[0];
              int hypre__sy2 = (stride[1]) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0);
              int hypre__sz2 = ((stride[2]) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0)) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0);
              int hypre__sx3 = stride[0];
              int hypre__sy3 = (stride[1]) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0);
              int hypre__sz3 = ((stride[2]) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0)) * (0 < ((((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1) ? (((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1 : 0);
              int hypre__nx = loop_size[0];
              int hypre__ny = loop_size[1];
              int hypre__nz = loop_size[2];
              int hypre__mx = hypre__nx;
              int hypre__my = hypre__ny;
              int hypre__mz = hypre__nz;
              int hypre__dir;
              int hypre__max;
              int hypre__div;
              int hypre__mod;
              int hypre__block;
              int hypre__num_blocks;
              hypre__dir = 0;
              hypre__max = hypre__nx;
              if (hypre__ny > hypre__max) {
                hypre__dir = 1;
                hypre__max = hypre__ny;
              }
              if (hypre__nz > hypre__max) {
                hypre__dir = 2;
                hypre__max = hypre__nz;
              }
              hypre__num_blocks = 1;
              if (hypre__max < hypre__num_blocks) {
                hypre__num_blocks = hypre__max;
              }
              if (hypre__num_blocks > 0) {
                hypre__div = hypre__max / hypre__num_blocks;
                hypre__mod = hypre__max % hypre__num_blocks;
              }
              ;
              ;
              for (hypre__block = 0; hypre__block < hypre__num_blocks; hypre__block++) {
                loopi = 0;
                loopj = 0;
                loopk = 0;
                hypre__nx = hypre__mx;
                hypre__ny = hypre__my;
                hypre__nz = hypre__mz;
                if (hypre__num_blocks > 1) {
                  if (hypre__dir == 0) {
                    loopi = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                    hypre__nx = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                  }
                  else
                    if (hypre__dir == 1) {
                      loopj = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                      hypre__ny = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                    }
                    else
                      if (hypre__dir == 2) {
                        loopk = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                        hypre__nz = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                      }
                }
                ;
                Ai = ((hypre__i1start + (loopi * hypre__sx1)) + (loopj * hypre__sy1)) + (loopk * hypre__sz1);
                xi = ((hypre__i2start + (loopi * hypre__sx2)) + (loopj * hypre__sy2)) + (loopk * hypre__sz2);
                yi = ((hypre__i3start + (loopi * hypre__sx3)) + (loopj * hypre__sy3)) + (loopk * hypre__sz3);
                for (loopk = 0; loopk < hypre__nz; loopk++) {
                  for (loopj = 0; loopj < hypre__ny; loopj++) {
                    for (loopi = 0; loopi < hypre__nx; loopi++) {
                      {
                        yp[yi] += (((Ap0[Ai]) * (xp[xi + xoff0])) + ((Ap1[Ai]) * (xp[xi + xoff1]))) + ((Ap2[Ai]) * (xp[xi + xoff2]));
                      }
                      Ai += hypre__sx1;
                      xi += hypre__sx2;
                      yi += hypre__sx3;
                    }
                    Ai += hypre__sy1 - (hypre__nx * hypre__sx1);
                    xi += hypre__sy2 - (hypre__nx * hypre__sx2);
                    yi += hypre__sy3 - (hypre__nx * hypre__sx3);
                  }
                  Ai += hypre__sz1 - (hypre__ny * hypre__sy1);
                  xi += hypre__sz2 - (hypre__ny * hypre__sy2);
                  yi += hypre__sz3 - (hypre__ny * hypre__sy3);
                }
              }
            }
            ;
            break;
          case 2:
            Ap0 = (A)->data + ((A)->data_indices[i][si + 0]);
            Ap1 = (A)->data + ((A)->data_indices[i][si + 1]);
            xoff0 = (stencil_shape[si + 0][0]) + (((stencil_shape[si + 0][1]) + ((stencil_shape[si + 0][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            xoff1 = (stencil_shape[si + 1][0]) + (((stencil_shape[si + 1][1]) + ((stencil_shape[si + 1][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            {
              int hypre__i1start = ((start[0]) - ((A_data_box)->imin[0])) + ((((start[1]) - ((A_data_box)->imin[1])) + (((start[2]) - ((A_data_box)->imin[2])) * (0 < ((((A_data_box)->imax[1]) - ((A_data_box)->imin[1])) + 1) ? (((A_data_box)->imax[1]) - ((A_data_box)->imin[1])) + 1 : 0))) * (0 < ((((A_data_box)->imax[0]) - ((A_data_box)->imin[0])) + 1) ? (((A_data_box)->imax[0]) - ((A_data_box)->imin[0])) + 1 : 0));
              int hypre__i2start = ((start[0]) - ((x_data_box)->imin[0])) + ((((start[1]) - ((x_data_box)->imin[1])) + (((start[2]) - ((x_data_box)->imin[2])) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
              int hypre__i3start = ((start[0]) - ((y_data_box)->imin[0])) + ((((start[1]) - ((y_data_box)->imin[1])) + (((start[2]) - ((y_data_box)->imin[2])) * (0 < ((((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1) ? (((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1 : 0))) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0));
              int hypre__sx1 = stride[0];
              int hypre__sy1 = (stride[1]) * (0 < ((((A_data_box)->imax[0]) - ((A_data_box)->imin[0])) + 1) ? (((A_data_box)->imax[0]) - ((A_data_box)->imin[0])) + 1 : 0);
              int hypre__sz1 = ((stride[2]) * (0 < ((((A_data_box)->imax[0]) - ((A_data_box)->imin[0])) + 1) ? (((A_data_box)->imax[0]) - ((A_data_box)->imin[0])) + 1 : 0)) * (0 < ((((A_data_box)->imax[1]) - ((A_data_box)->imin[1])) + 1) ? (((A_data_box)->imax[1]) - ((A_data_box)->imin[1])) + 1 : 0);
              int hypre__sx2 = stride[0];
              int hypre__sy2 = (stride[1]) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0);
              int hypre__sz2 = ((stride[2]) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0)) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0);
              int hypre__sx3 = stride[0];
              int hypre__sy3 = (stride[1]) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0);
              int hypre__sz3 = ((stride[2]) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0)) * (0 < ((((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1) ? (((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1 : 0);
              int hypre__nx = loop_size[0];
              int hypre__ny = loop_size[1];
              int hypre__nz = loop_size[2];
              int hypre__mx = hypre__nx;
              int hypre__my = hypre__ny;
              int hypre__mz = hypre__nz;
              int hypre__dir;
              int hypre__max;
              int hypre__div;
              int hypre__mod;
              int hypre__block;
              int hypre__num_blocks;
              hypre__dir = 0;
              hypre__max = hypre__nx;
              if (hypre__ny > hypre__max) {
                hypre__dir = 1;
                hypre__max = hypre__ny;
              }
              if (hypre__nz > hypre__max) {
                hypre__dir = 2;
                hypre__max = hypre__nz;
              }
              hypre__num_blocks = 1;
              if (hypre__max < hypre__num_blocks) {
                hypre__num_blocks = hypre__max;
              }
              if (hypre__num_blocks > 0) {
                hypre__div = hypre__max / hypre__num_blocks;
                hypre__mod = hypre__max % hypre__num_blocks;
              }
              ;
              ;
              for (hypre__block = 0; hypre__block < hypre__num_blocks; hypre__block++) {
                loopi = 0;
                loopj = 0;
                loopk = 0;
                hypre__nx = hypre__mx;
                hypre__ny = hypre__my;
                hypre__nz = hypre__mz;
                if (hypre__num_blocks > 1) {
                  if (hypre__dir == 0) {
                    loopi = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                    hypre__nx = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                  }
                  else
                    if (hypre__dir == 1) {
                      loopj = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                      hypre__ny = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                    }
                    else
                      if (hypre__dir == 2) {
                        loopk = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                        hypre__nz = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                      }
                }
                ;
                Ai = ((hypre__i1start + (loopi * hypre__sx1)) + (loopj * hypre__sy1)) + (loopk * hypre__sz1);
                xi = ((hypre__i2start + (loopi * hypre__sx2)) + (loopj * hypre__sy2)) + (loopk * hypre__sz2);
                yi = ((hypre__i3start + (loopi * hypre__sx3)) + (loopj * hypre__sy3)) + (loopk * hypre__sz3);
                for (loopk = 0; loopk < hypre__nz; loopk++) {
                  for (loopj = 0; loopj < hypre__ny; loopj++) {
                    for (loopi = 0; loopi < hypre__nx; loopi++) {
                      {
                        yp[yi] += ((Ap0[Ai]) * (xp[xi + xoff0])) + ((Ap1[Ai]) * (xp[xi + xoff1]));
                      }
                      Ai += hypre__sx1;
                      xi += hypre__sx2;
                      yi += hypre__sx3;
                    }
                    Ai += hypre__sy1 - (hypre__nx * hypre__sx1);
                    xi += hypre__sy2 - (hypre__nx * hypre__sx2);
                    yi += hypre__sy3 - (hypre__nx * hypre__sx3);
                  }
                  Ai += hypre__sz1 - (hypre__ny * hypre__sy1);
                  xi += hypre__sz2 - (hypre__ny * hypre__sy2);
                  yi += hypre__sz3 - (hypre__ny * hypre__sy3);
                }
              }
            }
            ;
            break;
          case 1:
            Ap0 = (A)->data + ((A)->data_indices[i][si + 0]);
            xoff0 = (stencil_shape[si + 0][0]) + (((stencil_shape[si + 0][1]) + ((stencil_shape[si + 0][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            {
              int hypre__i1start = ((start[0]) - ((A_data_box)->imin[0])) + ((((start[1]) - ((A_data_box)->imin[1])) + (((start[2]) - ((A_data_box)->imin[2])) * (0 < ((((A_data_box)->imax[1]) - ((A_data_box)->imin[1])) + 1) ? (((A_data_box)->imax[1]) - ((A_data_box)->imin[1])) + 1 : 0))) * (0 < ((((A_data_box)->imax[0]) - ((A_data_box)->imin[0])) + 1) ? (((A_data_box)->imax[0]) - ((A_data_box)->imin[0])) + 1 : 0));
              int hypre__i2start = ((start[0]) - ((x_data_box)->imin[0])) + ((((start[1]) - ((x_data_box)->imin[1])) + (((start[2]) - ((x_data_box)->imin[2])) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
              int hypre__i3start = ((start[0]) - ((y_data_box)->imin[0])) + ((((start[1]) - ((y_data_box)->imin[1])) + (((start[2]) - ((y_data_box)->imin[2])) * (0 < ((((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1) ? (((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1 : 0))) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0));
              int hypre__sx1 = stride[0];
              int hypre__sy1 = (stride[1]) * (0 < ((((A_data_box)->imax[0]) - ((A_data_box)->imin[0])) + 1) ? (((A_data_box)->imax[0]) - ((A_data_box)->imin[0])) + 1 : 0);
              int hypre__sz1 = ((stride[2]) * (0 < ((((A_data_box)->imax[0]) - ((A_data_box)->imin[0])) + 1) ? (((A_data_box)->imax[0]) - ((A_data_box)->imin[0])) + 1 : 0)) * (0 < ((((A_data_box)->imax[1]) - ((A_data_box)->imin[1])) + 1) ? (((A_data_box)->imax[1]) - ((A_data_box)->imin[1])) + 1 : 0);
              int hypre__sx2 = stride[0];
              int hypre__sy2 = (stride[1]) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0);
              int hypre__sz2 = ((stride[2]) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0)) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0);
              int hypre__sx3 = stride[0];
              int hypre__sy3 = (stride[1]) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0);
              int hypre__sz3 = ((stride[2]) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0)) * (0 < ((((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1) ? (((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1 : 0);
              int hypre__nx = loop_size[0];
              int hypre__ny = loop_size[1];
              int hypre__nz = loop_size[2];
              int hypre__mx = hypre__nx;
              int hypre__my = hypre__ny;
              int hypre__mz = hypre__nz;
              int hypre__dir;
              int hypre__max;
              int hypre__div;
              int hypre__mod;
              int hypre__block;
              int hypre__num_blocks;
              hypre__dir = 0;
              hypre__max = hypre__nx;
              if (hypre__ny > hypre__max) {
                hypre__dir = 1;
                hypre__max = hypre__ny;
              }
              if (hypre__nz > hypre__max) {
                hypre__dir = 2;
                hypre__max = hypre__nz;
              }
              hypre__num_blocks = 1;
              if (hypre__max < hypre__num_blocks) {
                hypre__num_blocks = hypre__max;
              }
              if (hypre__num_blocks > 0) {
                hypre__div = hypre__max / hypre__num_blocks;
                hypre__mod = hypre__max % hypre__num_blocks;
              }
              ;
              ;
              for (hypre__block = 0; hypre__block < hypre__num_blocks; hypre__block++) {
                loopi = 0;
                loopj = 0;
                loopk = 0;
                hypre__nx = hypre__mx;
                hypre__ny = hypre__my;
                hypre__nz = hypre__mz;
                if (hypre__num_blocks > 1) {
                  if (hypre__dir == 0) {
                    loopi = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                    hypre__nx = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                  }
                  else
                    if (hypre__dir == 1) {
                      loopj = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                      hypre__ny = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                    }
                    else
                      if (hypre__dir == 2) {
                        loopk = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                        hypre__nz = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                      }
                }
                ;
                Ai = ((hypre__i1start + (loopi * hypre__sx1)) + (loopj * hypre__sy1)) + (loopk * hypre__sz1);
                xi = ((hypre__i2start + (loopi * hypre__sx2)) + (loopj * hypre__sy2)) + (loopk * hypre__sz2);
                yi = ((hypre__i3start + (loopi * hypre__sx3)) + (loopj * hypre__sy3)) + (loopk * hypre__sz3);
                for (loopk = 0; loopk < hypre__nz; loopk++) {
                  for (loopj = 0; loopj < hypre__ny; loopj++) {
                    for (loopi = 0; loopi < hypre__nx; loopi++) {
                      {
                        yp[yi] += (Ap0[Ai]) * (xp[xi + xoff0]);
                      }
                      Ai += hypre__sx1;
                      xi += hypre__sx2;
                      yi += hypre__sx3;
                    }
                    Ai += hypre__sy1 - (hypre__nx * hypre__sx1);
                    xi += hypre__sy2 - (hypre__nx * hypre__sx2);
                    yi += hypre__sy3 - (hypre__nx * hypre__sx3);
                  }
                  Ai += hypre__sz1 - (hypre__ny * hypre__sy1);
                  xi += hypre__sz2 - (hypre__ny * hypre__sy2);
                  yi += hypre__sz3 - (hypre__ny * hypre__sy3);
                }
              }
            }
            ;
            break;
        }
      }
      if (alpha != 1.0) {
        {
          int hypre__i1start = ((start[0]) - ((y_data_box)->imin[0])) + ((((start[1]) - ((y_data_box)->imin[1])) + (((start[2]) - ((y_data_box)->imin[2])) * (0 < ((((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1) ? (((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1 : 0))) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0));
          int hypre__sx1 = stride[0];
          int hypre__sy1 = (stride[1]) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0);
          int hypre__sz1 = ((stride[2]) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0)) * (0 < ((((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1) ? (((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1 : 0);
          int hypre__nx = loop_size[0];
          int hypre__ny = loop_size[1];
          int hypre__nz = loop_size[2];
          int hypre__mx = hypre__nx;
          int hypre__my = hypre__ny;
          int hypre__mz = hypre__nz;
          int hypre__dir;
          int hypre__max;
          int hypre__div;
          int hypre__mod;
          int hypre__block;
          int hypre__num_blocks;
          hypre__dir = 0;
          hypre__max = hypre__nx;
          if (hypre__ny > hypre__max) {
            hypre__dir = 1;
            hypre__max = hypre__ny;
          }
          if (hypre__nz > hypre__max) {
            hypre__dir = 2;
            hypre__max = hypre__nz;
          }
          hypre__num_blocks = 1;
          if (hypre__max < hypre__num_blocks) {
            hypre__num_blocks = hypre__max;
          }
          if (hypre__num_blocks > 0) {
            hypre__div = hypre__max / hypre__num_blocks;
            hypre__mod = hypre__max % hypre__num_blocks;
          }
          ;
          ;
          for (hypre__block = 0; hypre__block < hypre__num_blocks; hypre__block++) {
            loopi = 0;
            loopj = 0;
            loopk = 0;
            hypre__nx = hypre__mx;
            hypre__ny = hypre__my;
            hypre__nz = hypre__mz;
            if (hypre__num_blocks > 1) {
              if (hypre__dir == 0) {
                loopi = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                hypre__nx = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
              }
              else
                if (hypre__dir == 1) {
                  loopj = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                  hypre__ny = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                }
                else
                  if (hypre__dir == 2) {
                    loopk = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                    hypre__nz = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                  }
            }
            ;
            yi = ((hypre__i1start + (loopi * hypre__sx1)) + (loopj * hypre__sy1)) + (loopk * hypre__sz1);
            for (loopk = 0; loopk < hypre__nz; loopk++) {
              for (loopj = 0; loopj < hypre__ny; loopj++) {
                for (loopi = 0; loopi < hypre__nx; loopi++) {
                  {
                    (yp[yi]) -= alpha;
                  }
                  yi += hypre__sx1;
                }
                yi += hypre__sy1 - (hypre__nx * hypre__sx1);
              }
              yi += hypre__sz1 - (hypre__ny * hypre__sy1);
            }
          }
        }
        ;
      }
    }
  }
  return ierr;
}
int hypre_StructMatvecCC1(double alpha, hypre_StructMatrix* A, hypre_StructVector* x, hypre_StructVector* y, hypre_BoxArrayArray* compute_box_aa, hypre_IndexRef stride) {
  int i;
  int j;
  int si;
  int ierr = 0;
  double* Ap0;
  double* Ap1;
  double* Ap2;
  double* Ap3;
  double* Ap4;
  double* Ap5;
  double* Ap6;
  double AAp0;
  double AAp1;
  double AAp2;
  double AAp3;
  double AAp4;
  double AAp5;
  double AAp6;
  int xoff0;
  int xoff1;
  int xoff2;
  int xoff3;
  int xoff4;
  int xoff5;
  int xoff6;
  int Ai;
  int xi;
  hypre_BoxArray* compute_box_a;
  hypre_Box* compute_box;
  hypre_Box* A_data_box;
  hypre_Box* x_data_box;
  hypre_StructStencil* stencil;
  hypre_Index* stencil_shape;
  int stencil_size;
  hypre_Box* y_data_box;
  double* xp;
  double* yp;
  int depth;
  hypre_Index loop_size;
  int loopi;
  int loopj;
  int loopk;
  hypre_IndexRef start;
  int yi;
  stencil = (A)->stencil;
  stencil_shape = (stencil)->shape;
  stencil_size = (stencil)->size;
  for (i = 0; i < (compute_box_aa)->size; i++) {
    compute_box_a = (compute_box_aa)->box_arrays[i];
    A_data_box = &(((A)->data_space)->boxes[i]);
    x_data_box = &(((x)->data_space)->boxes[i]);
    y_data_box = &(((y)->data_space)->boxes[i]);
    xp = (x)->data + ((x)->data_indices[i]);
    yp = (y)->data + ((y)->data_indices[i]);
    for (j = 0; j < (compute_box_a)->size; j++) {
      compute_box = &((compute_box_a)->boxes[j]);
      hypre_BoxGetSize(compute_box, loop_size);
      start = (compute_box)->imin;
      Ai = 0;
      for (si = 0; si < stencil_size; si += 7) {
        depth = 7 < (stencil_size - si) ? 7 : stencil_size - si;
        switch (depth) {
          case 7:
            Ap0 = (A)->data + ((A)->data_indices[i][si + 0]);
            Ap1 = (A)->data + ((A)->data_indices[i][si + 1]);
            Ap2 = (A)->data + ((A)->data_indices[i][si + 2]);
            Ap3 = (A)->data + ((A)->data_indices[i][si + 3]);
            Ap4 = (A)->data + ((A)->data_indices[i][si + 4]);
            Ap5 = (A)->data + ((A)->data_indices[i][si + 5]);
            Ap6 = (A)->data + ((A)->data_indices[i][si + 6]);
            AAp0 = (Ap0[Ai]) * alpha;
            AAp1 = (Ap1[Ai]) * alpha;
            AAp2 = (Ap2[Ai]) * alpha;
            AAp3 = (Ap3[Ai]) * alpha;
            AAp4 = (Ap4[Ai]) * alpha;
            AAp5 = (Ap5[Ai]) * alpha;
            AAp6 = (Ap6[Ai]) * alpha;
            xoff0 = (stencil_shape[si + 0][0]) + (((stencil_shape[si + 0][1]) + ((stencil_shape[si + 0][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            xoff1 = (stencil_shape[si + 1][0]) + (((stencil_shape[si + 1][1]) + ((stencil_shape[si + 1][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            xoff2 = (stencil_shape[si + 2][0]) + (((stencil_shape[si + 2][1]) + ((stencil_shape[si + 2][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            xoff3 = (stencil_shape[si + 3][0]) + (((stencil_shape[si + 3][1]) + ((stencil_shape[si + 3][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            xoff4 = (stencil_shape[si + 4][0]) + (((stencil_shape[si + 4][1]) + ((stencil_shape[si + 4][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            xoff5 = (stencil_shape[si + 5][0]) + (((stencil_shape[si + 5][1]) + ((stencil_shape[si + 5][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            xoff6 = (stencil_shape[si + 6][0]) + (((stencil_shape[si + 6][1]) + ((stencil_shape[si + 6][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            {
              int hypre__i1start = ((start[0]) - ((x_data_box)->imin[0])) + ((((start[1]) - ((x_data_box)->imin[1])) + (((start[2]) - ((x_data_box)->imin[2])) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
              int hypre__i2start = ((start[0]) - ((y_data_box)->imin[0])) + ((((start[1]) - ((y_data_box)->imin[1])) + (((start[2]) - ((y_data_box)->imin[2])) * (0 < ((((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1) ? (((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1 : 0))) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0));
              int hypre__sx1 = stride[0];
              int hypre__sy1 = (stride[1]) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0);
              int hypre__sz1 = ((stride[2]) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0)) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0);
              int hypre__sx2 = stride[0];
              int hypre__sy2 = (stride[1]) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0);
              int hypre__sz2 = ((stride[2]) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0)) * (0 < ((((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1) ? (((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1 : 0);
              int hypre__nx = loop_size[0];
              int hypre__ny = loop_size[1];
              int hypre__nz = loop_size[2];
              int hypre__mx = hypre__nx;
              int hypre__my = hypre__ny;
              int hypre__mz = hypre__nz;
              int hypre__dir;
              int hypre__max;
              int hypre__div;
              int hypre__mod;
              int hypre__block;
              int hypre__num_blocks;
              hypre__dir = 0;
              hypre__max = hypre__nx;
              if (hypre__ny > hypre__max) {
                hypre__dir = 1;
                hypre__max = hypre__ny;
              }
              if (hypre__nz > hypre__max) {
                hypre__dir = 2;
                hypre__max = hypre__nz;
              }
              hypre__num_blocks = 1;
              if (hypre__max < hypre__num_blocks) {
                hypre__num_blocks = hypre__max;
              }
              if (hypre__num_blocks > 0) {
                hypre__div = hypre__max / hypre__num_blocks;
                hypre__mod = hypre__max % hypre__num_blocks;
              }
              ;
              ;
              for (hypre__block = 0; hypre__block < hypre__num_blocks; hypre__block++) {
                loopi = 0;
                loopj = 0;
                loopk = 0;
                hypre__nx = hypre__mx;
                hypre__ny = hypre__my;
                hypre__nz = hypre__mz;
                if (hypre__num_blocks > 1) {
                  if (hypre__dir == 0) {
                    loopi = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                    hypre__nx = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                  }
                  else
                    if (hypre__dir == 1) {
                      loopj = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                      hypre__ny = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                    }
                    else
                      if (hypre__dir == 2) {
                        loopk = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                        hypre__nz = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                      }
                }
                ;
                xi = ((hypre__i1start + (loopi * hypre__sx1)) + (loopj * hypre__sy1)) + (loopk * hypre__sz1);
                yi = ((hypre__i2start + (loopi * hypre__sx2)) + (loopj * hypre__sy2)) + (loopk * hypre__sz2);
                for (loopk = 0; loopk < hypre__nz; loopk++) {
                  for (loopj = 0; loopj < hypre__ny; loopj++) {
                    for (loopi = 0; loopi < hypre__nx; loopi++) {
                      {
                        yp[yi] += ((((((AAp0 * (xp[xi + xoff0])) + (AAp1 * (xp[xi + xoff1]))) + (AAp2 * (xp[xi + xoff2]))) + (AAp3 * (xp[xi + xoff3]))) + (AAp4 * (xp[xi + xoff4]))) + (AAp5 * (xp[xi + xoff5]))) + (AAp6 * (xp[xi + xoff6]));
                      }
                      xi += hypre__sx1;
                      yi += hypre__sx2;
                    }
                    xi += hypre__sy1 - (hypre__nx * hypre__sx1);
                    yi += hypre__sy2 - (hypre__nx * hypre__sx2);
                  }
                  xi += hypre__sz1 - (hypre__ny * hypre__sy1);
                  yi += hypre__sz2 - (hypre__ny * hypre__sy2);
                }
              }
            }
            ;
            break;
          case 6:
            Ap0 = (A)->data + ((A)->data_indices[i][si + 0]);
            Ap1 = (A)->data + ((A)->data_indices[i][si + 1]);
            Ap2 = (A)->data + ((A)->data_indices[i][si + 2]);
            Ap3 = (A)->data + ((A)->data_indices[i][si + 3]);
            Ap4 = (A)->data + ((A)->data_indices[i][si + 4]);
            Ap5 = (A)->data + ((A)->data_indices[i][si + 5]);
            AAp0 = (Ap0[Ai]) * alpha;
            AAp1 = (Ap1[Ai]) * alpha;
            AAp2 = (Ap2[Ai]) * alpha;
            AAp3 = (Ap3[Ai]) * alpha;
            AAp4 = (Ap4[Ai]) * alpha;
            AAp5 = (Ap5[Ai]) * alpha;
            xoff0 = (stencil_shape[si + 0][0]) + (((stencil_shape[si + 0][1]) + ((stencil_shape[si + 0][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            xoff1 = (stencil_shape[si + 1][0]) + (((stencil_shape[si + 1][1]) + ((stencil_shape[si + 1][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            xoff2 = (stencil_shape[si + 2][0]) + (((stencil_shape[si + 2][1]) + ((stencil_shape[si + 2][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            xoff3 = (stencil_shape[si + 3][0]) + (((stencil_shape[si + 3][1]) + ((stencil_shape[si + 3][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            xoff4 = (stencil_shape[si + 4][0]) + (((stencil_shape[si + 4][1]) + ((stencil_shape[si + 4][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            xoff5 = (stencil_shape[si + 5][0]) + (((stencil_shape[si + 5][1]) + ((stencil_shape[si + 5][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            {
              int hypre__i1start = ((start[0]) - ((x_data_box)->imin[0])) + ((((start[1]) - ((x_data_box)->imin[1])) + (((start[2]) - ((x_data_box)->imin[2])) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
              int hypre__i2start = ((start[0]) - ((y_data_box)->imin[0])) + ((((start[1]) - ((y_data_box)->imin[1])) + (((start[2]) - ((y_data_box)->imin[2])) * (0 < ((((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1) ? (((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1 : 0))) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0));
              int hypre__sx1 = stride[0];
              int hypre__sy1 = (stride[1]) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0);
              int hypre__sz1 = ((stride[2]) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0)) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0);
              int hypre__sx2 = stride[0];
              int hypre__sy2 = (stride[1]) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0);
              int hypre__sz2 = ((stride[2]) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0)) * (0 < ((((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1) ? (((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1 : 0);
              int hypre__nx = loop_size[0];
              int hypre__ny = loop_size[1];
              int hypre__nz = loop_size[2];
              int hypre__mx = hypre__nx;
              int hypre__my = hypre__ny;
              int hypre__mz = hypre__nz;
              int hypre__dir;
              int hypre__max;
              int hypre__div;
              int hypre__mod;
              int hypre__block;
              int hypre__num_blocks;
              hypre__dir = 0;
              hypre__max = hypre__nx;
              if (hypre__ny > hypre__max) {
                hypre__dir = 1;
                hypre__max = hypre__ny;
              }
              if (hypre__nz > hypre__max) {
                hypre__dir = 2;
                hypre__max = hypre__nz;
              }
              hypre__num_blocks = 1;
              if (hypre__max < hypre__num_blocks) {
                hypre__num_blocks = hypre__max;
              }
              if (hypre__num_blocks > 0) {
                hypre__div = hypre__max / hypre__num_blocks;
                hypre__mod = hypre__max % hypre__num_blocks;
              }
              ;
              ;
              for (hypre__block = 0; hypre__block < hypre__num_blocks; hypre__block++) {
                loopi = 0;
                loopj = 0;
                loopk = 0;
                hypre__nx = hypre__mx;
                hypre__ny = hypre__my;
                hypre__nz = hypre__mz;
                if (hypre__num_blocks > 1) {
                  if (hypre__dir == 0) {
                    loopi = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                    hypre__nx = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                  }
                  else
                    if (hypre__dir == 1) {
                      loopj = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                      hypre__ny = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                    }
                    else
                      if (hypre__dir == 2) {
                        loopk = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                        hypre__nz = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                      }
                }
                ;
                xi = ((hypre__i1start + (loopi * hypre__sx1)) + (loopj * hypre__sy1)) + (loopk * hypre__sz1);
                yi = ((hypre__i2start + (loopi * hypre__sx2)) + (loopj * hypre__sy2)) + (loopk * hypre__sz2);
                for (loopk = 0; loopk < hypre__nz; loopk++) {
                  for (loopj = 0; loopj < hypre__ny; loopj++) {
                    for (loopi = 0; loopi < hypre__nx; loopi++) {
                      {
                        yp[yi] += (((((AAp0 * (xp[xi + xoff0])) + (AAp1 * (xp[xi + xoff1]))) + (AAp2 * (xp[xi + xoff2]))) + (AAp3 * (xp[xi + xoff3]))) + (AAp4 * (xp[xi + xoff4]))) + (AAp5 * (xp[xi + xoff5]));
                      }
                      xi += hypre__sx1;
                      yi += hypre__sx2;
                    }
                    xi += hypre__sy1 - (hypre__nx * hypre__sx1);
                    yi += hypre__sy2 - (hypre__nx * hypre__sx2);
                  }
                  xi += hypre__sz1 - (hypre__ny * hypre__sy1);
                  yi += hypre__sz2 - (hypre__ny * hypre__sy2);
                }
              }
            }
            ;
            break;
          case 5:
            Ap0 = (A)->data + ((A)->data_indices[i][si + 0]);
            Ap1 = (A)->data + ((A)->data_indices[i][si + 1]);
            Ap2 = (A)->data + ((A)->data_indices[i][si + 2]);
            Ap3 = (A)->data + ((A)->data_indices[i][si + 3]);
            Ap4 = (A)->data + ((A)->data_indices[i][si + 4]);
            AAp0 = (Ap0[Ai]) * alpha;
            AAp1 = (Ap1[Ai]) * alpha;
            AAp2 = (Ap2[Ai]) * alpha;
            AAp3 = (Ap3[Ai]) * alpha;
            AAp4 = (Ap4[Ai]) * alpha;
            xoff0 = (stencil_shape[si + 0][0]) + (((stencil_shape[si + 0][1]) + ((stencil_shape[si + 0][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            xoff1 = (stencil_shape[si + 1][0]) + (((stencil_shape[si + 1][1]) + ((stencil_shape[si + 1][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            xoff2 = (stencil_shape[si + 2][0]) + (((stencil_shape[si + 2][1]) + ((stencil_shape[si + 2][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            xoff3 = (stencil_shape[si + 3][0]) + (((stencil_shape[si + 3][1]) + ((stencil_shape[si + 3][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            xoff4 = (stencil_shape[si + 4][0]) + (((stencil_shape[si + 4][1]) + ((stencil_shape[si + 4][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            {
              int hypre__i1start = ((start[0]) - ((x_data_box)->imin[0])) + ((((start[1]) - ((x_data_box)->imin[1])) + (((start[2]) - ((x_data_box)->imin[2])) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
              int hypre__i2start = ((start[0]) - ((y_data_box)->imin[0])) + ((((start[1]) - ((y_data_box)->imin[1])) + (((start[2]) - ((y_data_box)->imin[2])) * (0 < ((((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1) ? (((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1 : 0))) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0));
              int hypre__sx1 = stride[0];
              int hypre__sy1 = (stride[1]) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0);
              int hypre__sz1 = ((stride[2]) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0)) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0);
              int hypre__sx2 = stride[0];
              int hypre__sy2 = (stride[1]) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0);
              int hypre__sz2 = ((stride[2]) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0)) * (0 < ((((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1) ? (((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1 : 0);
              int hypre__nx = loop_size[0];
              int hypre__ny = loop_size[1];
              int hypre__nz = loop_size[2];
              int hypre__mx = hypre__nx;
              int hypre__my = hypre__ny;
              int hypre__mz = hypre__nz;
              int hypre__dir;
              int hypre__max;
              int hypre__div;
              int hypre__mod;
              int hypre__block;
              int hypre__num_blocks;
              hypre__dir = 0;
              hypre__max = hypre__nx;
              if (hypre__ny > hypre__max) {
                hypre__dir = 1;
                hypre__max = hypre__ny;
              }
              if (hypre__nz > hypre__max) {
                hypre__dir = 2;
                hypre__max = hypre__nz;
              }
              hypre__num_blocks = 1;
              if (hypre__max < hypre__num_blocks) {
                hypre__num_blocks = hypre__max;
              }
              if (hypre__num_blocks > 0) {
                hypre__div = hypre__max / hypre__num_blocks;
                hypre__mod = hypre__max % hypre__num_blocks;
              }
              ;
              ;
              for (hypre__block = 0; hypre__block < hypre__num_blocks; hypre__block++) {
                loopi = 0;
                loopj = 0;
                loopk = 0;
                hypre__nx = hypre__mx;
                hypre__ny = hypre__my;
                hypre__nz = hypre__mz;
                if (hypre__num_blocks > 1) {
                  if (hypre__dir == 0) {
                    loopi = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                    hypre__nx = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                  }
                  else
                    if (hypre__dir == 1) {
                      loopj = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                      hypre__ny = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                    }
                    else
                      if (hypre__dir == 2) {
                        loopk = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                        hypre__nz = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                      }
                }
                ;
                xi = ((hypre__i1start + (loopi * hypre__sx1)) + (loopj * hypre__sy1)) + (loopk * hypre__sz1);
                yi = ((hypre__i2start + (loopi * hypre__sx2)) + (loopj * hypre__sy2)) + (loopk * hypre__sz2);
                for (loopk = 0; loopk < hypre__nz; loopk++) {
                  for (loopj = 0; loopj < hypre__ny; loopj++) {
                    for (loopi = 0; loopi < hypre__nx; loopi++) {
                      {
                        yp[yi] += ((((AAp0 * (xp[xi + xoff0])) + (AAp1 * (xp[xi + xoff1]))) + (AAp2 * (xp[xi + xoff2]))) + (AAp3 * (xp[xi + xoff3]))) + (AAp4 * (xp[xi + xoff4]));
                      }
                      xi += hypre__sx1;
                      yi += hypre__sx2;
                    }
                    xi += hypre__sy1 - (hypre__nx * hypre__sx1);
                    yi += hypre__sy2 - (hypre__nx * hypre__sx2);
                  }
                  xi += hypre__sz1 - (hypre__ny * hypre__sy1);
                  yi += hypre__sz2 - (hypre__ny * hypre__sy2);
                }
              }
            }
            ;
            break;
          case 4:
            Ap0 = (A)->data + ((A)->data_indices[i][si + 0]);
            Ap1 = (A)->data + ((A)->data_indices[i][si + 1]);
            Ap2 = (A)->data + ((A)->data_indices[i][si + 2]);
            Ap3 = (A)->data + ((A)->data_indices[i][si + 3]);
            AAp0 = (Ap0[Ai]) * alpha;
            AAp1 = (Ap1[Ai]) * alpha;
            AAp2 = (Ap2[Ai]) * alpha;
            AAp3 = (Ap3[Ai]) * alpha;
            xoff0 = (stencil_shape[si + 0][0]) + (((stencil_shape[si + 0][1]) + ((stencil_shape[si + 0][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            xoff1 = (stencil_shape[si + 1][0]) + (((stencil_shape[si + 1][1]) + ((stencil_shape[si + 1][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            xoff2 = (stencil_shape[si + 2][0]) + (((stencil_shape[si + 2][1]) + ((stencil_shape[si + 2][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            xoff3 = (stencil_shape[si + 3][0]) + (((stencil_shape[si + 3][1]) + ((stencil_shape[si + 3][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            {
              int hypre__i1start = ((start[0]) - ((x_data_box)->imin[0])) + ((((start[1]) - ((x_data_box)->imin[1])) + (((start[2]) - ((x_data_box)->imin[2])) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
              int hypre__i2start = ((start[0]) - ((y_data_box)->imin[0])) + ((((start[1]) - ((y_data_box)->imin[1])) + (((start[2]) - ((y_data_box)->imin[2])) * (0 < ((((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1) ? (((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1 : 0))) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0));
              int hypre__sx1 = stride[0];
              int hypre__sy1 = (stride[1]) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0);
              int hypre__sz1 = ((stride[2]) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0)) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0);
              int hypre__sx2 = stride[0];
              int hypre__sy2 = (stride[1]) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0);
              int hypre__sz2 = ((stride[2]) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0)) * (0 < ((((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1) ? (((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1 : 0);
              int hypre__nx = loop_size[0];
              int hypre__ny = loop_size[1];
              int hypre__nz = loop_size[2];
              int hypre__mx = hypre__nx;
              int hypre__my = hypre__ny;
              int hypre__mz = hypre__nz;
              int hypre__dir;
              int hypre__max;
              int hypre__div;
              int hypre__mod;
              int hypre__block;
              int hypre__num_blocks;
              hypre__dir = 0;
              hypre__max = hypre__nx;
              if (hypre__ny > hypre__max) {
                hypre__dir = 1;
                hypre__max = hypre__ny;
              }
              if (hypre__nz > hypre__max) {
                hypre__dir = 2;
                hypre__max = hypre__nz;
              }
              hypre__num_blocks = 1;
              if (hypre__max < hypre__num_blocks) {
                hypre__num_blocks = hypre__max;
              }
              if (hypre__num_blocks > 0) {
                hypre__div = hypre__max / hypre__num_blocks;
                hypre__mod = hypre__max % hypre__num_blocks;
              }
              ;
              ;
              for (hypre__block = 0; hypre__block < hypre__num_blocks; hypre__block++) {
                loopi = 0;
                loopj = 0;
                loopk = 0;
                hypre__nx = hypre__mx;
                hypre__ny = hypre__my;
                hypre__nz = hypre__mz;
                if (hypre__num_blocks > 1) {
                  if (hypre__dir == 0) {
                    loopi = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                    hypre__nx = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                  }
                  else
                    if (hypre__dir == 1) {
                      loopj = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                      hypre__ny = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                    }
                    else
                      if (hypre__dir == 2) {
                        loopk = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                        hypre__nz = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                      }
                }
                ;
                xi = ((hypre__i1start + (loopi * hypre__sx1)) + (loopj * hypre__sy1)) + (loopk * hypre__sz1);
                yi = ((hypre__i2start + (loopi * hypre__sx2)) + (loopj * hypre__sy2)) + (loopk * hypre__sz2);
                for (loopk = 0; loopk < hypre__nz; loopk++) {
                  for (loopj = 0; loopj < hypre__ny; loopj++) {
                    for (loopi = 0; loopi < hypre__nx; loopi++) {
                      {
                        yp[yi] += (((AAp0 * (xp[xi + xoff0])) + (AAp1 * (xp[xi + xoff1]))) + (AAp2 * (xp[xi + xoff2]))) + (AAp3 * (xp[xi + xoff3]));
                      }
                      xi += hypre__sx1;
                      yi += hypre__sx2;
                    }
                    xi += hypre__sy1 - (hypre__nx * hypre__sx1);
                    yi += hypre__sy2 - (hypre__nx * hypre__sx2);
                  }
                  xi += hypre__sz1 - (hypre__ny * hypre__sy1);
                  yi += hypre__sz2 - (hypre__ny * hypre__sy2);
                }
              }
            }
            ;
            break;
          case 3:
            Ap0 = (A)->data + ((A)->data_indices[i][si + 0]);
            Ap1 = (A)->data + ((A)->data_indices[i][si + 1]);
            Ap2 = (A)->data + ((A)->data_indices[i][si + 2]);
            AAp0 = (Ap0[Ai]) * alpha;
            AAp1 = (Ap1[Ai]) * alpha;
            AAp2 = (Ap2[Ai]) * alpha;
            xoff0 = (stencil_shape[si + 0][0]) + (((stencil_shape[si + 0][1]) + ((stencil_shape[si + 0][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            xoff1 = (stencil_shape[si + 1][0]) + (((stencil_shape[si + 1][1]) + ((stencil_shape[si + 1][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            xoff2 = (stencil_shape[si + 2][0]) + (((stencil_shape[si + 2][1]) + ((stencil_shape[si + 2][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            {
              int hypre__i1start = ((start[0]) - ((x_data_box)->imin[0])) + ((((start[1]) - ((x_data_box)->imin[1])) + (((start[2]) - ((x_data_box)->imin[2])) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
              int hypre__i2start = ((start[0]) - ((y_data_box)->imin[0])) + ((((start[1]) - ((y_data_box)->imin[1])) + (((start[2]) - ((y_data_box)->imin[2])) * (0 < ((((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1) ? (((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1 : 0))) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0));
              int hypre__sx1 = stride[0];
              int hypre__sy1 = (stride[1]) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0);
              int hypre__sz1 = ((stride[2]) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0)) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0);
              int hypre__sx2 = stride[0];
              int hypre__sy2 = (stride[1]) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0);
              int hypre__sz2 = ((stride[2]) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0)) * (0 < ((((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1) ? (((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1 : 0);
              int hypre__nx = loop_size[0];
              int hypre__ny = loop_size[1];
              int hypre__nz = loop_size[2];
              int hypre__mx = hypre__nx;
              int hypre__my = hypre__ny;
              int hypre__mz = hypre__nz;
              int hypre__dir;
              int hypre__max;
              int hypre__div;
              int hypre__mod;
              int hypre__block;
              int hypre__num_blocks;
              hypre__dir = 0;
              hypre__max = hypre__nx;
              if (hypre__ny > hypre__max) {
                hypre__dir = 1;
                hypre__max = hypre__ny;
              }
              if (hypre__nz > hypre__max) {
                hypre__dir = 2;
                hypre__max = hypre__nz;
              }
              hypre__num_blocks = 1;
              if (hypre__max < hypre__num_blocks) {
                hypre__num_blocks = hypre__max;
              }
              if (hypre__num_blocks > 0) {
                hypre__div = hypre__max / hypre__num_blocks;
                hypre__mod = hypre__max % hypre__num_blocks;
              }
              ;
              ;
              for (hypre__block = 0; hypre__block < hypre__num_blocks; hypre__block++) {
                loopi = 0;
                loopj = 0;
                loopk = 0;
                hypre__nx = hypre__mx;
                hypre__ny = hypre__my;
                hypre__nz = hypre__mz;
                if (hypre__num_blocks > 1) {
                  if (hypre__dir == 0) {
                    loopi = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                    hypre__nx = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                  }
                  else
                    if (hypre__dir == 1) {
                      loopj = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                      hypre__ny = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                    }
                    else
                      if (hypre__dir == 2) {
                        loopk = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                        hypre__nz = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                      }
                }
                ;
                xi = ((hypre__i1start + (loopi * hypre__sx1)) + (loopj * hypre__sy1)) + (loopk * hypre__sz1);
                yi = ((hypre__i2start + (loopi * hypre__sx2)) + (loopj * hypre__sy2)) + (loopk * hypre__sz2);
                for (loopk = 0; loopk < hypre__nz; loopk++) {
                  for (loopj = 0; loopj < hypre__ny; loopj++) {
                    for (loopi = 0; loopi < hypre__nx; loopi++) {
                      {
                        yp[yi] += ((AAp0 * (xp[xi + xoff0])) + (AAp1 * (xp[xi + xoff1]))) + (AAp2 * (xp[xi + xoff2]));
                      }
                      xi += hypre__sx1;
                      yi += hypre__sx2;
                    }
                    xi += hypre__sy1 - (hypre__nx * hypre__sx1);
                    yi += hypre__sy2 - (hypre__nx * hypre__sx2);
                  }
                  xi += hypre__sz1 - (hypre__ny * hypre__sy1);
                  yi += hypre__sz2 - (hypre__ny * hypre__sy2);
                }
              }
            }
            ;
            break;
          case 2:
            Ap0 = (A)->data + ((A)->data_indices[i][si + 0]);
            Ap1 = (A)->data + ((A)->data_indices[i][si + 1]);
            AAp0 = (Ap0[Ai]) * alpha;
            AAp1 = (Ap1[Ai]) * alpha;
            xoff0 = (stencil_shape[si + 0][0]) + (((stencil_shape[si + 0][1]) + ((stencil_shape[si + 0][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            xoff1 = (stencil_shape[si + 1][0]) + (((stencil_shape[si + 1][1]) + ((stencil_shape[si + 1][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            {
              int hypre__i1start = ((start[0]) - ((x_data_box)->imin[0])) + ((((start[1]) - ((x_data_box)->imin[1])) + (((start[2]) - ((x_data_box)->imin[2])) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
              int hypre__i2start = ((start[0]) - ((y_data_box)->imin[0])) + ((((start[1]) - ((y_data_box)->imin[1])) + (((start[2]) - ((y_data_box)->imin[2])) * (0 < ((((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1) ? (((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1 : 0))) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0));
              int hypre__sx1 = stride[0];
              int hypre__sy1 = (stride[1]) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0);
              int hypre__sz1 = ((stride[2]) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0)) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0);
              int hypre__sx2 = stride[0];
              int hypre__sy2 = (stride[1]) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0);
              int hypre__sz2 = ((stride[2]) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0)) * (0 < ((((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1) ? (((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1 : 0);
              int hypre__nx = loop_size[0];
              int hypre__ny = loop_size[1];
              int hypre__nz = loop_size[2];
              int hypre__mx = hypre__nx;
              int hypre__my = hypre__ny;
              int hypre__mz = hypre__nz;
              int hypre__dir;
              int hypre__max;
              int hypre__div;
              int hypre__mod;
              int hypre__block;
              int hypre__num_blocks;
              hypre__dir = 0;
              hypre__max = hypre__nx;
              if (hypre__ny > hypre__max) {
                hypre__dir = 1;
                hypre__max = hypre__ny;
              }
              if (hypre__nz > hypre__max) {
                hypre__dir = 2;
                hypre__max = hypre__nz;
              }
              hypre__num_blocks = 1;
              if (hypre__max < hypre__num_blocks) {
                hypre__num_blocks = hypre__max;
              }
              if (hypre__num_blocks > 0) {
                hypre__div = hypre__max / hypre__num_blocks;
                hypre__mod = hypre__max % hypre__num_blocks;
              }
              ;
              ;
              for (hypre__block = 0; hypre__block < hypre__num_blocks; hypre__block++) {
                loopi = 0;
                loopj = 0;
                loopk = 0;
                hypre__nx = hypre__mx;
                hypre__ny = hypre__my;
                hypre__nz = hypre__mz;
                if (hypre__num_blocks > 1) {
                  if (hypre__dir == 0) {
                    loopi = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                    hypre__nx = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                  }
                  else
                    if (hypre__dir == 1) {
                      loopj = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                      hypre__ny = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                    }
                    else
                      if (hypre__dir == 2) {
                        loopk = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                        hypre__nz = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                      }
                }
                ;
                xi = ((hypre__i1start + (loopi * hypre__sx1)) + (loopj * hypre__sy1)) + (loopk * hypre__sz1);
                yi = ((hypre__i2start + (loopi * hypre__sx2)) + (loopj * hypre__sy2)) + (loopk * hypre__sz2);
                for (loopk = 0; loopk < hypre__nz; loopk++) {
                  for (loopj = 0; loopj < hypre__ny; loopj++) {
                    for (loopi = 0; loopi < hypre__nx; loopi++) {
                      {
                        yp[yi] += (AAp0 * (xp[xi + xoff0])) + (AAp1 * (xp[xi + xoff1]));
                      }
                      xi += hypre__sx1;
                      yi += hypre__sx2;
                    }
                    xi += hypre__sy1 - (hypre__nx * hypre__sx1);
                    yi += hypre__sy2 - (hypre__nx * hypre__sx2);
                  }
                  xi += hypre__sz1 - (hypre__ny * hypre__sy1);
                  yi += hypre__sz2 - (hypre__ny * hypre__sy2);
                }
              }
            }
            ;
            break;
          case 1:
            Ap0 = (A)->data + ((A)->data_indices[i][si + 0]);
            AAp0 = (Ap0[Ai]) * alpha;
            xoff0 = (stencil_shape[si + 0][0]) + (((stencil_shape[si + 0][1]) + ((stencil_shape[si + 0][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            {
              int hypre__i1start = ((start[0]) - ((x_data_box)->imin[0])) + ((((start[1]) - ((x_data_box)->imin[1])) + (((start[2]) - ((x_data_box)->imin[2])) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
              int hypre__i2start = ((start[0]) - ((y_data_box)->imin[0])) + ((((start[1]) - ((y_data_box)->imin[1])) + (((start[2]) - ((y_data_box)->imin[2])) * (0 < ((((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1) ? (((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1 : 0))) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0));
              int hypre__sx1 = stride[0];
              int hypre__sy1 = (stride[1]) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0);
              int hypre__sz1 = ((stride[2]) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0)) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0);
              int hypre__sx2 = stride[0];
              int hypre__sy2 = (stride[1]) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0);
              int hypre__sz2 = ((stride[2]) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0)) * (0 < ((((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1) ? (((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1 : 0);
              int hypre__nx = loop_size[0];
              int hypre__ny = loop_size[1];
              int hypre__nz = loop_size[2];
              int hypre__mx = hypre__nx;
              int hypre__my = hypre__ny;
              int hypre__mz = hypre__nz;
              int hypre__dir;
              int hypre__max;
              int hypre__div;
              int hypre__mod;
              int hypre__block;
              int hypre__num_blocks;
              hypre__dir = 0;
              hypre__max = hypre__nx;
              if (hypre__ny > hypre__max) {
                hypre__dir = 1;
                hypre__max = hypre__ny;
              }
              if (hypre__nz > hypre__max) {
                hypre__dir = 2;
                hypre__max = hypre__nz;
              }
              hypre__num_blocks = 1;
              if (hypre__max < hypre__num_blocks) {
                hypre__num_blocks = hypre__max;
              }
              if (hypre__num_blocks > 0) {
                hypre__div = hypre__max / hypre__num_blocks;
                hypre__mod = hypre__max % hypre__num_blocks;
              }
              ;
              ;
              for (hypre__block = 0; hypre__block < hypre__num_blocks; hypre__block++) {
                loopi = 0;
                loopj = 0;
                loopk = 0;
                hypre__nx = hypre__mx;
                hypre__ny = hypre__my;
                hypre__nz = hypre__mz;
                if (hypre__num_blocks > 1) {
                  if (hypre__dir == 0) {
                    loopi = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                    hypre__nx = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                  }
                  else
                    if (hypre__dir == 1) {
                      loopj = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                      hypre__ny = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                    }
                    else
                      if (hypre__dir == 2) {
                        loopk = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                        hypre__nz = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                      }
                }
                ;
                xi = ((hypre__i1start + (loopi * hypre__sx1)) + (loopj * hypre__sy1)) + (loopk * hypre__sz1);
                yi = ((hypre__i2start + (loopi * hypre__sx2)) + (loopj * hypre__sy2)) + (loopk * hypre__sz2);
                for (loopk = 0; loopk < hypre__nz; loopk++) {
                  for (loopj = 0; loopj < hypre__ny; loopj++) {
                    for (loopi = 0; loopi < hypre__nx; loopi++) {
                      {
                        yp[yi] += AAp0 * (xp[xi + xoff0]);
                      }
                      xi += hypre__sx1;
                      yi += hypre__sx2;
                    }
                    xi += hypre__sy1 - (hypre__nx * hypre__sx1);
                    yi += hypre__sy2 - (hypre__nx * hypre__sx2);
                  }
                  xi += hypre__sz1 - (hypre__ny * hypre__sy1);
                  yi += hypre__sz2 - (hypre__ny * hypre__sy2);
                }
              }
            }
            ;
        }
      }
    }
  }
  return ierr;
}
int hypre_StructMatvecCC2(double alpha, hypre_StructMatrix* A, hypre_StructVector* x, hypre_StructVector* y, hypre_BoxArrayArray* compute_box_aa, hypre_IndexRef stride) {
  int i;
  int j;
  int si;
  int ierr = 0;
  double* Ap0;
  double* Ap1;
  double* Ap2;
  double* Ap3;
  double* Ap4;
  double* Ap5;
  double* Ap6;
  double AAp0;
  double AAp1;
  double AAp2;
  double AAp3;
  double AAp4;
  double AAp5;
  double AAp6;
  int xoff0;
  int xoff1;
  int xoff2;
  int xoff3;
  int xoff4;
  int xoff5;
  int xoff6;
  int si_center;
  int center_rank;
  hypre_Index center_index;
  int Ai;
  int Ai_CC;
  int xi;
  hypre_BoxArray* compute_box_a;
  hypre_Box* compute_box;
  hypre_Box* A_data_box;
  hypre_Box* x_data_box;
  hypre_StructStencil* stencil;
  hypre_Index* stencil_shape;
  int stencil_size;
  hypre_Box* y_data_box;
  double* xp;
  double* yp;
  int depth;
  hypre_Index loop_size;
  int loopi;
  int loopj;
  int loopk;
  hypre_IndexRef start;
  int yi;
  stencil = (A)->stencil;
  stencil_shape = (stencil)->shape;
  stencil_size = (stencil)->size;
  for (i = 0; i < (compute_box_aa)->size; i++) {
    compute_box_a = (compute_box_aa)->box_arrays[i];
    A_data_box = &(((A)->data_space)->boxes[i]);
    x_data_box = &(((x)->data_space)->boxes[i]);
    y_data_box = &(((y)->data_space)->boxes[i]);
    xp = (x)->data + ((x)->data_indices[i]);
    yp = (y)->data + ((y)->data_indices[i]);
    for (j = 0; j < (compute_box_a)->size; j++) {
      compute_box = &((compute_box_a)->boxes[j]);
      hypre_BoxGetSize(compute_box, loop_size);
      start = (compute_box)->imin;
      Ai_CC = 0;
      center_index[0] = 0, center_index[1] = 0, center_index[2] = 0;
      center_rank = hypre_StructStencilElementRank(stencil, center_index);
      si_center = center_rank;
      for (si = 0; si < stencil_size; si += 7) {
        depth = 7 < (stencil_size - si) ? 7 : stencil_size - si;
        switch (depth) {
          case 7:
            Ap0 = (A)->data + ((A)->data_indices[i][si + 0]);
            Ap1 = (A)->data + ((A)->data_indices[i][si + 1]);
            Ap2 = (A)->data + ((A)->data_indices[i][si + 2]);
            Ap3 = (A)->data + ((A)->data_indices[i][si + 3]);
            Ap4 = (A)->data + ((A)->data_indices[i][si + 4]);
            Ap5 = (A)->data + ((A)->data_indices[i][si + 5]);
            Ap6 = (A)->data + ((A)->data_indices[i][si + 6]);
            AAp0 = Ap0[Ai_CC];
            AAp1 = Ap1[Ai_CC];
            AAp2 = Ap2[Ai_CC];
            AAp3 = Ap3[Ai_CC];
            AAp4 = Ap4[Ai_CC];
            AAp5 = Ap5[Ai_CC];
            AAp6 = Ap6[Ai_CC];
            if ((0 <= (si_center - si)) && ((si_center - si) < 7)) {
              switch (si_center - si) {
                case 0:
                  AAp0 = 0;
                  break;
                case 1:
                  AAp1 = 0;
                  break;
                case 2:
                  AAp2 = 0;
                  break;
                case 3:
                  AAp3 = 0;
                  break;
                case 4:
                  AAp4 = 0;
                  break;
                case 5:
                  AAp5 = 0;
                  break;
                case 6:
                  AAp6 = 0;
                  break;
              }
            }
            xoff0 = (stencil_shape[si + 0][0]) + (((stencil_shape[si + 0][1]) + ((stencil_shape[si + 0][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            xoff0 = (stencil_shape[si + 0][0]) + (((stencil_shape[si + 0][1]) + ((stencil_shape[si + 0][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            xoff1 = (stencil_shape[si + 1][0]) + (((stencil_shape[si + 1][1]) + ((stencil_shape[si + 1][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            xoff2 = (stencil_shape[si + 2][0]) + (((stencil_shape[si + 2][1]) + ((stencil_shape[si + 2][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            xoff3 = (stencil_shape[si + 3][0]) + (((stencil_shape[si + 3][1]) + ((stencil_shape[si + 3][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            xoff4 = (stencil_shape[si + 4][0]) + (((stencil_shape[si + 4][1]) + ((stencil_shape[si + 4][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            xoff5 = (stencil_shape[si + 5][0]) + (((stencil_shape[si + 5][1]) + ((stencil_shape[si + 5][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            xoff6 = (stencil_shape[si + 6][0]) + (((stencil_shape[si + 6][1]) + ((stencil_shape[si + 6][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            {
              int hypre__i1start = ((start[0]) - ((x_data_box)->imin[0])) + ((((start[1]) - ((x_data_box)->imin[1])) + (((start[2]) - ((x_data_box)->imin[2])) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
              int hypre__i2start = ((start[0]) - ((y_data_box)->imin[0])) + ((((start[1]) - ((y_data_box)->imin[1])) + (((start[2]) - ((y_data_box)->imin[2])) * (0 < ((((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1) ? (((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1 : 0))) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0));
              int hypre__sx1 = stride[0];
              int hypre__sy1 = (stride[1]) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0);
              int hypre__sz1 = ((stride[2]) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0)) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0);
              int hypre__sx2 = stride[0];
              int hypre__sy2 = (stride[1]) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0);
              int hypre__sz2 = ((stride[2]) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0)) * (0 < ((((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1) ? (((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1 : 0);
              int hypre__nx = loop_size[0];
              int hypre__ny = loop_size[1];
              int hypre__nz = loop_size[2];
              int hypre__mx = hypre__nx;
              int hypre__my = hypre__ny;
              int hypre__mz = hypre__nz;
              int hypre__dir;
              int hypre__max;
              int hypre__div;
              int hypre__mod;
              int hypre__block;
              int hypre__num_blocks;
              hypre__dir = 0;
              hypre__max = hypre__nx;
              if (hypre__ny > hypre__max) {
                hypre__dir = 1;
                hypre__max = hypre__ny;
              }
              if (hypre__nz > hypre__max) {
                hypre__dir = 2;
                hypre__max = hypre__nz;
              }
              hypre__num_blocks = 1;
              if (hypre__max < hypre__num_blocks) {
                hypre__num_blocks = hypre__max;
              }
              if (hypre__num_blocks > 0) {
                hypre__div = hypre__max / hypre__num_blocks;
                hypre__mod = hypre__max % hypre__num_blocks;
              }
              ;
              ;
              for (hypre__block = 0; hypre__block < hypre__num_blocks; hypre__block++) {
                loopi = 0;
                loopj = 0;
                loopk = 0;
                hypre__nx = hypre__mx;
                hypre__ny = hypre__my;
                hypre__nz = hypre__mz;
                if (hypre__num_blocks > 1) {
                  if (hypre__dir == 0) {
                    loopi = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                    hypre__nx = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                  }
                  else
                    if (hypre__dir == 1) {
                      loopj = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                      hypre__ny = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                    }
                    else
                      if (hypre__dir == 2) {
                        loopk = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                        hypre__nz = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                      }
                }
                ;
                xi = ((hypre__i1start + (loopi * hypre__sx1)) + (loopj * hypre__sy1)) + (loopk * hypre__sz1);
                yi = ((hypre__i2start + (loopi * hypre__sx2)) + (loopj * hypre__sy2)) + (loopk * hypre__sz2);
                for (loopk = 0; loopk < hypre__nz; loopk++) {
                  for (loopj = 0; loopj < hypre__ny; loopj++) {
                    for (loopi = 0; loopi < hypre__nx; loopi++) {
                      {
                        yp[yi] += ((((((AAp0 * (xp[xi + xoff0])) + (AAp1 * (xp[xi + xoff1]))) + (AAp2 * (xp[xi + xoff2]))) + (AAp3 * (xp[xi + xoff3]))) + (AAp4 * (xp[xi + xoff4]))) + (AAp5 * (xp[xi + xoff5]))) + (AAp6 * (xp[xi + xoff6]));
                      }
                      xi += hypre__sx1;
                      yi += hypre__sx2;
                    }
                    xi += hypre__sy1 - (hypre__nx * hypre__sx1);
                    yi += hypre__sy2 - (hypre__nx * hypre__sx2);
                  }
                  xi += hypre__sz1 - (hypre__ny * hypre__sy1);
                  yi += hypre__sz2 - (hypre__ny * hypre__sy2);
                }
              }
            }
            ;
            break;
          case 6:
            Ap0 = (A)->data + ((A)->data_indices[i][si + 0]);
            Ap1 = (A)->data + ((A)->data_indices[i][si + 1]);
            Ap2 = (A)->data + ((A)->data_indices[i][si + 2]);
            Ap3 = (A)->data + ((A)->data_indices[i][si + 3]);
            Ap4 = (A)->data + ((A)->data_indices[i][si + 4]);
            Ap5 = (A)->data + ((A)->data_indices[i][si + 5]);
            AAp0 = Ap0[Ai_CC];
            AAp1 = Ap1[Ai_CC];
            AAp2 = Ap2[Ai_CC];
            AAp3 = Ap3[Ai_CC];
            AAp4 = Ap4[Ai_CC];
            AAp5 = Ap5[Ai_CC];
            if ((0 <= (si_center - si)) && ((si_center - si) < 6)) {
              switch (si_center - si) {
                case 0:
                  AAp0 = 0;
                  break;
                case 1:
                  AAp1 = 0;
                  break;
                case 2:
                  AAp2 = 0;
                  break;
                case 3:
                  AAp3 = 0;
                  break;
                case 4:
                  AAp4 = 0;
                  break;
                case 5:
                  AAp5 = 0;
                  break;
              }
            }
            xoff0 = (stencil_shape[si + 0][0]) + (((stencil_shape[si + 0][1]) + ((stencil_shape[si + 0][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            xoff1 = (stencil_shape[si + 1][0]) + (((stencil_shape[si + 1][1]) + ((stencil_shape[si + 1][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            xoff2 = (stencil_shape[si + 2][0]) + (((stencil_shape[si + 2][1]) + ((stencil_shape[si + 2][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            xoff3 = (stencil_shape[si + 3][0]) + (((stencil_shape[si + 3][1]) + ((stencil_shape[si + 3][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            xoff4 = (stencil_shape[si + 4][0]) + (((stencil_shape[si + 4][1]) + ((stencil_shape[si + 4][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            xoff5 = (stencil_shape[si + 5][0]) + (((stencil_shape[si + 5][1]) + ((stencil_shape[si + 5][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            {
              int hypre__i1start = ((start[0]) - ((x_data_box)->imin[0])) + ((((start[1]) - ((x_data_box)->imin[1])) + (((start[2]) - ((x_data_box)->imin[2])) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
              int hypre__i2start = ((start[0]) - ((y_data_box)->imin[0])) + ((((start[1]) - ((y_data_box)->imin[1])) + (((start[2]) - ((y_data_box)->imin[2])) * (0 < ((((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1) ? (((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1 : 0))) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0));
              int hypre__sx1 = stride[0];
              int hypre__sy1 = (stride[1]) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0);
              int hypre__sz1 = ((stride[2]) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0)) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0);
              int hypre__sx2 = stride[0];
              int hypre__sy2 = (stride[1]) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0);
              int hypre__sz2 = ((stride[2]) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0)) * (0 < ((((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1) ? (((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1 : 0);
              int hypre__nx = loop_size[0];
              int hypre__ny = loop_size[1];
              int hypre__nz = loop_size[2];
              int hypre__mx = hypre__nx;
              int hypre__my = hypre__ny;
              int hypre__mz = hypre__nz;
              int hypre__dir;
              int hypre__max;
              int hypre__div;
              int hypre__mod;
              int hypre__block;
              int hypre__num_blocks;
              hypre__dir = 0;
              hypre__max = hypre__nx;
              if (hypre__ny > hypre__max) {
                hypre__dir = 1;
                hypre__max = hypre__ny;
              }
              if (hypre__nz > hypre__max) {
                hypre__dir = 2;
                hypre__max = hypre__nz;
              }
              hypre__num_blocks = 1;
              if (hypre__max < hypre__num_blocks) {
                hypre__num_blocks = hypre__max;
              }
              if (hypre__num_blocks > 0) {
                hypre__div = hypre__max / hypre__num_blocks;
                hypre__mod = hypre__max % hypre__num_blocks;
              }
              ;
              ;
              for (hypre__block = 0; hypre__block < hypre__num_blocks; hypre__block++) {
                loopi = 0;
                loopj = 0;
                loopk = 0;
                hypre__nx = hypre__mx;
                hypre__ny = hypre__my;
                hypre__nz = hypre__mz;
                if (hypre__num_blocks > 1) {
                  if (hypre__dir == 0) {
                    loopi = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                    hypre__nx = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                  }
                  else
                    if (hypre__dir == 1) {
                      loopj = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                      hypre__ny = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                    }
                    else
                      if (hypre__dir == 2) {
                        loopk = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                        hypre__nz = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                      }
                }
                ;
                xi = ((hypre__i1start + (loopi * hypre__sx1)) + (loopj * hypre__sy1)) + (loopk * hypre__sz1);
                yi = ((hypre__i2start + (loopi * hypre__sx2)) + (loopj * hypre__sy2)) + (loopk * hypre__sz2);
                for (loopk = 0; loopk < hypre__nz; loopk++) {
                  for (loopj = 0; loopj < hypre__ny; loopj++) {
                    for (loopi = 0; loopi < hypre__nx; loopi++) {
                      {
                        yp[yi] += (((((AAp0 * (xp[xi + xoff0])) + (AAp1 * (xp[xi + xoff1]))) + (AAp2 * (xp[xi + xoff2]))) + (AAp3 * (xp[xi + xoff3]))) + (AAp4 * (xp[xi + xoff4]))) + (AAp5 * (xp[xi + xoff5]));
                      }
                      xi += hypre__sx1;
                      yi += hypre__sx2;
                    }
                    xi += hypre__sy1 - (hypre__nx * hypre__sx1);
                    yi += hypre__sy2 - (hypre__nx * hypre__sx2);
                  }
                  xi += hypre__sz1 - (hypre__ny * hypre__sy1);
                  yi += hypre__sz2 - (hypre__ny * hypre__sy2);
                }
              }
            }
            ;
            break;
          case 5:
            Ap0 = (A)->data + ((A)->data_indices[i][si + 0]);
            Ap1 = (A)->data + ((A)->data_indices[i][si + 1]);
            Ap2 = (A)->data + ((A)->data_indices[i][si + 2]);
            Ap3 = (A)->data + ((A)->data_indices[i][si + 3]);
            Ap4 = (A)->data + ((A)->data_indices[i][si + 4]);
            AAp0 = Ap0[Ai_CC];
            AAp1 = Ap1[Ai_CC];
            AAp2 = Ap2[Ai_CC];
            AAp3 = Ap3[Ai_CC];
            AAp4 = Ap4[Ai_CC];
            if ((0 <= (si_center - si)) && ((si_center - si) < 5)) {
              switch (si_center - si) {
                case 0:
                  AAp0 = 0;
                  break;
                case 1:
                  AAp1 = 0;
                  break;
                case 2:
                  AAp2 = 0;
                  break;
                case 3:
                  AAp3 = 0;
                  break;
                case 4:
                  AAp4 = 0;
                  break;
              }
            }
            xoff0 = (stencil_shape[si + 0][0]) + (((stencil_shape[si + 0][1]) + ((stencil_shape[si + 0][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            xoff1 = (stencil_shape[si + 1][0]) + (((stencil_shape[si + 1][1]) + ((stencil_shape[si + 1][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            xoff2 = (stencil_shape[si + 2][0]) + (((stencil_shape[si + 2][1]) + ((stencil_shape[si + 2][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            xoff3 = (stencil_shape[si + 3][0]) + (((stencil_shape[si + 3][1]) + ((stencil_shape[si + 3][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            xoff4 = (stencil_shape[si + 4][0]) + (((stencil_shape[si + 4][1]) + ((stencil_shape[si + 4][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            {
              int hypre__i1start = ((start[0]) - ((x_data_box)->imin[0])) + ((((start[1]) - ((x_data_box)->imin[1])) + (((start[2]) - ((x_data_box)->imin[2])) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
              int hypre__i2start = ((start[0]) - ((y_data_box)->imin[0])) + ((((start[1]) - ((y_data_box)->imin[1])) + (((start[2]) - ((y_data_box)->imin[2])) * (0 < ((((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1) ? (((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1 : 0))) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0));
              int hypre__sx1 = stride[0];
              int hypre__sy1 = (stride[1]) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0);
              int hypre__sz1 = ((stride[2]) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0)) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0);
              int hypre__sx2 = stride[0];
              int hypre__sy2 = (stride[1]) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0);
              int hypre__sz2 = ((stride[2]) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0)) * (0 < ((((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1) ? (((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1 : 0);
              int hypre__nx = loop_size[0];
              int hypre__ny = loop_size[1];
              int hypre__nz = loop_size[2];
              int hypre__mx = hypre__nx;
              int hypre__my = hypre__ny;
              int hypre__mz = hypre__nz;
              int hypre__dir;
              int hypre__max;
              int hypre__div;
              int hypre__mod;
              int hypre__block;
              int hypre__num_blocks;
              hypre__dir = 0;
              hypre__max = hypre__nx;
              if (hypre__ny > hypre__max) {
                hypre__dir = 1;
                hypre__max = hypre__ny;
              }
              if (hypre__nz > hypre__max) {
                hypre__dir = 2;
                hypre__max = hypre__nz;
              }
              hypre__num_blocks = 1;
              if (hypre__max < hypre__num_blocks) {
                hypre__num_blocks = hypre__max;
              }
              if (hypre__num_blocks > 0) {
                hypre__div = hypre__max / hypre__num_blocks;
                hypre__mod = hypre__max % hypre__num_blocks;
              }
              ;
              ;
              for (hypre__block = 0; hypre__block < hypre__num_blocks; hypre__block++) {
                loopi = 0;
                loopj = 0;
                loopk = 0;
                hypre__nx = hypre__mx;
                hypre__ny = hypre__my;
                hypre__nz = hypre__mz;
                if (hypre__num_blocks > 1) {
                  if (hypre__dir == 0) {
                    loopi = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                    hypre__nx = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                  }
                  else
                    if (hypre__dir == 1) {
                      loopj = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                      hypre__ny = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                    }
                    else
                      if (hypre__dir == 2) {
                        loopk = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                        hypre__nz = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                      }
                }
                ;
                xi = ((hypre__i1start + (loopi * hypre__sx1)) + (loopj * hypre__sy1)) + (loopk * hypre__sz1);
                yi = ((hypre__i2start + (loopi * hypre__sx2)) + (loopj * hypre__sy2)) + (loopk * hypre__sz2);
                for (loopk = 0; loopk < hypre__nz; loopk++) {
                  for (loopj = 0; loopj < hypre__ny; loopj++) {
                    for (loopi = 0; loopi < hypre__nx; loopi++) {
                      {
                        yp[yi] += ((((AAp0 * (xp[xi + xoff0])) + (AAp1 * (xp[xi + xoff1]))) + (AAp2 * (xp[xi + xoff2]))) + (AAp3 * (xp[xi + xoff3]))) + (AAp4 * (xp[xi + xoff4]));
                      }
                      xi += hypre__sx1;
                      yi += hypre__sx2;
                    }
                    xi += hypre__sy1 - (hypre__nx * hypre__sx1);
                    yi += hypre__sy2 - (hypre__nx * hypre__sx2);
                  }
                  xi += hypre__sz1 - (hypre__ny * hypre__sy1);
                  yi += hypre__sz2 - (hypre__ny * hypre__sy2);
                }
              }
            }
            ;
            break;
          case 4:
            Ap0 = (A)->data + ((A)->data_indices[i][si + 0]);
            Ap1 = (A)->data + ((A)->data_indices[i][si + 1]);
            Ap2 = (A)->data + ((A)->data_indices[i][si + 2]);
            Ap3 = (A)->data + ((A)->data_indices[i][si + 3]);
            AAp0 = Ap0[Ai_CC];
            AAp1 = Ap1[Ai_CC];
            AAp2 = Ap2[Ai_CC];
            AAp3 = Ap3[Ai_CC];
            if ((0 <= (si_center - si)) && ((si_center - si) < 4)) {
              switch (si_center - si) {
                case 0:
                  AAp0 = 0;
                  break;
                case 1:
                  AAp1 = 0;
                  break;
                case 2:
                  AAp2 = 0;
                  break;
                case 3:
                  AAp3 = 0;
                  break;
              }
            }
            xoff0 = (stencil_shape[si + 0][0]) + (((stencil_shape[si + 0][1]) + ((stencil_shape[si + 0][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            xoff1 = (stencil_shape[si + 1][0]) + (((stencil_shape[si + 1][1]) + ((stencil_shape[si + 1][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            xoff2 = (stencil_shape[si + 2][0]) + (((stencil_shape[si + 2][1]) + ((stencil_shape[si + 2][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            xoff3 = (stencil_shape[si + 3][0]) + (((stencil_shape[si + 3][1]) + ((stencil_shape[si + 3][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            {
              int hypre__i1start = ((start[0]) - ((x_data_box)->imin[0])) + ((((start[1]) - ((x_data_box)->imin[1])) + (((start[2]) - ((x_data_box)->imin[2])) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
              int hypre__i2start = ((start[0]) - ((y_data_box)->imin[0])) + ((((start[1]) - ((y_data_box)->imin[1])) + (((start[2]) - ((y_data_box)->imin[2])) * (0 < ((((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1) ? (((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1 : 0))) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0));
              int hypre__sx1 = stride[0];
              int hypre__sy1 = (stride[1]) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0);
              int hypre__sz1 = ((stride[2]) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0)) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0);
              int hypre__sx2 = stride[0];
              int hypre__sy2 = (stride[1]) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0);
              int hypre__sz2 = ((stride[2]) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0)) * (0 < ((((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1) ? (((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1 : 0);
              int hypre__nx = loop_size[0];
              int hypre__ny = loop_size[1];
              int hypre__nz = loop_size[2];
              int hypre__mx = hypre__nx;
              int hypre__my = hypre__ny;
              int hypre__mz = hypre__nz;
              int hypre__dir;
              int hypre__max;
              int hypre__div;
              int hypre__mod;
              int hypre__block;
              int hypre__num_blocks;
              hypre__dir = 0;
              hypre__max = hypre__nx;
              if (hypre__ny > hypre__max) {
                hypre__dir = 1;
                hypre__max = hypre__ny;
              }
              if (hypre__nz > hypre__max) {
                hypre__dir = 2;
                hypre__max = hypre__nz;
              }
              hypre__num_blocks = 1;
              if (hypre__max < hypre__num_blocks) {
                hypre__num_blocks = hypre__max;
              }
              if (hypre__num_blocks > 0) {
                hypre__div = hypre__max / hypre__num_blocks;
                hypre__mod = hypre__max % hypre__num_blocks;
              }
              ;
              ;
              for (hypre__block = 0; hypre__block < hypre__num_blocks; hypre__block++) {
                loopi = 0;
                loopj = 0;
                loopk = 0;
                hypre__nx = hypre__mx;
                hypre__ny = hypre__my;
                hypre__nz = hypre__mz;
                if (hypre__num_blocks > 1) {
                  if (hypre__dir == 0) {
                    loopi = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                    hypre__nx = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                  }
                  else
                    if (hypre__dir == 1) {
                      loopj = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                      hypre__ny = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                    }
                    else
                      if (hypre__dir == 2) {
                        loopk = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                        hypre__nz = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                      }
                }
                ;
                xi = ((hypre__i1start + (loopi * hypre__sx1)) + (loopj * hypre__sy1)) + (loopk * hypre__sz1);
                yi = ((hypre__i2start + (loopi * hypre__sx2)) + (loopj * hypre__sy2)) + (loopk * hypre__sz2);
                for (loopk = 0; loopk < hypre__nz; loopk++) {
                  for (loopj = 0; loopj < hypre__ny; loopj++) {
                    for (loopi = 0; loopi < hypre__nx; loopi++) {
                      {
                        yp[yi] += (((AAp0 * (xp[xi + xoff0])) + (AAp1 * (xp[xi + xoff1]))) + (AAp2 * (xp[xi + xoff2]))) + (AAp3 * (xp[xi + xoff3]));
                      }
                      xi += hypre__sx1;
                      yi += hypre__sx2;
                    }
                    xi += hypre__sy1 - (hypre__nx * hypre__sx1);
                    yi += hypre__sy2 - (hypre__nx * hypre__sx2);
                  }
                  xi += hypre__sz1 - (hypre__ny * hypre__sy1);
                  yi += hypre__sz2 - (hypre__ny * hypre__sy2);
                }
              }
            }
            ;
            break;
          case 3:
            Ap0 = (A)->data + ((A)->data_indices[i][si + 0]);
            Ap1 = (A)->data + ((A)->data_indices[i][si + 1]);
            Ap2 = (A)->data + ((A)->data_indices[i][si + 2]);
            AAp0 = Ap0[Ai_CC];
            AAp1 = Ap1[Ai_CC];
            AAp2 = Ap2[Ai_CC];
            if ((0 <= (si_center - si)) && ((si_center - si) < 3)) {
              switch (si_center - si) {
                case 0:
                  AAp0 = 0;
                  break;
                case 1:
                  AAp1 = 0;
                  break;
                case 2:
                  AAp2 = 0;
                  break;
              }
            }
            xoff0 = (stencil_shape[si + 0][0]) + (((stencil_shape[si + 0][1]) + ((stencil_shape[si + 0][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            xoff1 = (stencil_shape[si + 1][0]) + (((stencil_shape[si + 1][1]) + ((stencil_shape[si + 1][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            xoff2 = (stencil_shape[si + 2][0]) + (((stencil_shape[si + 2][1]) + ((stencil_shape[si + 2][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            {
              int hypre__i1start = ((start[0]) - ((x_data_box)->imin[0])) + ((((start[1]) - ((x_data_box)->imin[1])) + (((start[2]) - ((x_data_box)->imin[2])) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
              int hypre__i2start = ((start[0]) - ((y_data_box)->imin[0])) + ((((start[1]) - ((y_data_box)->imin[1])) + (((start[2]) - ((y_data_box)->imin[2])) * (0 < ((((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1) ? (((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1 : 0))) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0));
              int hypre__sx1 = stride[0];
              int hypre__sy1 = (stride[1]) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0);
              int hypre__sz1 = ((stride[2]) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0)) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0);
              int hypre__sx2 = stride[0];
              int hypre__sy2 = (stride[1]) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0);
              int hypre__sz2 = ((stride[2]) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0)) * (0 < ((((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1) ? (((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1 : 0);
              int hypre__nx = loop_size[0];
              int hypre__ny = loop_size[1];
              int hypre__nz = loop_size[2];
              int hypre__mx = hypre__nx;
              int hypre__my = hypre__ny;
              int hypre__mz = hypre__nz;
              int hypre__dir;
              int hypre__max;
              int hypre__div;
              int hypre__mod;
              int hypre__block;
              int hypre__num_blocks;
              hypre__dir = 0;
              hypre__max = hypre__nx;
              if (hypre__ny > hypre__max) {
                hypre__dir = 1;
                hypre__max = hypre__ny;
              }
              if (hypre__nz > hypre__max) {
                hypre__dir = 2;
                hypre__max = hypre__nz;
              }
              hypre__num_blocks = 1;
              if (hypre__max < hypre__num_blocks) {
                hypre__num_blocks = hypre__max;
              }
              if (hypre__num_blocks > 0) {
                hypre__div = hypre__max / hypre__num_blocks;
                hypre__mod = hypre__max % hypre__num_blocks;
              }
              ;
              ;
              for (hypre__block = 0; hypre__block < hypre__num_blocks; hypre__block++) {
                loopi = 0;
                loopj = 0;
                loopk = 0;
                hypre__nx = hypre__mx;
                hypre__ny = hypre__my;
                hypre__nz = hypre__mz;
                if (hypre__num_blocks > 1) {
                  if (hypre__dir == 0) {
                    loopi = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                    hypre__nx = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                  }
                  else
                    if (hypre__dir == 1) {
                      loopj = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                      hypre__ny = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                    }
                    else
                      if (hypre__dir == 2) {
                        loopk = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                        hypre__nz = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                      }
                }
                ;
                xi = ((hypre__i1start + (loopi * hypre__sx1)) + (loopj * hypre__sy1)) + (loopk * hypre__sz1);
                yi = ((hypre__i2start + (loopi * hypre__sx2)) + (loopj * hypre__sy2)) + (loopk * hypre__sz2);
                for (loopk = 0; loopk < hypre__nz; loopk++) {
                  for (loopj = 0; loopj < hypre__ny; loopj++) {
                    for (loopi = 0; loopi < hypre__nx; loopi++) {
                      {
                        yp[yi] += ((AAp0 * (xp[xi + xoff0])) + (AAp1 * (xp[xi + xoff1]))) + (AAp2 * (xp[xi + xoff2]));
                      }
                      xi += hypre__sx1;
                      yi += hypre__sx2;
                    }
                    xi += hypre__sy1 - (hypre__nx * hypre__sx1);
                    yi += hypre__sy2 - (hypre__nx * hypre__sx2);
                  }
                  xi += hypre__sz1 - (hypre__ny * hypre__sy1);
                  yi += hypre__sz2 - (hypre__ny * hypre__sy2);
                }
              }
            }
            ;
            break;
          case 2:
            Ap0 = (A)->data + ((A)->data_indices[i][si + 0]);
            Ap1 = (A)->data + ((A)->data_indices[i][si + 1]);
            AAp0 = Ap0[Ai_CC];
            AAp1 = Ap1[Ai_CC];
            if ((0 <= (si_center - si)) && ((si_center - si) < 2)) {
              switch (si_center - si) {
                case 0:
                  AAp0 = 0;
                  break;
                case 1:
                  AAp1 = 0;
                  break;
              }
            }
            xoff0 = (stencil_shape[si + 0][0]) + (((stencil_shape[si + 0][1]) + ((stencil_shape[si + 0][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            xoff1 = (stencil_shape[si + 1][0]) + (((stencil_shape[si + 1][1]) + ((stencil_shape[si + 1][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            {
              int hypre__i1start = ((start[0]) - ((x_data_box)->imin[0])) + ((((start[1]) - ((x_data_box)->imin[1])) + (((start[2]) - ((x_data_box)->imin[2])) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
              int hypre__i2start = ((start[0]) - ((y_data_box)->imin[0])) + ((((start[1]) - ((y_data_box)->imin[1])) + (((start[2]) - ((y_data_box)->imin[2])) * (0 < ((((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1) ? (((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1 : 0))) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0));
              int hypre__sx1 = stride[0];
              int hypre__sy1 = (stride[1]) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0);
              int hypre__sz1 = ((stride[2]) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0)) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0);
              int hypre__sx2 = stride[0];
              int hypre__sy2 = (stride[1]) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0);
              int hypre__sz2 = ((stride[2]) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0)) * (0 < ((((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1) ? (((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1 : 0);
              int hypre__nx = loop_size[0];
              int hypre__ny = loop_size[1];
              int hypre__nz = loop_size[2];
              int hypre__mx = hypre__nx;
              int hypre__my = hypre__ny;
              int hypre__mz = hypre__nz;
              int hypre__dir;
              int hypre__max;
              int hypre__div;
              int hypre__mod;
              int hypre__block;
              int hypre__num_blocks;
              hypre__dir = 0;
              hypre__max = hypre__nx;
              if (hypre__ny > hypre__max) {
                hypre__dir = 1;
                hypre__max = hypre__ny;
              }
              if (hypre__nz > hypre__max) {
                hypre__dir = 2;
                hypre__max = hypre__nz;
              }
              hypre__num_blocks = 1;
              if (hypre__max < hypre__num_blocks) {
                hypre__num_blocks = hypre__max;
              }
              if (hypre__num_blocks > 0) {
                hypre__div = hypre__max / hypre__num_blocks;
                hypre__mod = hypre__max % hypre__num_blocks;
              }
              ;
              ;
              for (hypre__block = 0; hypre__block < hypre__num_blocks; hypre__block++) {
                loopi = 0;
                loopj = 0;
                loopk = 0;
                hypre__nx = hypre__mx;
                hypre__ny = hypre__my;
                hypre__nz = hypre__mz;
                if (hypre__num_blocks > 1) {
                  if (hypre__dir == 0) {
                    loopi = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                    hypre__nx = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                  }
                  else
                    if (hypre__dir == 1) {
                      loopj = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                      hypre__ny = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                    }
                    else
                      if (hypre__dir == 2) {
                        loopk = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                        hypre__nz = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                      }
                }
                ;
                xi = ((hypre__i1start + (loopi * hypre__sx1)) + (loopj * hypre__sy1)) + (loopk * hypre__sz1);
                yi = ((hypre__i2start + (loopi * hypre__sx2)) + (loopj * hypre__sy2)) + (loopk * hypre__sz2);
                for (loopk = 0; loopk < hypre__nz; loopk++) {
                  for (loopj = 0; loopj < hypre__ny; loopj++) {
                    for (loopi = 0; loopi < hypre__nx; loopi++) {
                      {
                        yp[yi] += (AAp0 * (xp[xi + xoff0])) + (AAp1 * (xp[xi + xoff1]));
                      }
                      xi += hypre__sx1;
                      yi += hypre__sx2;
                    }
                    xi += hypre__sy1 - (hypre__nx * hypre__sx1);
                    yi += hypre__sy2 - (hypre__nx * hypre__sx2);
                  }
                  xi += hypre__sz1 - (hypre__ny * hypre__sy1);
                  yi += hypre__sz2 - (hypre__ny * hypre__sy2);
                }
              }
            }
            ;
            break;
          case 1:
            Ap0 = (A)->data + ((A)->data_indices[i][si + 0]);
            AAp0 = Ap0[Ai_CC];
            if ((si_center - si) == 0) {
              AAp0 = 0;
            }
            xoff0 = (stencil_shape[si + 0][0]) + (((stencil_shape[si + 0][1]) + ((stencil_shape[si + 0][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
            {
              int hypre__i1start = ((start[0]) - ((x_data_box)->imin[0])) + ((((start[1]) - ((x_data_box)->imin[1])) + (((start[2]) - ((x_data_box)->imin[2])) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
              int hypre__i2start = ((start[0]) - ((y_data_box)->imin[0])) + ((((start[1]) - ((y_data_box)->imin[1])) + (((start[2]) - ((y_data_box)->imin[2])) * (0 < ((((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1) ? (((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1 : 0))) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0));
              int hypre__sx1 = stride[0];
              int hypre__sy1 = (stride[1]) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0);
              int hypre__sz1 = ((stride[2]) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0)) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0);
              int hypre__sx2 = stride[0];
              int hypre__sy2 = (stride[1]) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0);
              int hypre__sz2 = ((stride[2]) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0)) * (0 < ((((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1) ? (((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1 : 0);
              int hypre__nx = loop_size[0];
              int hypre__ny = loop_size[1];
              int hypre__nz = loop_size[2];
              int hypre__mx = hypre__nx;
              int hypre__my = hypre__ny;
              int hypre__mz = hypre__nz;
              int hypre__dir;
              int hypre__max;
              int hypre__div;
              int hypre__mod;
              int hypre__block;
              int hypre__num_blocks;
              hypre__dir = 0;
              hypre__max = hypre__nx;
              if (hypre__ny > hypre__max) {
                hypre__dir = 1;
                hypre__max = hypre__ny;
              }
              if (hypre__nz > hypre__max) {
                hypre__dir = 2;
                hypre__max = hypre__nz;
              }
              hypre__num_blocks = 1;
              if (hypre__max < hypre__num_blocks) {
                hypre__num_blocks = hypre__max;
              }
              if (hypre__num_blocks > 0) {
                hypre__div = hypre__max / hypre__num_blocks;
                hypre__mod = hypre__max % hypre__num_blocks;
              }
              ;
              ;
              for (hypre__block = 0; hypre__block < hypre__num_blocks; hypre__block++) {
                loopi = 0;
                loopj = 0;
                loopk = 0;
                hypre__nx = hypre__mx;
                hypre__ny = hypre__my;
                hypre__nz = hypre__mz;
                if (hypre__num_blocks > 1) {
                  if (hypre__dir == 0) {
                    loopi = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                    hypre__nx = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                  }
                  else
                    if (hypre__dir == 1) {
                      loopj = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                      hypre__ny = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                    }
                    else
                      if (hypre__dir == 2) {
                        loopk = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                        hypre__nz = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                      }
                }
                ;
                xi = ((hypre__i1start + (loopi * hypre__sx1)) + (loopj * hypre__sy1)) + (loopk * hypre__sz1);
                yi = ((hypre__i2start + (loopi * hypre__sx2)) + (loopj * hypre__sy2)) + (loopk * hypre__sz2);
                for (loopk = 0; loopk < hypre__nz; loopk++) {
                  for (loopj = 0; loopj < hypre__ny; loopj++) {
                    for (loopi = 0; loopi < hypre__nx; loopi++) {
                      {
                        yp[yi] += AAp0 * (xp[xi + xoff0]);
                      }
                      xi += hypre__sx1;
                      yi += hypre__sx2;
                    }
                    xi += hypre__sy1 - (hypre__nx * hypre__sx1);
                    yi += hypre__sy2 - (hypre__nx * hypre__sx2);
                  }
                  xi += hypre__sz1 - (hypre__ny * hypre__sy1);
                  yi += hypre__sz2 - (hypre__ny * hypre__sy2);
                }
              }
            }
            ;
            break;
        }
      }
      Ap0 = (A)->data + ((A)->data_indices[i][si_center]);
      xoff0 = (stencil_shape[si_center][0]) + (((stencil_shape[si_center][1]) + ((stencil_shape[si_center][2]) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
      if (alpha != 1.0) {
        {
          int hypre__i1start = ((start[0]) - ((A_data_box)->imin[0])) + ((((start[1]) - ((A_data_box)->imin[1])) + (((start[2]) - ((A_data_box)->imin[2])) * (0 < ((((A_data_box)->imax[1]) - ((A_data_box)->imin[1])) + 1) ? (((A_data_box)->imax[1]) - ((A_data_box)->imin[1])) + 1 : 0))) * (0 < ((((A_data_box)->imax[0]) - ((A_data_box)->imin[0])) + 1) ? (((A_data_box)->imax[0]) - ((A_data_box)->imin[0])) + 1 : 0));
          int hypre__i2start = ((start[0]) - ((x_data_box)->imin[0])) + ((((start[1]) - ((x_data_box)->imin[1])) + (((start[2]) - ((x_data_box)->imin[2])) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
          int hypre__i3start = ((start[0]) - ((y_data_box)->imin[0])) + ((((start[1]) - ((y_data_box)->imin[1])) + (((start[2]) - ((y_data_box)->imin[2])) * (0 < ((((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1) ? (((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1 : 0))) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0));
          int hypre__sx1 = stride[0];
          int hypre__sy1 = (stride[1]) * (0 < ((((A_data_box)->imax[0]) - ((A_data_box)->imin[0])) + 1) ? (((A_data_box)->imax[0]) - ((A_data_box)->imin[0])) + 1 : 0);
          int hypre__sz1 = ((stride[2]) * (0 < ((((A_data_box)->imax[0]) - ((A_data_box)->imin[0])) + 1) ? (((A_data_box)->imax[0]) - ((A_data_box)->imin[0])) + 1 : 0)) * (0 < ((((A_data_box)->imax[1]) - ((A_data_box)->imin[1])) + 1) ? (((A_data_box)->imax[1]) - ((A_data_box)->imin[1])) + 1 : 0);
          int hypre__sx2 = stride[0];
          int hypre__sy2 = (stride[1]) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0);
          int hypre__sz2 = ((stride[2]) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0)) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0);
          int hypre__sx3 = stride[0];
          int hypre__sy3 = (stride[1]) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0);
          int hypre__sz3 = ((stride[2]) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0)) * (0 < ((((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1) ? (((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1 : 0);
          int hypre__nx = loop_size[0];
          int hypre__ny = loop_size[1];
          int hypre__nz = loop_size[2];
          int hypre__mx = hypre__nx;
          int hypre__my = hypre__ny;
          int hypre__mz = hypre__nz;
          int hypre__dir;
          int hypre__max;
          int hypre__div;
          int hypre__mod;
          int hypre__block;
          int hypre__num_blocks;
          hypre__dir = 0;
          hypre__max = hypre__nx;
          if (hypre__ny > hypre__max) {
            hypre__dir = 1;
            hypre__max = hypre__ny;
          }
          if (hypre__nz > hypre__max) {
            hypre__dir = 2;
            hypre__max = hypre__nz;
          }
          hypre__num_blocks = 1;
          if (hypre__max < hypre__num_blocks) {
            hypre__num_blocks = hypre__max;
          }
          if (hypre__num_blocks > 0) {
            hypre__div = hypre__max / hypre__num_blocks;
            hypre__mod = hypre__max % hypre__num_blocks;
          }
          ;
          ;
          for (hypre__block = 0; hypre__block < hypre__num_blocks; hypre__block++) {
            loopi = 0;
            loopj = 0;
            loopk = 0;
            hypre__nx = hypre__mx;
            hypre__ny = hypre__my;
            hypre__nz = hypre__mz;
            if (hypre__num_blocks > 1) {
              if (hypre__dir == 0) {
                loopi = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                hypre__nx = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
              }
              else
                if (hypre__dir == 1) {
                  loopj = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                  hypre__ny = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                }
                else
                  if (hypre__dir == 2) {
                    loopk = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                    hypre__nz = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                  }
            }
            ;
            Ai = ((hypre__i1start + (loopi * hypre__sx1)) + (loopj * hypre__sy1)) + (loopk * hypre__sz1);
            xi = ((hypre__i2start + (loopi * hypre__sx2)) + (loopj * hypre__sy2)) + (loopk * hypre__sz2);
            yi = ((hypre__i3start + (loopi * hypre__sx3)) + (loopj * hypre__sy3)) + (loopk * hypre__sz3);
            for (loopk = 0; loopk < hypre__nz; loopk++) {
              for (loopj = 0; loopj < hypre__ny; loopj++) {
                for (loopi = 0; loopi < hypre__nx; loopi++) {
                  {
                    yp[yi] = alpha * ((yp[yi]) + ((Ap0[Ai]) * (xp[xi + xoff0])));
                  }
                  Ai += hypre__sx1;
                  xi += hypre__sx2;
                  yi += hypre__sx3;
                }
                Ai += hypre__sy1 - (hypre__nx * hypre__sx1);
                xi += hypre__sy2 - (hypre__nx * hypre__sx2);
                yi += hypre__sy3 - (hypre__nx * hypre__sx3);
              }
              Ai += hypre__sz1 - (hypre__ny * hypre__sy1);
              xi += hypre__sz2 - (hypre__ny * hypre__sy2);
              yi += hypre__sz3 - (hypre__ny * hypre__sy3);
            }
          }
        }
        ;
      }
      else {
        {
          int hypre__i1start = ((start[0]) - ((A_data_box)->imin[0])) + ((((start[1]) - ((A_data_box)->imin[1])) + (((start[2]) - ((A_data_box)->imin[2])) * (0 < ((((A_data_box)->imax[1]) - ((A_data_box)->imin[1])) + 1) ? (((A_data_box)->imax[1]) - ((A_data_box)->imin[1])) + 1 : 0))) * (0 < ((((A_data_box)->imax[0]) - ((A_data_box)->imin[0])) + 1) ? (((A_data_box)->imax[0]) - ((A_data_box)->imin[0])) + 1 : 0));
          int hypre__i2start = ((start[0]) - ((x_data_box)->imin[0])) + ((((start[1]) - ((x_data_box)->imin[1])) + (((start[2]) - ((x_data_box)->imin[2])) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0))) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0));
          int hypre__i3start = ((start[0]) - ((y_data_box)->imin[0])) + ((((start[1]) - ((y_data_box)->imin[1])) + (((start[2]) - ((y_data_box)->imin[2])) * (0 < ((((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1) ? (((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1 : 0))) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0));
          int hypre__sx1 = stride[0];
          int hypre__sy1 = (stride[1]) * (0 < ((((A_data_box)->imax[0]) - ((A_data_box)->imin[0])) + 1) ? (((A_data_box)->imax[0]) - ((A_data_box)->imin[0])) + 1 : 0);
          int hypre__sz1 = ((stride[2]) * (0 < ((((A_data_box)->imax[0]) - ((A_data_box)->imin[0])) + 1) ? (((A_data_box)->imax[0]) - ((A_data_box)->imin[0])) + 1 : 0)) * (0 < ((((A_data_box)->imax[1]) - ((A_data_box)->imin[1])) + 1) ? (((A_data_box)->imax[1]) - ((A_data_box)->imin[1])) + 1 : 0);
          int hypre__sx2 = stride[0];
          int hypre__sy2 = (stride[1]) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0);
          int hypre__sz2 = ((stride[2]) * (0 < ((((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1) ? (((x_data_box)->imax[0]) - ((x_data_box)->imin[0])) + 1 : 0)) * (0 < ((((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1) ? (((x_data_box)->imax[1]) - ((x_data_box)->imin[1])) + 1 : 0);
          int hypre__sx3 = stride[0];
          int hypre__sy3 = (stride[1]) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0);
          int hypre__sz3 = ((stride[2]) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0)) * (0 < ((((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1) ? (((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1 : 0);
          int hypre__nx = loop_size[0];
          int hypre__ny = loop_size[1];
          int hypre__nz = loop_size[2];
          int hypre__mx = hypre__nx;
          int hypre__my = hypre__ny;
          int hypre__mz = hypre__nz;
          int hypre__dir;
          int hypre__max;
          int hypre__div;
          int hypre__mod;
          int hypre__block;
          int hypre__num_blocks;
          hypre__dir = 0;
          hypre__max = hypre__nx;
          if (hypre__ny > hypre__max) {
            hypre__dir = 1;
            hypre__max = hypre__ny;
          }
          if (hypre__nz > hypre__max) {
            hypre__dir = 2;
            hypre__max = hypre__nz;
          }
          hypre__num_blocks = 1;
          if (hypre__max < hypre__num_blocks) {
            hypre__num_blocks = hypre__max;
          }
          if (hypre__num_blocks > 0) {
            hypre__div = hypre__max / hypre__num_blocks;
            hypre__mod = hypre__max % hypre__num_blocks;
          }
          ;
          ;
          for (hypre__block = 0; hypre__block < hypre__num_blocks; hypre__block++) {
            loopi = 0;
            loopj = 0;
            loopk = 0;
            hypre__nx = hypre__mx;
            hypre__ny = hypre__my;
            hypre__nz = hypre__mz;
            if (hypre__num_blocks > 1) {
              if (hypre__dir == 0) {
                loopi = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                hypre__nx = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
              }
              else
                if (hypre__dir == 1) {
                  loopj = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                  hypre__ny = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                }
                else
                  if (hypre__dir == 2) {
                    loopk = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                    hypre__nz = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                  }
            }
            ;
            Ai = ((hypre__i1start + (loopi * hypre__sx1)) + (loopj * hypre__sy1)) + (loopk * hypre__sz1);
            xi = ((hypre__i2start + (loopi * hypre__sx2)) + (loopj * hypre__sy2)) + (loopk * hypre__sz2);
            yi = ((hypre__i3start + (loopi * hypre__sx3)) + (loopj * hypre__sy3)) + (loopk * hypre__sz3);
            for (loopk = 0; loopk < hypre__nz; loopk++) {
              for (loopj = 0; loopj < hypre__ny; loopj++) {
                for (loopi = 0; loopi < hypre__nx; loopi++) {
                  {
                    yp[yi] += (Ap0[Ai]) * (xp[xi + xoff0]);
                  }
                  Ai += hypre__sx1;
                  xi += hypre__sx2;
                  yi += hypre__sx3;
                }
                Ai += hypre__sy1 - (hypre__nx * hypre__sx1);
                xi += hypre__sy2 - (hypre__nx * hypre__sx2);
                yi += hypre__sy3 - (hypre__nx * hypre__sx3);
              }
              Ai += hypre__sz1 - (hypre__ny * hypre__sy1);
              xi += hypre__sz2 - (hypre__ny * hypre__sy2);
              yi += hypre__sz3 - (hypre__ny * hypre__sy3);
            }
          }
        }
        ;
      }
    }
  }
  return ierr;
}
int hypre_StructMatvecDestroy(void* matvec_vdata) {
  int ierr = 0;
  hypre_StructMatvecData* matvec_data = matvec_vdata;
  if (matvec_data) {
    hypre_StructMatrixDestroy((matvec_data)->A);
    hypre_StructVectorDestroy((matvec_data)->x);
    hypre_ComputePkgDestroy((matvec_data)->compute_pkg);
    hypre_Free((char*)matvec_data), matvec_data = (void*)0;
  }
  return ierr;
}
//===================== struct_scale.c =====================
int hypre_StructScale(double alpha, hypre_StructVector* y) {
  int ierr = 0;
  hypre_Box* y_data_box;
  int yi;
  double* yp;
  hypre_BoxArray* boxes;
  hypre_Box* box;
  hypre_Index loop_size;
  hypre_IndexRef start;
  hypre_Index unit_stride;
  int i;
  int loopi;
  int loopj;
  int loopk;
  unit_stride[0] = 1, unit_stride[1] = 1, unit_stride[2] = 1;
  boxes = ((y)->grid)->boxes;
  for (i = 0; i < (boxes)->size; i++) {
    box = &((boxes)->boxes[i]);
    start = (box)->imin;
    y_data_box = &(((y)->data_space)->boxes[i]);
    yp = (y)->data + ((y)->data_indices[i]);
    hypre_BoxGetSize(box, loop_size);
    {
      int hypre__i1start = ((start[0]) - ((y_data_box)->imin[0])) + ((((start[1]) - ((y_data_box)->imin[1])) + (((start[2]) - ((y_data_box)->imin[2])) * (0 < ((((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1) ? (((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1 : 0))) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0));
      int hypre__sx1 = unit_stride[0];
      int hypre__sy1 = (unit_stride[1]) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0);
      int hypre__sz1 = ((unit_stride[2]) * (0 < ((((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1) ? (((y_data_box)->imax[0]) - ((y_data_box)->imin[0])) + 1 : 0)) * (0 < ((((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1) ? (((y_data_box)->imax[1]) - ((y_data_box)->imin[1])) + 1 : 0);
      int hypre__nx = loop_size[0];
      int hypre__ny = loop_size[1];
      int hypre__nz = loop_size[2];
      int hypre__mx = hypre__nx;
      int hypre__my = hypre__ny;
      int hypre__mz = hypre__nz;
      int hypre__dir;
      int hypre__max;
      int hypre__div;
      int hypre__mod;
      int hypre__block;
      int hypre__num_blocks;
      hypre__dir = 0;
      hypre__max = hypre__nx;
      if (hypre__ny > hypre__max) {
        hypre__dir = 1;
        hypre__max = hypre__ny;
      }
      if (hypre__nz > hypre__max) {
        hypre__dir = 2;
        hypre__max = hypre__nz;
      }
      hypre__num_blocks = 1;
      if (hypre__max < hypre__num_blocks) {
        hypre__num_blocks = hypre__max;
      }
      if (hypre__num_blocks > 0) {
        hypre__div = hypre__max / hypre__num_blocks;
        hypre__mod = hypre__max % hypre__num_blocks;
      }
      ;
      ;
      for (hypre__block = 0; hypre__block < hypre__num_blocks; hypre__block++) {
        loopi = 0;
        loopj = 0;
        loopk = 0;
        hypre__nx = hypre__mx;
        hypre__ny = hypre__my;
        hypre__nz = hypre__mz;
        if (hypre__num_blocks > 1) {
          if (hypre__dir == 0) {
            loopi = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
            hypre__nx = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
          }
          else
            if (hypre__dir == 1) {
              loopj = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
              hypre__ny = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
            }
            else
              if (hypre__dir == 2) {
                loopk = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                hypre__nz = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
              }
        }
        ;
        yi = ((hypre__i1start + (loopi * hypre__sx1)) + (loopj * hypre__sy1)) + (loopk * hypre__sz1);
        for (loopk = 0; loopk < hypre__nz; loopk++) {
          for (loopj = 0; loopj < hypre__ny; loopj++) {
            for (loopi = 0; loopi < hypre__nx; loopi++) {
              {
                (yp[yi]) -= alpha;
              }
              yi += hypre__sx1;
            }
            yi += hypre__sy1 - (hypre__nx * hypre__sx1);
          }
          yi += hypre__sz1 - (hypre__ny * hypre__sy1);
        }
      }
    }
    ;
  }
  return ierr;
}
//==================== struct_stencil.c ====================
hypre_StructStencil* hypre_StructStencilCreate(int dim, int size, hypre_Index* shape) {
  hypre_StructStencil* stencil;
  int abs_offset;
  int max_offset;
  int s;
  int d;
  stencil = (hypre_StructStencil*)(hypre_MAlloc((unsigned)(sizeof(hypre_StructStencil) * 1)));
  (stencil)->shape = shape;
  (stencil)->size = size;
  (stencil)->dim = dim;
  (stencil)->ref_count = 1;
  max_offset = 0;
  for (s = 0; s < size; s++) {
    for (d = 0; d < 3; d++) {
      abs_offset = shape[s][d];
      abs_offset = abs_offset < 0 ? -abs_offset : abs_offset;
      max_offset = abs_offset < max_offset ? max_offset : abs_offset;
    }
  }
  (stencil)->max_offset = max_offset;
  return stencil;
}
hypre_StructStencil* hypre_StructStencilRef(hypre_StructStencil* stencil) {
  (stencil)->ref_count++;
  return stencil;
}
int hypre_StructStencilDestroy(hypre_StructStencil* stencil) {
  int ierr = 0;
  if (stencil) {
    (stencil)->ref_count--;
    if ((stencil)->ref_count == 0) {
      hypre_Free((char*)((stencil)->shape)), (stencil)->shape = (void*)0;
      hypre_Free((char*)stencil), stencil = (void*)0;
    }
  }
  return ierr;
}
int hypre_StructStencilElementRank(hypre_StructStencil* stencil, hypre_Index stencil_element) {
  hypre_Index* stencil_shape;
  int rank;
  int i;
  rank = -1;
  stencil_shape = (stencil)->shape;
  for (i = 0; i < (stencil)->size; i++) {
    if ((((stencil_shape[i][0]) == (stencil_element[0])) && ((stencil_shape[i][1]) == (stencil_element[1]))) && ((stencil_shape[i][2]) == (stencil_element[2]))) {
      rank = i;
      break;
    }
  }
  return rank;
}
int hypre_StructStencilSymmetrize(hypre_StructStencil* stencil, hypre_StructStencil** symm_stencil_ptr, int** symm_elements_ptr) {
  hypre_Index* stencil_shape = (stencil)->shape;
  int stencil_size = (stencil)->size;
  hypre_StructStencil* symm_stencil;
  hypre_Index* symm_stencil_shape;
  int symm_stencil_size;
  int* symm_elements;
  int no_symmetric_stencil_element;
  int i;
  int j;
  int d;
  int ierr = 0;
  symm_stencil_shape = (hypre_Index*)(hypre_CAlloc((unsigned)(2 * stencil_size), (unsigned)(sizeof(hypre_Index))));
  for (i = 0; i < stencil_size; i++) {
    symm_stencil_shape[i][0] = stencil_shape[i][0], symm_stencil_shape[i][1] = stencil_shape[i][1], symm_stencil_shape[i][2] = stencil_shape[i][2];
  }
  symm_elements = (int*)(hypre_CAlloc((unsigned)(2 * stencil_size), (unsigned)(sizeof(int))));
  for (i = 0; i < (2 * stencil_size); i++)
    symm_elements[i] = -1;
  symm_stencil_size = stencil_size;
  for (i = 0; i < stencil_size; i++) {
    if ((symm_elements[i]) < 0) {
      no_symmetric_stencil_element = 1;
      for (j = i; j < stencil_size; j++) {
        if ((((symm_stencil_shape[j][0]) == (-(symm_stencil_shape[i][0]))) && ((symm_stencil_shape[j][1]) == (-(symm_stencil_shape[i][1])))) && ((symm_stencil_shape[j][2]) == (-(symm_stencil_shape[i][2])))) {
          if (i != j)
            symm_elements[j] = i;
          no_symmetric_stencil_element = 0;
        }
      }
      if (no_symmetric_stencil_element) {
        for (d = 0; d < 3; d++) {
          symm_stencil_shape[symm_stencil_size][d] = -(symm_stencil_shape[i][d]);
        }
        symm_elements[symm_stencil_size] = i;
        symm_stencil_size++;
      }
    }
  }
  symm_stencil = hypre_StructStencilCreate((stencil)->dim, symm_stencil_size, symm_stencil_shape);
  *symm_stencil_ptr = symm_stencil;
  *symm_elements_ptr = symm_elements;
  return ierr;
}
//===================== struct_vector.c ====================
hypre_StructVector* hypre_StructVectorCreate(MPI_Comm comm, hypre_StructGrid* grid) {
  hypre_StructVector* vector;
  int i;
  vector = (hypre_StructVector*)(hypre_CAlloc((unsigned)1, (unsigned)(sizeof(hypre_StructVector))));
  (vector)->comm = comm;
  hypre_StructGridRef(grid, &((vector)->grid));
  (vector)->data_alloced = 1;
  (vector)->OffProcAdd = 0;
  (vector)->ref_count = 1;
  for (i = 0; i < 6; i++) {
    (vector)->num_ghost[i] = 1;
    (vector)->add_num_ghost[i] = 1;
  }
  return vector;
}
hypre_StructVector* hypre_StructVectorRef(hypre_StructVector* vector) {
  (vector)->ref_count++;
  return vector;
}
int hypre_StructVectorDestroy(hypre_StructVector* vector) {
  int ierr = 0;
  if (vector) {
    (vector)->ref_count--;
    if ((vector)->ref_count == 0) {
      if ((vector)->data_alloced) {
        hypre_Free((char*)((vector)->data)), (vector)->data = (void*)0;
      }
      hypre_Free((char*)((vector)->data_indices)), (vector)->data_indices = (void*)0;
      hypre_BoxArrayDestroy((vector)->data_space);
      hypre_StructGridDestroy((vector)->grid);
      hypre_Free((char*)vector), vector = (void*)0;
    }
  }
  return ierr;
}
int hypre_StructVectorInitializeShell(hypre_StructVector* vector) {
  int ierr = 0;
  hypre_StructGrid* grid;
  int* num_ghost;
  hypre_BoxArray* data_space;
  hypre_BoxArray* boxes;
  hypre_Box* box;
  hypre_Box* data_box;
  int* data_indices;
  int data_size;
  int i;
  int d;
  grid = (vector)->grid;
  if ((vector)->data_space == (void*)0) {
    num_ghost = (vector)->num_ghost;
    boxes = (grid)->boxes;
    data_space = hypre_BoxArrayCreate((boxes)->size);
    for (i = 0; i < (boxes)->size; i++) {
      box = &((boxes)->boxes[i]);
      data_box = &((data_space)->boxes[i]);
      (data_box)->imin[0] = (box)->imin[0], (data_box)->imin[1] = (box)->imin[1], (data_box)->imin[2] = (box)->imin[2], (data_box)->imax[0] = (box)->imax[0], (data_box)->imax[1] = (box)->imax[1], (data_box)->imax[2] = (box)->imax[2];
      for (d = 0; d < 3; d++) {
        ((data_box)->imin[d]) -= (num_ghost[2 * d]);
        (data_box)->imax[d] += num_ghost[(2 * d) + 1];
      }
    }
    (vector)->data_space = data_space;
  }
  if ((vector)->data_indices == (void*)0) {
    data_space = (vector)->data_space;
    data_indices = (int*)(hypre_CAlloc((unsigned)((data_space)->size), (unsigned)(sizeof(int))));
    data_size = 0;
    for (i = 0; i < (data_space)->size; i++) {
      data_box = &((data_space)->boxes[i]);
      data_indices[i] = data_size;
      data_size += ((0 < ((((data_box)->imax[0]) - ((data_box)->imin[0])) + 1) ? (((data_box)->imax[0]) - ((data_box)->imin[0])) + 1 : 0) * (0 < ((((data_box)->imax[1]) - ((data_box)->imin[1])) + 1) ? (((data_box)->imax[1]) - ((data_box)->imin[1])) + 1 : 0)) * (0 < ((((data_box)->imax[2]) - ((data_box)->imin[2])) + 1) ? (((data_box)->imax[2]) - ((data_box)->imin[2])) + 1 : 0);
    }
    (vector)->data_indices = data_indices;
    (vector)->data_size = data_size;
  }
  (vector)->global_size = (grid)->global_size;
  return ierr;
}
int hypre_StructVectorInitializeData(hypre_StructVector* vector, double* data) {
  int ierr = 0;
  (vector)->data = data;
  (vector)->data_alloced = 0;
  return ierr;
}
int hypre_StructVectorSetBoxValues(hypre_StructVector* vector, hypre_Box* value_box, double* values, int add_to) {
  int ierr = 0;
  MPI_Comm comm = (vector)->comm;
  int* add_num_ghost = (vector)->add_num_ghost;
  hypre_BoxArray* grid_boxes;
  hypre_Box* grid_box;
  hypre_BoxArray* box_array1;
  hypre_BoxArray* box_array2;
  hypre_BoxArray* tmp_box_array;
  hypre_BoxArray* value_boxarray;
  hypre_BoxArrayArray* box_aarray;
  hypre_Box* box;
  hypre_Box* tmp_box;
  hypre_Box* orig_box;
  hypre_Box* vbox;
  hypre_BoxArray* data_space;
  hypre_Box* data_box;
  hypre_IndexRef data_start;
  hypre_Index data_stride;
  int datai;
  double* datap;
  hypre_Box* dval_box;
  hypre_Index dval_start;
  hypre_Index dval_stride;
  int dvali;
  hypre_Index loop_size;
  int i;
  int j;
  int k;
  int vol_vbox;
  int vol_iboxes;
  int vol_offproc;
  int loopi;
  int loopj;
  int loopk;
  int nprocs;
  MPI_Comm_size(comm, &(nprocs));
  vol_vbox = ((0 < ((((value_box)->imax[0]) - ((value_box)->imin[0])) + 1) ? (((value_box)->imax[0]) - ((value_box)->imin[0])) + 1 : 0) * (0 < ((((value_box)->imax[1]) - ((value_box)->imin[1])) + 1) ? (((value_box)->imax[1]) - ((value_box)->imin[1])) + 1 : 0)) * (0 < ((((value_box)->imax[2]) - ((value_box)->imin[2])) + 1) ? (((value_box)->imax[2]) - ((value_box)->imin[2])) + 1 : 0);
  vol_iboxes = 0;
  grid_boxes = ((vector)->grid)->boxes;
  box_array1 = hypre_BoxArrayCreate((grid_boxes)->size);
  box = hypre_BoxCreate();
  for (i = 0; i < (grid_boxes)->size; i++) {
    grid_box = &((grid_boxes)->boxes[i]);
    hypre_IntersectBoxes(value_box, grid_box, box);
    (&((box_array1)->boxes[i]))->imin[0] = (box)->imin[0], (&((box_array1)->boxes[i]))->imin[1] = (box)->imin[1], (&((box_array1)->boxes[i]))->imin[2] = (box)->imin[2], (&((box_array1)->boxes[i]))->imax[0] = (box)->imax[0], (&((box_array1)->boxes[i]))->imax[1] = (box)->imax[1], (&((box_array1)->boxes[i]))->imax[2] = (box)->imax[2];
    vol_iboxes += ((0 < ((((box)->imax[0]) - ((box)->imin[0])) + 1) ? (((box)->imax[0]) - ((box)->imin[0])) + 1 : 0) * (0 < ((((box)->imax[1]) - ((box)->imin[1])) + 1) ? (((box)->imax[1]) - ((box)->imin[1])) + 1 : 0)) * (0 < ((((box)->imax[2]) - ((box)->imin[2])) + 1) ? (((box)->imax[2]) - ((box)->imin[2])) + 1 : 0);
  }
  vol_offproc = 0;
  if (((vol_vbox > vol_iboxes) && add_to) && (nprocs > 1)) {
    box_aarray = hypre_BoxArrayArrayCreate((grid_boxes)->size);
    value_boxarray = hypre_BoxArrayCreate(0);
    hypre_AppendBox(value_box, value_boxarray);
    for (i = 0; i < (grid_boxes)->size; i++) {
      tmp_box_array = hypre_BoxArrayCreate(0);
      orig_box = &((grid_boxes)->boxes[i]);
      tmp_box = hypre_BoxDuplicate(orig_box);
      for (j = 0; j < 3; j++) {
        ((tmp_box)->imin[j]) -= (add_num_ghost[2 * j]);
        (tmp_box)->imax[j] += add_num_ghost[(2 * j) + 1];
      }
      hypre_SubtractBoxes(tmp_box, orig_box, tmp_box_array);
      hypre_BoxDestroy(tmp_box);
      box_array2 = (box_aarray)->box_arrays[i];
      for (j = 0; j < (tmp_box_array)->size; j++) {
        tmp_box = &((tmp_box_array)->boxes[j]);
        for (k = 0; k < (value_boxarray)->size; k++) {
          vbox = &((value_boxarray)->boxes[k]);
          hypre_IntersectBoxes(vbox, tmp_box, box);
          hypre_AppendBox(box, box_array2);
          vol_offproc += ((0 < ((((box)->imax[0]) - ((box)->imin[0])) + 1) ? (((box)->imax[0]) - ((box)->imin[0])) + 1 : 0) * (0 < ((((box)->imax[1]) - ((box)->imin[1])) + 1) ? (((box)->imax[1]) - ((box)->imin[1])) + 1 : 0)) * (0 < ((((box)->imax[2]) - ((box)->imin[2])) + 1) ? (((box)->imax[2]) - ((box)->imin[2])) + 1 : 0);
        }
      }
      hypre_SubtractBoxArrays(value_boxarray, box_array2, tmp_box_array);
      hypre_BoxArrayDestroy(tmp_box_array);
    }
    if (!vol_offproc) {
      hypre_BoxArrayArrayDestroy(box_aarray);
    }
    else {
      (vector)->OffProcAdd = 1;
    }
    hypre_BoxArrayDestroy(value_boxarray);
  }
  hypre_BoxDestroy(box);
  if (box_array1) {
    data_space = (vector)->data_space;
    data_stride[0] = 1, data_stride[1] = 1, data_stride[2] = 1;
    dval_box = hypre_BoxDuplicate(value_box);
    dval_stride[0] = 1, dval_stride[1] = 1, dval_stride[2] = 1;
    for (i = 0; i < (box_array1)->size; i++) {
      box = &((box_array1)->boxes[i]);
      data_box = &((data_space)->boxes[i]);
      if (box) {
        data_start = (box)->imin;
        dval_start[0] = data_start[0], dval_start[1] = data_start[1], dval_start[2] = data_start[2];
        datap = (vector)->data + ((vector)->data_indices[i]);
        hypre_BoxGetSize(box, loop_size);
        if (add_to) {
          {
            int hypre__i1start = ((data_start[0]) - ((data_box)->imin[0])) + ((((data_start[1]) - ((data_box)->imin[1])) + (((data_start[2]) - ((data_box)->imin[2])) * (0 < ((((data_box)->imax[1]) - ((data_box)->imin[1])) + 1) ? (((data_box)->imax[1]) - ((data_box)->imin[1])) + 1 : 0))) * (0 < ((((data_box)->imax[0]) - ((data_box)->imin[0])) + 1) ? (((data_box)->imax[0]) - ((data_box)->imin[0])) + 1 : 0));
            int hypre__i2start = ((dval_start[0]) - ((dval_box)->imin[0])) + ((((dval_start[1]) - ((dval_box)->imin[1])) + (((dval_start[2]) - ((dval_box)->imin[2])) * (0 < ((((dval_box)->imax[1]) - ((dval_box)->imin[1])) + 1) ? (((dval_box)->imax[1]) - ((dval_box)->imin[1])) + 1 : 0))) * (0 < ((((dval_box)->imax[0]) - ((dval_box)->imin[0])) + 1) ? (((dval_box)->imax[0]) - ((dval_box)->imin[0])) + 1 : 0));
            int hypre__sx1 = data_stride[0];
            int hypre__sy1 = (data_stride[1]) * (0 < ((((data_box)->imax[0]) - ((data_box)->imin[0])) + 1) ? (((data_box)->imax[0]) - ((data_box)->imin[0])) + 1 : 0);
            int hypre__sz1 = ((data_stride[2]) * (0 < ((((data_box)->imax[0]) - ((data_box)->imin[0])) + 1) ? (((data_box)->imax[0]) - ((data_box)->imin[0])) + 1 : 0)) * (0 < ((((data_box)->imax[1]) - ((data_box)->imin[1])) + 1) ? (((data_box)->imax[1]) - ((data_box)->imin[1])) + 1 : 0);
            int hypre__sx2 = dval_stride[0];
            int hypre__sy2 = (dval_stride[1]) * (0 < ((((dval_box)->imax[0]) - ((dval_box)->imin[0])) + 1) ? (((dval_box)->imax[0]) - ((dval_box)->imin[0])) + 1 : 0);
            int hypre__sz2 = ((dval_stride[2]) * (0 < ((((dval_box)->imax[0]) - ((dval_box)->imin[0])) + 1) ? (((dval_box)->imax[0]) - ((dval_box)->imin[0])) + 1 : 0)) * (0 < ((((dval_box)->imax[1]) - ((dval_box)->imin[1])) + 1) ? (((dval_box)->imax[1]) - ((dval_box)->imin[1])) + 1 : 0);
            int hypre__nx = loop_size[0];
            int hypre__ny = loop_size[1];
            int hypre__nz = loop_size[2];
            int hypre__mx = hypre__nx;
            int hypre__my = hypre__ny;
            int hypre__mz = hypre__nz;
            int hypre__dir;
            int hypre__max;
            int hypre__div;
            int hypre__mod;
            int hypre__block;
            int hypre__num_blocks;
            hypre__dir = 0;
            hypre__max = hypre__nx;
            if (hypre__ny > hypre__max) {
              hypre__dir = 1;
              hypre__max = hypre__ny;
            }
            if (hypre__nz > hypre__max) {
              hypre__dir = 2;
              hypre__max = hypre__nz;
            }
            hypre__num_blocks = 1;
            if (hypre__max < hypre__num_blocks) {
              hypre__num_blocks = hypre__max;
            }
            if (hypre__num_blocks > 0) {
              hypre__div = hypre__max / hypre__num_blocks;
              hypre__mod = hypre__max % hypre__num_blocks;
            }
            ;
            ;
            for (hypre__block = 0; hypre__block < hypre__num_blocks; hypre__block++) {
              loopi = 0;
              loopj = 0;
              loopk = 0;
              hypre__nx = hypre__mx;
              hypre__ny = hypre__my;
              hypre__nz = hypre__mz;
              if (hypre__num_blocks > 1) {
                if (hypre__dir == 0) {
                  loopi = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                  hypre__nx = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                }
                else
                  if (hypre__dir == 1) {
                    loopj = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                    hypre__ny = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                  }
                  else
                    if (hypre__dir == 2) {
                      loopk = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                      hypre__nz = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                    }
              }
              ;
              datai = ((hypre__i1start + (loopi * hypre__sx1)) + (loopj * hypre__sy1)) + (loopk * hypre__sz1);
              dvali = ((hypre__i2start + (loopi * hypre__sx2)) + (loopj * hypre__sy2)) + (loopk * hypre__sz2);
              for (loopk = 0; loopk < hypre__nz; loopk++) {
                for (loopj = 0; loopj < hypre__ny; loopj++) {
                  for (loopi = 0; loopi < hypre__nx; loopi++) {
                    {
                      datap[datai] += values[dvali];
                    }
                    datai += hypre__sx1;
                    dvali += hypre__sx2;
                  }
                  datai += hypre__sy1 - (hypre__nx * hypre__sx1);
                  dvali += hypre__sy2 - (hypre__nx * hypre__sx2);
                }
                datai += hypre__sz1 - (hypre__ny * hypre__sy1);
                dvali += hypre__sz2 - (hypre__ny * hypre__sy2);
              }
            }
          }
          ;
        }
        else {
          {
            int hypre__i1start = ((data_start[0]) - ((data_box)->imin[0])) + ((((data_start[1]) - ((data_box)->imin[1])) + (((data_start[2]) - ((data_box)->imin[2])) * (0 < ((((data_box)->imax[1]) - ((data_box)->imin[1])) + 1) ? (((data_box)->imax[1]) - ((data_box)->imin[1])) + 1 : 0))) * (0 < ((((data_box)->imax[0]) - ((data_box)->imin[0])) + 1) ? (((data_box)->imax[0]) - ((data_box)->imin[0])) + 1 : 0));
            int hypre__i2start = ((dval_start[0]) - ((dval_box)->imin[0])) + ((((dval_start[1]) - ((dval_box)->imin[1])) + (((dval_start[2]) - ((dval_box)->imin[2])) * (0 < ((((dval_box)->imax[1]) - ((dval_box)->imin[1])) + 1) ? (((dval_box)->imax[1]) - ((dval_box)->imin[1])) + 1 : 0))) * (0 < ((((dval_box)->imax[0]) - ((dval_box)->imin[0])) + 1) ? (((dval_box)->imax[0]) - ((dval_box)->imin[0])) + 1 : 0));
            int hypre__sx1 = data_stride[0];
            int hypre__sy1 = (data_stride[1]) * (0 < ((((data_box)->imax[0]) - ((data_box)->imin[0])) + 1) ? (((data_box)->imax[0]) - ((data_box)->imin[0])) + 1 : 0);
            int hypre__sz1 = ((data_stride[2]) * (0 < ((((data_box)->imax[0]) - ((data_box)->imin[0])) + 1) ? (((data_box)->imax[0]) - ((data_box)->imin[0])) + 1 : 0)) * (0 < ((((data_box)->imax[1]) - ((data_box)->imin[1])) + 1) ? (((data_box)->imax[1]) - ((data_box)->imin[1])) + 1 : 0);
            int hypre__sx2 = dval_stride[0];
            int hypre__sy2 = (dval_stride[1]) * (0 < ((((dval_box)->imax[0]) - ((dval_box)->imin[0])) + 1) ? (((dval_box)->imax[0]) - ((dval_box)->imin[0])) + 1 : 0);
            int hypre__sz2 = ((dval_stride[2]) * (0 < ((((dval_box)->imax[0]) - ((dval_box)->imin[0])) + 1) ? (((dval_box)->imax[0]) - ((dval_box)->imin[0])) + 1 : 0)) * (0 < ((((dval_box)->imax[1]) - ((dval_box)->imin[1])) + 1) ? (((dval_box)->imax[1]) - ((dval_box)->imin[1])) + 1 : 0);
            int hypre__nx = loop_size[0];
            int hypre__ny = loop_size[1];
            int hypre__nz = loop_size[2];
            int hypre__mx = hypre__nx;
            int hypre__my = hypre__ny;
            int hypre__mz = hypre__nz;
            int hypre__dir;
            int hypre__max;
            int hypre__div;
            int hypre__mod;
            int hypre__block;
            int hypre__num_blocks;
            hypre__dir = 0;
            hypre__max = hypre__nx;
            if (hypre__ny > hypre__max) {
              hypre__dir = 1;
              hypre__max = hypre__ny;
            }
            if (hypre__nz > hypre__max) {
              hypre__dir = 2;
              hypre__max = hypre__nz;
            }
            hypre__num_blocks = 1;
            if (hypre__max < hypre__num_blocks) {
              hypre__num_blocks = hypre__max;
            }
            if (hypre__num_blocks > 0) {
              hypre__div = hypre__max / hypre__num_blocks;
              hypre__mod = hypre__max % hypre__num_blocks;
            }
            ;
            ;
            for (hypre__block = 0; hypre__block < hypre__num_blocks; hypre__block++) {
              loopi = 0;
              loopj = 0;
              loopk = 0;
              hypre__nx = hypre__mx;
              hypre__ny = hypre__my;
              hypre__nz = hypre__mz;
              if (hypre__num_blocks > 1) {
                if (hypre__dir == 0) {
                  loopi = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                  hypre__nx = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                }
                else
                  if (hypre__dir == 1) {
                    loopj = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                    hypre__ny = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                  }
                  else
                    if (hypre__dir == 2) {
                      loopk = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                      hypre__nz = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                    }
              }
              ;
              datai = ((hypre__i1start + (loopi * hypre__sx1)) + (loopj * hypre__sy1)) + (loopk * hypre__sz1);
              dvali = ((hypre__i2start + (loopi * hypre__sx2)) + (loopj * hypre__sy2)) + (loopk * hypre__sz2);
              for (loopk = 0; loopk < hypre__nz; loopk++) {
                for (loopj = 0; loopj < hypre__ny; loopj++) {
                  for (loopi = 0; loopi < hypre__nx; loopi++) {
                    {
                      datap[datai] = values[dvali];
                    }
                    datai += hypre__sx1;
                    dvali += hypre__sx2;
                  }
                  datai += hypre__sy1 - (hypre__nx * hypre__sx1);
                  dvali += hypre__sy2 - (hypre__nx * hypre__sx2);
                }
                datai += hypre__sz1 - (hypre__ny * hypre__sy1);
                dvali += hypre__sz2 - (hypre__ny * hypre__sy2);
              }
            }
          }
          ;
        }
      }
    }
    hypre_BoxDestroy(dval_box);
  }
  hypre_BoxArrayDestroy(box_array1);
  if (vol_offproc) {
    data_space = (vector)->data_space;
    data_stride[0] = 1, data_stride[1] = 1, data_stride[2] = 1;
    dval_box = hypre_BoxDuplicate(value_box);
    dval_stride[0] = 1, dval_stride[1] = 1, dval_stride[2] = 1;
    for (i = 0; i < (data_space)->size; i++) {
      data_box = &((data_space)->boxes[i]);
      box_array2 = (box_aarray)->box_arrays[i];
      for (j = 0; j < (box_array2)->size; j++) {
        box = &((box_array2)->boxes[j]);
        if (box) {
          data_start = (box)->imin;
          dval_start[0] = data_start[0], dval_start[1] = data_start[1], dval_start[2] = data_start[2];
          datap = (vector)->data + ((vector)->data_indices[i]);
          hypre_BoxGetSize(box, loop_size);
          if (add_to) {
            {
              int hypre__i1start = ((data_start[0]) - ((data_box)->imin[0])) + ((((data_start[1]) - ((data_box)->imin[1])) + (((data_start[2]) - ((data_box)->imin[2])) * (0 < ((((data_box)->imax[1]) - ((data_box)->imin[1])) + 1) ? (((data_box)->imax[1]) - ((data_box)->imin[1])) + 1 : 0))) * (0 < ((((data_box)->imax[0]) - ((data_box)->imin[0])) + 1) ? (((data_box)->imax[0]) - ((data_box)->imin[0])) + 1 : 0));
              int hypre__i2start = ((dval_start[0]) - ((dval_box)->imin[0])) + ((((dval_start[1]) - ((dval_box)->imin[1])) + (((dval_start[2]) - ((dval_box)->imin[2])) * (0 < ((((dval_box)->imax[1]) - ((dval_box)->imin[1])) + 1) ? (((dval_box)->imax[1]) - ((dval_box)->imin[1])) + 1 : 0))) * (0 < ((((dval_box)->imax[0]) - ((dval_box)->imin[0])) + 1) ? (((dval_box)->imax[0]) - ((dval_box)->imin[0])) + 1 : 0));
              int hypre__sx1 = data_stride[0];
              int hypre__sy1 = (data_stride[1]) * (0 < ((((data_box)->imax[0]) - ((data_box)->imin[0])) + 1) ? (((data_box)->imax[0]) - ((data_box)->imin[0])) + 1 : 0);
              int hypre__sz1 = ((data_stride[2]) * (0 < ((((data_box)->imax[0]) - ((data_box)->imin[0])) + 1) ? (((data_box)->imax[0]) - ((data_box)->imin[0])) + 1 : 0)) * (0 < ((((data_box)->imax[1]) - ((data_box)->imin[1])) + 1) ? (((data_box)->imax[1]) - ((data_box)->imin[1])) + 1 : 0);
              int hypre__sx2 = dval_stride[0];
              int hypre__sy2 = (dval_stride[1]) * (0 < ((((dval_box)->imax[0]) - ((dval_box)->imin[0])) + 1) ? (((dval_box)->imax[0]) - ((dval_box)->imin[0])) + 1 : 0);
              int hypre__sz2 = ((dval_stride[2]) * (0 < ((((dval_box)->imax[0]) - ((dval_box)->imin[0])) + 1) ? (((dval_box)->imax[0]) - ((dval_box)->imin[0])) + 1 : 0)) * (0 < ((((dval_box)->imax[1]) - ((dval_box)->imin[1])) + 1) ? (((dval_box)->imax[1]) - ((dval_box)->imin[1])) + 1 : 0);
              int hypre__nx = loop_size[0];
              int hypre__ny = loop_size[1];
              int hypre__nz = loop_size[2];
              int hypre__mx = hypre__nx;
              int hypre__my = hypre__ny;
              int hypre__mz = hypre__nz;
              int hypre__dir;
              int hypre__max;
              int hypre__div;
              int hypre__mod;
              int hypre__block;
              int hypre__num_blocks;
              hypre__dir = 0;
              hypre__max = hypre__nx;
              if (hypre__ny > hypre__max) {
                hypre__dir = 1;
                hypre__max = hypre__ny;
              }
              if (hypre__nz > hypre__max) {
                hypre__dir = 2;
                hypre__max = hypre__nz;
              }
              hypre__num_blocks = 1;
              if (hypre__max < hypre__num_blocks) {
                hypre__num_blocks = hypre__max;
              }
              if (hypre__num_blocks > 0) {
                hypre__div = hypre__max / hypre__num_blocks;
                hypre__mod = hypre__max % hypre__num_blocks;
              }
              ;
              ;
              for (hypre__block = 0; hypre__block < hypre__num_blocks; hypre__block++) {
                loopi = 0;
                loopj = 0;
                loopk = 0;
                hypre__nx = hypre__mx;
                hypre__ny = hypre__my;
                hypre__nz = hypre__mz;
                if (hypre__num_blocks > 1) {
                  if (hypre__dir == 0) {
                    loopi = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                    hypre__nx = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                  }
                  else
                    if (hypre__dir == 1) {
                      loopj = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                      hypre__ny = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                    }
                    else
                      if (hypre__dir == 2) {
                        loopk = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                        hypre__nz = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                      }
                }
                ;
                datai = ((hypre__i1start + (loopi * hypre__sx1)) + (loopj * hypre__sy1)) + (loopk * hypre__sz1);
                dvali = ((hypre__i2start + (loopi * hypre__sx2)) + (loopj * hypre__sy2)) + (loopk * hypre__sz2);
                for (loopk = 0; loopk < hypre__nz; loopk++) {
                  for (loopj = 0; loopj < hypre__ny; loopj++) {
                    for (loopi = 0; loopi < hypre__nx; loopi++) {
                      {
                        datap[datai] += values[dvali];
                      }
                      datai += hypre__sx1;
                      dvali += hypre__sx2;
                    }
                    datai += hypre__sy1 - (hypre__nx * hypre__sx1);
                    dvali += hypre__sy2 - (hypre__nx * hypre__sx2);
                  }
                  datai += hypre__sz1 - (hypre__ny * hypre__sy1);
                  dvali += hypre__sz2 - (hypre__ny * hypre__sy2);
                }
              }
            }
            ;
          }
        }
      }
    }
    hypre_BoxDestroy(dval_box);
    hypre_BoxArrayArrayDestroy(box_aarray);
  }
  return ierr;
}
int hypre_StructVectorAssemble(hypre_StructVector* vector) {
  int ierr = 0;
  int sum_OffProcAdd;
  int OffProcAdd = (vector)->OffProcAdd;
  sum_OffProcAdd = 0;
  MPI_Allreduce(&(OffProcAdd), &(sum_OffProcAdd), 1, MPI_INT, _SUM, (vector)->comm);
  if (sum_OffProcAdd) {
    hypre_CommInfo* comm_info;
    hypre_CommInfo* inv_comm_info;
    hypre_CommPkg* comm_pkg;
    int* num_ghost = (vector)->add_num_ghost;
    hypre_BoxArrayArray* send_boxes;
    hypre_BoxArrayArray* recv_boxes;
    int** send_procs;
    int** recv_procs;
    int** send_rboxnums;
    int** recv_rboxnums;
    hypre_BoxArrayArray* send_rboxes;
    hypre_BoxArray* box_array;
    hypre_BoxArray* recv_array;
    double* data;
    hypre_CommHandle* comm_handle;
    hypre_Box* data_box;
    hypre_Box* box;
    double* data_vec;
    double* comm_data;
    hypre_Index loop_size;
    hypre_IndexRef start;
    hypre_Index unit_stride;
    int i;
    int j;
    int xi;
    int loopi;
    int loopj;
    int loopk;
    hypre_CreateCommInfoFromNumGhost((vector)->grid, num_ghost, &(comm_info));
    send_boxes = hypre_BoxArrayArrayDuplicate((comm_info)->recv_boxes);
    recv_boxes = hypre_BoxArrayArrayDuplicate((comm_info)->send_boxes);
    send_rboxes = hypre_BoxArrayArrayDuplicate(send_boxes);
    send_procs = (int**)(hypre_CAlloc((unsigned)((send_boxes)->size), (unsigned)(sizeof(int*))));
    recv_procs = (int**)(hypre_CAlloc((unsigned)((recv_boxes)->size), (unsigned)(sizeof(int*))));
    send_rboxnums = (int**)(hypre_CAlloc((unsigned)((send_boxes)->size), (unsigned)(sizeof(int*))));
    recv_rboxnums = (int**)(hypre_CAlloc((unsigned)((recv_boxes)->size), (unsigned)(sizeof(int*))));
    for (i = 0; i < (send_boxes)->size; i++) {
      box_array = (send_boxes)->box_arrays[i];
      send_procs[i] = (int*)(hypre_CAlloc((unsigned)((box_array)->size), (unsigned)(sizeof(int))));
      memcpy(send_procs[i], (comm_info)->recv_processes[i], (box_array)->size * sizeof(int));
      send_rboxnums[i] = (int*)(hypre_CAlloc((unsigned)((box_array)->size), (unsigned)(sizeof(int))));
      memcpy(send_rboxnums[i], (comm_info)->recv_rboxnums[i], (box_array)->size * sizeof(int));
    }
    for (i = 0; i < (recv_boxes)->size; i++) {
      box_array = (recv_boxes)->box_arrays[i];
      recv_procs[i] = (int*)(hypre_CAlloc((unsigned)((box_array)->size), (unsigned)(sizeof(int))));
      memcpy(recv_procs[i], (comm_info)->send_processes[i], (box_array)->size * sizeof(int));
      recv_rboxnums[i] = (int*)(hypre_CAlloc((unsigned)((box_array)->size), (unsigned)(sizeof(int))));
      memcpy(recv_rboxnums[i], (comm_info)->send_rboxnums[i], (box_array)->size * sizeof(int));
    }
    hypre_CommInfoCreate(send_boxes, recv_boxes, send_procs, recv_procs, send_rboxnums, recv_rboxnums, send_rboxes, &(inv_comm_info));
    hypre_CommPkgCreate(inv_comm_info, (vector)->data_space, (vector)->data_space, 1, (vector)->comm, &(comm_pkg));
    data = (double*)(hypre_CAlloc((unsigned)((vector)->data_size), (unsigned)(sizeof(double))));
    hypre_InitializeCommunication(comm_pkg, (vector)->data, data, &(comm_handle));
    hypre_FinalizeCommunication(comm_handle);
    unit_stride[0] = 1, unit_stride[1] = 1, unit_stride[2] = 1;
    box_array = ((vector)->grid)->boxes;
    for (i = 0; i < (box_array)->size; i++) {
      recv_array = ((comm_info)->send_boxes)->box_arrays[i];
      data_box = &(((vector)->data_space)->boxes[i]);
      data_vec = (vector)->data + ((vector)->data_indices[i]);
      comm_data = data + ((vector)->data_indices[i]);
      for (j = 0; j < (recv_array)->size; j++) {
        box = &((recv_array)->boxes[j]);
        start = (box)->imin;
        hypre_BoxGetSize(box, loop_size);
        {
          int hypre__i1start = ((start[0]) - ((data_box)->imin[0])) + ((((start[1]) - ((data_box)->imin[1])) + (((start[2]) - ((data_box)->imin[2])) * (0 < ((((data_box)->imax[1]) - ((data_box)->imin[1])) + 1) ? (((data_box)->imax[1]) - ((data_box)->imin[1])) + 1 : 0))) * (0 < ((((data_box)->imax[0]) - ((data_box)->imin[0])) + 1) ? (((data_box)->imax[0]) - ((data_box)->imin[0])) + 1 : 0));
          int hypre__sx1 = unit_stride[0];
          int hypre__sy1 = (unit_stride[1]) * (0 < ((((data_box)->imax[0]) - ((data_box)->imin[0])) + 1) ? (((data_box)->imax[0]) - ((data_box)->imin[0])) + 1 : 0);
          int hypre__sz1 = ((unit_stride[2]) * (0 < ((((data_box)->imax[0]) - ((data_box)->imin[0])) + 1) ? (((data_box)->imax[0]) - ((data_box)->imin[0])) + 1 : 0)) * (0 < ((((data_box)->imax[1]) - ((data_box)->imin[1])) + 1) ? (((data_box)->imax[1]) - ((data_box)->imin[1])) + 1 : 0);
          int hypre__nx = loop_size[0];
          int hypre__ny = loop_size[1];
          int hypre__nz = loop_size[2];
          int hypre__mx = hypre__nx;
          int hypre__my = hypre__ny;
          int hypre__mz = hypre__nz;
          int hypre__dir;
          int hypre__max;
          int hypre__div;
          int hypre__mod;
          int hypre__block;
          int hypre__num_blocks;
          hypre__dir = 0;
          hypre__max = hypre__nx;
          if (hypre__ny > hypre__max) {
            hypre__dir = 1;
            hypre__max = hypre__ny;
          }
          if (hypre__nz > hypre__max) {
            hypre__dir = 2;
            hypre__max = hypre__nz;
          }
          hypre__num_blocks = 1;
          if (hypre__max < hypre__num_blocks) {
            hypre__num_blocks = hypre__max;
          }
          if (hypre__num_blocks > 0) {
            hypre__div = hypre__max / hypre__num_blocks;
            hypre__mod = hypre__max % hypre__num_blocks;
          }
          ;
          for (hypre__block = 0; hypre__block < hypre__num_blocks; hypre__block++) {
            loopi = 0;
            loopj = 0;
            loopk = 0;
            hypre__nx = hypre__mx;
            hypre__ny = hypre__my;
            hypre__nz = hypre__mz;
            if (hypre__num_blocks > 1) {
              if (hypre__dir == 0) {
                loopi = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                hypre__nx = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
              }
              else
                if (hypre__dir == 1) {
                  loopj = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                  hypre__ny = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                }
                else
                  if (hypre__dir == 2) {
                    loopk = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                    hypre__nz = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                  }
            }
            ;
            xi = ((hypre__i1start + (loopi * hypre__sx1)) + (loopj * hypre__sy1)) + (loopk * hypre__sz1);
            for (loopk = 0; loopk < hypre__nz; loopk++) {
              for (loopj = 0; loopj < hypre__ny; loopj++) {
                for (loopi = 0; loopi < hypre__nx; loopi++) {
                  {
                    data_vec[xi] += comm_data[xi];
                  }
                  xi += hypre__sx1;
                }
                xi += hypre__sy1 - (hypre__nx * hypre__sx1);
              }
              xi += hypre__sz1 - (hypre__ny * hypre__sy1);
            }
          }
        }
        ;
      }
    }
    hypre_Free((char*)data), data = (void*)0;
    hypre_CommInfoDestroy(comm_info);
    hypre_CommPkgDestroy(comm_pkg);
  }
  return ierr;
}
int hypre_StructVectorClearBoundGhostValues(hypre_StructVector* vector) {
  int ierr = 0;
  int vi;
  double* vp;
  hypre_BoxArray* boxes;
  hypre_Box* box;
  hypre_Box* v_data_box;
  hypre_Index loop_size;
  hypre_IndexRef start;
  hypre_Index stride;
  hypre_Box* bbox;
  hypre_StructGrid* grid;
  hypre_BoxArray* boundary_boxes;
  hypre_BoxArray* array_of_box;
  hypre_BoxArray* work_boxarray;
  int i;
  int i2;
  int loopi;
  int loopj;
  int loopk;
  grid = (vector)->grid;
  boxes = (grid)->boxes;
  stride[0] = 1, stride[1] = 1, stride[2] = 1;
  for (i = 0; i < (boxes)->size; i++) {
    box = &((boxes)->boxes[i]);
    boundary_boxes = hypre_BoxArrayCreate(0);
    v_data_box = &(((vector)->data_space)->boxes[i]);
    ierr += hypre_BoxBoundaryG(v_data_box, grid, boundary_boxes);
    vp = (vector)->data + ((vector)->data_indices[i]);
    work_boxarray = hypre_BoxArrayCreate(0);
    array_of_box = hypre_BoxArrayCreate(1);
    (array_of_box)->boxes[0] = *box;
    hypre_SubtractBoxArrays(boundary_boxes, array_of_box, work_boxarray);
    for (i2 = 0; i2 < (boundary_boxes)->size; i2++) {
      bbox = &((boundary_boxes)->boxes[i2]);
      hypre_BoxGetSize(bbox, loop_size);
      start = (bbox)->imin;
      {
        int hypre__i1start = ((start[0]) - ((v_data_box)->imin[0])) + ((((start[1]) - ((v_data_box)->imin[1])) + (((start[2]) - ((v_data_box)->imin[2])) * (0 < ((((v_data_box)->imax[1]) - ((v_data_box)->imin[1])) + 1) ? (((v_data_box)->imax[1]) - ((v_data_box)->imin[1])) + 1 : 0))) * (0 < ((((v_data_box)->imax[0]) - ((v_data_box)->imin[0])) + 1) ? (((v_data_box)->imax[0]) - ((v_data_box)->imin[0])) + 1 : 0));
        int hypre__sx1 = stride[0];
        int hypre__sy1 = (stride[1]) * (0 < ((((v_data_box)->imax[0]) - ((v_data_box)->imin[0])) + 1) ? (((v_data_box)->imax[0]) - ((v_data_box)->imin[0])) + 1 : 0);
        int hypre__sz1 = ((stride[2]) * (0 < ((((v_data_box)->imax[0]) - ((v_data_box)->imin[0])) + 1) ? (((v_data_box)->imax[0]) - ((v_data_box)->imin[0])) + 1 : 0)) * (0 < ((((v_data_box)->imax[1]) - ((v_data_box)->imin[1])) + 1) ? (((v_data_box)->imax[1]) - ((v_data_box)->imin[1])) + 1 : 0);
        int hypre__nx = loop_size[0];
        int hypre__ny = loop_size[1];
        int hypre__nz = loop_size[2];
        int hypre__mx = hypre__nx;
        int hypre__my = hypre__ny;
        int hypre__mz = hypre__nz;
        int hypre__dir;
        int hypre__max;
        int hypre__div;
        int hypre__mod;
        int hypre__block;
        int hypre__num_blocks;
        hypre__dir = 0;
        hypre__max = hypre__nx;
        if (hypre__ny > hypre__max) {
          hypre__dir = 1;
          hypre__max = hypre__ny;
        }
        if (hypre__nz > hypre__max) {
          hypre__dir = 2;
          hypre__max = hypre__nz;
        }
        hypre__num_blocks = 1;
        if (hypre__max < hypre__num_blocks) {
          hypre__num_blocks = hypre__max;
        }
        if (hypre__num_blocks > 0) {
          hypre__div = hypre__max / hypre__num_blocks;
          hypre__mod = hypre__max % hypre__num_blocks;
        }
        ;
        ;
        for (hypre__block = 0; hypre__block < hypre__num_blocks; hypre__block++) {
          loopi = 0;
          loopj = 0;
          loopk = 0;
          hypre__nx = hypre__mx;
          hypre__ny = hypre__my;
          hypre__nz = hypre__mz;
          if (hypre__num_blocks > 1) {
            if (hypre__dir == 0) {
              loopi = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
              hypre__nx = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
            }
            else
              if (hypre__dir == 1) {
                loopj = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                hypre__ny = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
              }
              else
                if (hypre__dir == 2) {
                  loopk = (hypre__block * hypre__div) + (hypre__mod < hypre__block ? hypre__mod : hypre__block);
                  hypre__nz = hypre__div + (hypre__mod > hypre__block ? 1 : 0);
                }
          }
          ;
          vi = ((hypre__i1start + (loopi * hypre__sx1)) + (loopj * hypre__sy1)) + (loopk * hypre__sz1);
          for (loopk = 0; loopk < hypre__nz; loopk++) {
            for (loopj = 0; loopj < hypre__ny; loopj++) {
              for (loopi = 0; loopi < hypre__nx; loopi++) {
                {
                  vp[vi] = 0.0;
                }
                vi += hypre__sx1;
              }
              vi += hypre__sy1 - (hypre__nx * hypre__sx1);
            }
            vi += hypre__sz1 - (hypre__ny * hypre__sy1);
          }
        }
      }
      ;
    }
    hypre_BoxArrayDestroy(boundary_boxes);
    hypre_BoxArrayDestroy(work_boxarray);
    hypre_BoxArrayDestroy(array_of_box);
  }
  return ierr;
}
int hypre_StructVectorPrint(char* filename, hypre_StructVector* vector, int all) {
  int ierr = 0;
  FILE* file;
  char  new_filename[255];
  hypre_StructGrid* grid;
  hypre_BoxArray* boxes;
  hypre_BoxArray* data_space;
  int myid;
  MPI_Comm_rank((vector)->comm, &(myid));
  sprintf(new_filename, "%s.%05d", filename, myid);
  if ((file = fopen(new_filename, "w")) == (void*)0) {
    printf("Error: can't open output file %s\n", new_filename);
    exit(1);
  }
  fprintf(file, "StructVector\n");
  fprintf(file, "\nGrid:\n");
  grid = (vector)->grid;
  hypre_StructGridPrint(file, grid);
  data_space = (vector)->data_space;
  if (all)
    boxes = data_space;
  else
    boxes = (grid)->boxes;
  fprintf(file, "\nData:\n");
  hypre_PrintBoxArrayData(file, boxes, data_space, 1, (vector)->data);
  fflush(file);
  fclose(file);
  return ierr;
}
//===================== amg_linklist.c =====================
void dispose_elt(hypre_LinkList element_ptr) {
  free(element_ptr);
}
void remove_point(hypre_LinkList* LoL_head_ptr, hypre_LinkList* LoL_tail_ptr, int measure, int index, int* lists, int* where) {
  hypre_LinkList LoL_head = *LoL_head_ptr;
  hypre_LinkList LoL_tail = *LoL_tail_ptr;
  hypre_LinkList list_ptr;
  list_ptr = LoL_head;
  do {
    if (measure == (list_ptr)->data) {
      if (((list_ptr)->head == index) && ((list_ptr)->tail == index)) {
        if ((list_ptr == LoL_head) && (list_ptr == LoL_tail)) {
          LoL_head = (void*)0;
          LoL_tail = (void*)0;
          dispose_elt(list_ptr);
          *LoL_head_ptr = LoL_head;
          *LoL_tail_ptr = LoL_tail;
          return;
        }
        else
          if (LoL_head == list_ptr) {
            ((list_ptr)->next_elt)->prev_elt = (void*)0;
            LoL_head = (list_ptr)->next_elt;
            dispose_elt(list_ptr);
            *LoL_head_ptr = LoL_head;
            *LoL_tail_ptr = LoL_tail;
            return;
          }
          else
            if (LoL_tail == list_ptr) {
              ((list_ptr)->prev_elt)->next_elt = (void*)0;
              LoL_tail = (list_ptr)->prev_elt;
              dispose_elt(list_ptr);
              *LoL_head_ptr = LoL_head;
              *LoL_tail_ptr = LoL_tail;
              return;
            }
            else {
              ((list_ptr)->next_elt)->prev_elt = (list_ptr)->prev_elt;
              ((list_ptr)->prev_elt)->next_elt = (list_ptr)->next_elt;
              dispose_elt(list_ptr);
              *LoL_head_ptr = LoL_head;
              *LoL_tail_ptr = LoL_tail;
              return;
            }
      }
      else
        if ((list_ptr)->head == index) {
          (list_ptr)->head = lists[index];
          where[lists[index]] = -1;
          return;
        }
        else
          if ((list_ptr)->tail == index) {
            (list_ptr)->tail = where[index];
            lists[where[index]] = -2;
            return;
          }
          else {
            lists[where[index]] = lists[index];
            where[lists[index]] = where[index];
            return;
          }
    }
    list_ptr = (list_ptr)->next_elt;
  }while (list_ptr != (void*)0);
  printf("No such list!\n");
  return;
}
hypre_LinkList create_elt(int Item) {
  hypre_LinkList new_elt_ptr;
  if ((new_elt_ptr = (hypre_LinkList)(malloc(sizeof(hypre_ListElement)))) == (void*)0) {
    printf("\n create_elt: malloc failed \n\n");
  }
  else {
    (new_elt_ptr)->data = Item;
    (new_elt_ptr)->next_elt = (void*)0;
    (new_elt_ptr)->prev_elt = (void*)0;
    (new_elt_ptr)->head = -2;
    (new_elt_ptr)->tail = -1;
  }
  return new_elt_ptr;
}
void enter_on_lists(hypre_LinkList* LoL_head_ptr, hypre_LinkList* LoL_tail_ptr, int measure, int index, int* lists, int* where) {
  hypre_LinkList LoL_head = *LoL_head_ptr;
  hypre_LinkList LoL_tail = *LoL_tail_ptr;
  hypre_LinkList list_ptr;
  hypre_LinkList new_ptr;
  int old_tail;
  list_ptr = LoL_head;
  if (LoL_head == (void*)0) {
    new_ptr = create_elt(measure);
    (new_ptr)->head = index;
    (new_ptr)->tail = index;
    lists[index] = -2;
    where[index] = -1;
    LoL_head = new_ptr;
    LoL_tail = new_ptr;
    *LoL_head_ptr = LoL_head;
    *LoL_tail_ptr = LoL_tail;
    return;
  }
  else {
    do {
      if (measure > (list_ptr)->data) {
        new_ptr = create_elt(measure);
        (new_ptr)->head = index;
        (new_ptr)->tail = index;
        lists[index] = -2;
        where[index] = -1;
        if ((list_ptr)->prev_elt != (void*)0) {
          (new_ptr)->prev_elt = (list_ptr)->prev_elt;
          ((list_ptr)->prev_elt)->next_elt = new_ptr;
          (list_ptr)->prev_elt = new_ptr;
          (new_ptr)->next_elt = list_ptr;
        }
        else {
          (new_ptr)->next_elt = list_ptr;
          (list_ptr)->prev_elt = new_ptr;
          (new_ptr)->prev_elt = (void*)0;
          LoL_head = new_ptr;
        }
        *LoL_head_ptr = LoL_head;
        *LoL_tail_ptr = LoL_tail;
        return;
      }
      else
        if (measure == (list_ptr)->data) {
          old_tail = (list_ptr)->tail;
          lists[old_tail] = index;
          where[index] = old_tail;
          lists[index] = -2;
          (list_ptr)->tail = index;
          return;
        }
      list_ptr = (list_ptr)->next_elt;
    }while (list_ptr != (void*)0);
    new_ptr = create_elt(measure);
    (new_ptr)->head = index;
    (new_ptr)->tail = index;
    lists[index] = -2;
    where[index] = -1;
    (LoL_tail)->next_elt = new_ptr;
    (new_ptr)->prev_elt = LoL_tail;
    (new_ptr)->next_elt = (void*)0;
    LoL_tail = new_ptr;
    *LoL_head_ptr = LoL_head;
    *LoL_tail_ptr = LoL_tail;
    return;
  }
}
//======================= binsearch.c ======================
int hypre_BinarySearch(int* list, int value, int list_length) {
  int low;
  int high;
  int m;
  int not_found = 1;
  low = 0;
  high = list_length - 1;
  while (not_found && (low <= high)) {
    m = (low + high) / 2;
    if (value < (list[m])) {
      high = m - 1;
    }
    else
      if (value > (list[m])) {
        low = m + 1;
      }
      else {
        not_found = 0;
        return m;
      }
  }
  return -1;
}
int hypre_BigBinarySearch(int* list, int value, int list_length) {
  int low;
  int high;
  int m;
  int not_found = 1;
  low = 0;
  high = list_length - 1;
  while (not_found && (low <= high)) {
    m = (low + high) / 2;
    if (value < (list[m])) {
      high = m - 1;
    }
    else
      if (value > (list[m])) {
        low = m + 1;
      }
      else {
        not_found = 0;
        return m;
      }
  }
  return -1;
}
//====================== hypre_error.c =====================
int hypre__global_error = 0;
void hypre_error_handler(char* filename, int line, int ierr) {
  hypre__global_error |= ierr;
}
//===================== hypre_memory.c =====================
int hypre_OutOfMemory(int size) {
  printf("Out of memory trying to allocate %d bytes\n", size);
  fflush(stdout);
  hypre_error_handler("/Users/ziqingluo/Documents/workspace/CIVL/examples/omp/amg2013/AMG2013/utilities/hypre_memory.c", 908, 2);
  return 0;
}
char* hypre_MAlloc(int size) {
  char* ptr;
  if (size > 0) {
    ptr = malloc(size);
    if (ptr == (void*)0) {
      hypre_OutOfMemory(size);
    }
  }
  else {
    ptr = (void*)0;
  }
  return ptr;
}
char* hypre_CAlloc(int count, int elt_size) {
  char* ptr;
  int size = count * elt_size;
  if (size > 0) {
    ptr = calloc(count, elt_size);
    if (ptr == (void*)0) {
      hypre_OutOfMemory(size);
    }
  }
  else {
    ptr = (void*)0;
  }
  return ptr;
}
char* hypre_ReAlloc(char* ptr, int size) {
  if (ptr == (void*)0) {
    ptr = malloc(size);
  }
  else {
    ptr = realloc(ptr, size);
  }
  if ((ptr == (void*)0) && (size > 0)) {
    hypre_OutOfMemory(size);
  }
  return ptr;
}
void hypre_Free(char* ptr) {
  if (ptr) {
    free(ptr);
  }
}
//====================== hypre_qsort.c =====================
void swap(int* v, int i, int j) {
  int temp;
  temp = v[i];
  v[i] = v[j];
  v[j] = temp;
}
void swap2(int* v, double* w, int i, int j) {
  int temp;
  double temp2;
  temp = v[i];
  v[i] = v[j];
  v[j] = temp;
  temp2 = w[i];
  w[i] = w[j];
  w[j] = temp2;
}
void qsort0(int* v, int left, int right) {
  int i;
  int last;
  if (left >= right)
    return;
  swap(v, left, (left + right) / 2);
  last = left;
  for (i = left + 1; i <= right; i++)
    if ((v[i]) < (v[left])) {
      swap(v, ++last, i);
    }
  swap(v, left, last);
  qsort0(v, left, last - 1);
  qsort0(v, last + 1, right);
}
void hypre_BigSwapbi(int* v, int* w, int i, int j) {
  int big_temp;
  int temp;
  big_temp = v[i];
  v[i] = v[j];
  v[j] = big_temp;
  temp = w[i];
  w[i] = w[j];
  w[j] = temp;
}
void hypre_BigQsortbi(int* v, int* w, int left, int right) {
  int i;
  int last;
  if (left >= right) {
    return;
  }
  hypre_BigSwapbi(v, w, left, (left + right) / 2);
  last = left;
  for (i = left + 1; i <= right; i++) {
    if ((v[i]) < (v[left])) {
      hypre_BigSwapbi(v, w, ++last, i);
    }
  }
  hypre_BigSwapbi(v, w, left, last);
  hypre_BigQsortbi(v, w, left, last - 1);
  hypre_BigQsortbi(v, w, last + 1, right);
}
void hypre_BigSwap(int* v, int i, int j) {
  int temp;
  temp = v[i];
  v[i] = v[j];
  v[j] = temp;
}
void hypre_BigQsort0(int* v, int left, int right) {
  int i;
  int last;
  if (left >= right)
    return;
  hypre_BigSwap(v, left, (left + right) / 2);
  last = left;
  for (i = left + 1; i <= right; i++)
    if ((v[i]) < (v[left])) {
      hypre_BigSwap(v, ++last, i);
    }
  hypre_BigSwap(v, left, last);
  hypre_BigQsort0(v, left, last - 1);
  hypre_BigQsort0(v, last + 1, right);
}
//======================== random.c ========================
static int Seed = 13579;
void hypre_SeedRand(int seed) {
  Seed = seed;
}
double hypre_Rand() {
  int low;
  int high;
  int test;
  high = Seed / 127773;
  low = Seed % 127773;
  test = (16807 * low) - (2836 * high);
  if (test > 0) {
    Seed = test;
  }
  else {
    Seed = test + 2147483647;
  }
  return (double)Seed / 2147483647;
}
//========================= time.h =========================
typedef double clock_t;
clock_t clock(void);
//======================== unistd.h ========================
enum $anon_enum_0{
  _SC_2_C_BIND,
  _SC_2_C_DEV,
  _SC_2_C_VERSION,
  _SC_2_FORT_DEV,
  _SC_2_FORT_RUN,
  _SC_2_LOCALEDEF,
  _SC_2_SW_DEV,
  _SC_2_UPE,
  _SC_2_VERSION,
  _SC_ARG_MAX,
  _SC_AIO_LISTIO_MAX,
  _SC_AIO_MAX,
  _SC_AIO_PRIO_DELTA_MAX,
  _SC_ASYNCHRONOUS_IO,
  _SC_ATEXIT_MAX,
  _SC_BC_BASE_MAX,
  _SC_BC_DIM_MAX,
  _SC_BC_SCALE_MAX,
  _SC_BC_STRING_MAX,
  _SC_CHILD_MAX,
  _SC_CLK_TCK,
  _SC_COLL_WEIGHTS_MAX,
  _SC_DELAYTIMER_MAX,
  _SC_EXPR_NEST_MAX,
  _SC_FSYNC,
  _SC_GETGR_R_SIZE_MAX,
  _SC_GETPW_R_SIZE_MAX,
  _SC_IOV_MAX,
  _SC_JOB_CONTROL,
  _SC_LINE_MAX,
  _SC_LOGIN_NAME_MAX,
  _SC_MAPPED_FILES,
  _SC_MEMLOCK,
  _SC_MEMLOCK_RANGE,
  _SC_MEMORY_PROTECTION,
  _SC_MESSAGE_PASSING,
  _SC_MQ_OPEN_MAX,
  _SC_MQ_PRIO_MAX,
  _SC_NGROUPS_MAX,
  _SC_OPEN_MAX,
  _SC_PAGESIZE,
  _SC_PAGE_SIZE,
  _SC_PASS_MAX,
  _SC_PRIORITIZED_IO,
  _SC_PRIORITY_SCHEDULING,
  _SC_RE_DUP_MAX,
  _SC_REALTIME_SIGNALS,
  _SC_RTSIG_MAX,
  _SC_SAVED_IDS,
  _SC_SEMAPHORES,
  _SC_SEM_NSEMS_MAX,
  _SC_SEM_VALUE_MAX,
  _SC_SHARED_MEMORY_OBJECTS,
  _SC_SIGQUEUE_MAX,
  _SC_STREAM_MAX,
  _SC_SYNCHRONIZED_IO,
  _SC_THREADS,
  _SC_THREAD_ATTR_STACKADDR,
  _SC_THREAD_ATTR_STACKSIZE,
  _SC_THREAD_DESTRUCTOR_ITERATIONS,
  _SC_THREAD_KEYS_MAX,
  _SC_THREAD_PRIORITY_SCHEDULING,
  _SC_THREAD_PRIO_INHERIT,
  _SC_THREAD_PRIO_PROTECT,
  _SC_THREAD_PROCESS_SHARED,
  _SC_THREAD_SAFE_FUNCTIONS,
  _SC_THREAD_STACK_MIN,
  _SC_THREAD_THREADS_MAX,
  _SC_TIMERS,
  _SC_TIMER_MAX,
  _SC_TTY_NAME_MAX,
  _SC_TZNAME_MAX,
  _SC_VERSION,
  _SC_XOPEN_VERSION,
  _SC_XOPEN_CRYPT,
  _SC_XOPEN_ENH_I18N,
  _SC_XOPEN_SHM,
  _SC_XOPEN_UNIX,
  _SC_XOPEN_XCU_VERSION,
  _SC_XOPEN_LEGACY,
  _SC_XOPEN_REALTIME,
  _SC_XOPEN_REALTIME_THREADS,
  _SC_XBS5_ILP32_OFF32,
  _SC_XBS5_ILP32_OFFBIG,
  _SC_XBS5_LP64_OFF64,
  _SC_XBS5_LPBIG_OFFBIG
};
long sysconf(int);
//========================= times.h ========================
struct tms;
clock_t times(struct tms* timer);
//========================= timer.c ========================
double time_getWallclockSeconds(void) {
  struct tms usage;
  long wallclock = times(&(usage));
  return (double)wallclock / (double)(sysconf(_SC_CLK_TCK));
}
double time_getCPUSeconds(void) {
  clock_t cpuclock = clock();
  return (double)cpuclock / (double)100;
}
//======================= utilities.h ======================
hypre_TimingType* hypre_global_timing = (void*)0;
//======================== timing.c ========================
int hypre_InitializeTiming(char* name) {
  int time_index;
  double* old_wall_time;
  double* old_cpu_time;
  double* old_flops;
  char** old_name;
  int* old_state;
  int* old_num_regs;
  int new_name;
  int i;
  if (hypre_global_timing == (void*)0) {
    hypre_global_timing = (hypre_TimingType*)(hypre_CAlloc((unsigned)1, (unsigned)(sizeof(hypre_TimingType))));
  }
  new_name = 1;
  for (i = 0; i < (hypre_global_timing)->size; i++) {
    if (((hypre_global_timing)->num_regs[i]) > 0) {
      if (strcmp(name, (hypre_global_timing)->name[i]) == 0) {
        new_name = 0;
        time_index = i;
        (hypre_global_timing)->num_regs[time_index]++;
        break;
      }
    }
  }
  if (new_name) {
    for (i = 0; i < (hypre_global_timing)->size; i++) {
      if (((hypre_global_timing)->num_regs[i]) == 0) {
        break;
      }
    }
    time_index = i;
  }
  if (new_name) {
    if (time_index == (hypre_global_timing)->size) {
      old_wall_time = (hypre_global_timing)->wall_time;
      old_cpu_time = (hypre_global_timing)->cpu_time;
      old_flops = (hypre_global_timing)->flops;
      old_name = (hypre_global_timing)->name;
      old_state = (hypre_global_timing)->state;
      old_num_regs = (hypre_global_timing)->num_regs;
      (hypre_global_timing)->wall_time = (double*)(hypre_CAlloc((unsigned)(time_index + 1), (unsigned)(sizeof(double))));
      (hypre_global_timing)->cpu_time = (double*)(hypre_CAlloc((unsigned)(time_index + 1), (unsigned)(sizeof(double))));
      (hypre_global_timing)->flops = (double*)(hypre_CAlloc((unsigned)(time_index + 1), (unsigned)(sizeof(double))));
      (hypre_global_timing)->name = (char**)(hypre_CAlloc((unsigned)(time_index + 1), (unsigned)(sizeof(char*))));
      (hypre_global_timing)->state = (int*)(hypre_CAlloc((unsigned)(time_index + 1), (unsigned)(sizeof(int))));
      (hypre_global_timing)->num_regs = (int*)(hypre_CAlloc((unsigned)(time_index + 1), (unsigned)(sizeof(int))));
      (hypre_global_timing)->size++;
      for (i = 0; i < time_index; i++) {
        (hypre_global_timing)->wall_time[i] = old_wall_time[i];
        (hypre_global_timing)->cpu_time[i] = old_cpu_time[i];
        (hypre_global_timing)->flops[i] = old_flops[i];
        (hypre_global_timing)->name[i] = old_name[i];
        (hypre_global_timing)->state[i] = old_state[i];
        (hypre_global_timing)->num_regs[i] = old_num_regs[i];
      }
      hypre_Free((char*)old_wall_time), old_wall_time = (void*)0;
      hypre_Free((char*)old_cpu_time), old_cpu_time = (void*)0;
      hypre_Free((char*)old_flops), old_flops = (void*)0;
      hypre_Free((char*)old_name), old_name = (void*)0;
      hypre_Free((char*)old_state), old_state = (void*)0;
      hypre_Free((char*)old_num_regs), old_num_regs = (void*)0;
    }
    (hypre_global_timing)->name[time_index] = (char*)(hypre_CAlloc((unsigned)80, (unsigned)(sizeof(char))));
    strncpy((hypre_global_timing)->name[time_index], name, 79);
    (hypre_global_timing)->state[time_index] = 0;
    (hypre_global_timing)->num_regs[time_index] = 1;
    (hypre_global_timing)->num_names++;
  }
  return time_index;
}
int hypre_FinalizeTiming(int time_index) {
  int ierr = 0;
  int i;
  if (hypre_global_timing == (void*)0)
    return ierr;
  if (time_index < (hypre_global_timing)->size) {
    if (((hypre_global_timing)->num_regs[time_index]) > 0) {
      (hypre_global_timing)->num_regs[time_index]--;
    }
    if (((hypre_global_timing)->num_regs[time_index]) == 0) {
      hypre_Free((char*)((hypre_global_timing)->name[time_index])), (hypre_global_timing)->name[time_index] = (void*)0;
      (hypre_global_timing)->num_names--;
    }
  }
  if ((hypre_global_timing)->num_names == 0) {
    for (i = 0; i < (hypre_global_timing)->size; i++) {
      hypre_Free((char*)((hypre_global_timing)->wall_time)), (hypre_global_timing)->wall_time = (void*)0;
      hypre_Free((char*)((hypre_global_timing)->cpu_time)), (hypre_global_timing)->cpu_time = (void*)0;
      hypre_Free((char*)((hypre_global_timing)->flops)), (hypre_global_timing)->flops = (void*)0;
      hypre_Free((char*)((hypre_global_timing)->name)), (hypre_global_timing)->name = (void*)0;
      hypre_Free((char*)((hypre_global_timing)->state)), (hypre_global_timing)->state = (void*)0;
      hypre_Free((char*)((hypre_global_timing)->num_regs)), (hypre_global_timing)->num_regs = (void*)0;
    }
    hypre_Free((char*)hypre_global_timing), hypre_global_timing = (void*)0;
    hypre_global_timing = (void*)0;
  }
  return ierr;
}
int hypre_BeginTiming(int time_index) {
  int ierr = 0;
  if (hypre_global_timing == (void*)0)
    return ierr;
  if (((hypre_global_timing)->state[time_index]) == 0) {
    (hypre_global_timing)->wall_count += time_getWallclockSeconds();
    (hypre_global_timing)->CPU_count += time_getCPUSeconds();
    ((hypre_global_timing)->wall_time[time_index]) -= (hypre_global_timing)->wall_count;
    ((hypre_global_timing)->cpu_time[time_index]) -= (hypre_global_timing)->CPU_count;
    ((hypre_global_timing)->flops[time_index]) -= (hypre_global_timing)->FLOP_count;
    (hypre_global_timing)->wall_count -= time_getWallclockSeconds();
    (hypre_global_timing)->CPU_count -= time_getCPUSeconds();
  }
  (hypre_global_timing)->state[time_index]++;
  return ierr;
}
int hypre_EndTiming(int time_index) {
  int ierr = 0;
  if (hypre_global_timing == (void*)0)
    return ierr;
  (hypre_global_timing)->state[time_index]--;
  if (((hypre_global_timing)->state[time_index]) == 0) {
    (hypre_global_timing)->wall_count += time_getWallclockSeconds();
    (hypre_global_timing)->CPU_count += time_getCPUSeconds();
    (hypre_global_timing)->wall_time[time_index] += (hypre_global_timing)->wall_count;
    (hypre_global_timing)->cpu_time[time_index] += (hypre_global_timing)->CPU_count;
    (hypre_global_timing)->flops[time_index] += (hypre_global_timing)->FLOP_count;
    (hypre_global_timing)->wall_count -= time_getWallclockSeconds();
    (hypre_global_timing)->CPU_count -= time_getCPUSeconds();
  }
  return ierr;
}
int hypre_ClearTiming() {
  int ierr = 0;
  int i;
  if (hypre_global_timing == (void*)0)
    return ierr;
  for (i = 0; i < (hypre_global_timing)->size; i++) {
    (hypre_global_timing)->wall_time[i] = 0.0;
    (hypre_global_timing)->cpu_time[i] = 0.0;
    (hypre_global_timing)->flops[i] = 0.0;
  }
  return ierr;
}
int hypre_PrintTiming(char* heading, double* wall_time_ptr, MPI_Comm comm) {
  int ierr = 0;
  double local_wall_time;
  double local_cpu_time;
  double wall_time;
  double cpu_time;
  double wall_mflops;
  double cpu_mflops;
  int i;
  int myrank;
  if (hypre_global_timing == (void*)0)
    return ierr;
  MPI_Comm_rank(comm, &(myrank));
  if (myrank == 0) {
    printf("=============================================\n");
    printf("%s:\n", heading);
    printf("=============================================\n");
  }
  for (i = 0; i < (hypre_global_timing)->size; i++) {
    if (((hypre_global_timing)->num_regs[i]) > 0) {
      local_wall_time = (hypre_global_timing)->wall_time[i];
      local_cpu_time = (hypre_global_timing)->cpu_time[i];
      MPI_Allreduce(&(local_wall_time), &(wall_time), 1, MPI_DOUBLE, _MAX, comm);
      MPI_Allreduce(&(local_cpu_time), &(cpu_time), 1, MPI_DOUBLE, _MAX, comm);
      if (myrank == 0) {
        printf("%s:\n", (hypre_global_timing)->name[i]);
        *wall_time_ptr = wall_time;
        printf("%s  wall clock time = %f seconds\n", (hypre_global_timing)->name[i], wall_time);
        if (wall_time)
          wall_mflops = (((hypre_global_timing)->flops[i]) / wall_time) / 1.0e6;
        else
          wall_mflops = 0.0;
        printf("%s  cpu clock time  = %f seconds\n", (hypre_global_timing)->name[i], cpu_time);
        if (cpu_time)
          cpu_mflops = (((hypre_global_timing)->flops[i]) / cpu_time) / 1.0e6;
        else
          cpu_mflops = 0.0;
      }
    }
  }
  return ierr;
}

f0	: predefined macros
f1	: AMG2013/test/amg2013.c
f2	: /include/abc/stdlib.h
f3	: /include/abc/stdio.h
f4	: /include/abc/civl-stdio.cvh
f5	: /include/abc/civlc.cvh
f6	: /include/abc/op.h
f7	: /include/abc/stdarg.h
f8	: /include/abc/math.h
f9	: AMG2013/utilities/utilities.h
f10	: AMG2013/utilities/HYPRE_utilities.h
f11	: ./AMG2013/HYPRE.h
f12	: /include/abc/mpi.h
f13	: /include/abc/string.h
f14	: /include/abc/stddef.h
f15	: AMG2013/parcsr_mv/HYPRE_parcsr_mv.h
f16	: AMG2013/seq_mv/HYPRE_seq_mv.h
f17	: AMG2013/sstruct_mv/HYPRE_sstruct_mv.h
f18	: AMG2013/struct_mv/HYPRE_struct_mv.h
f19	: AMG2013/IJ_mv/HYPRE_IJ_mv.h
f20	: AMG2013/parcsr_ls/HYPRE_parcsr_ls.h
f21	: AMG2013/krylov/krylov.h
f22	: AMG2013/sstruct_mv/sstruct_mv.h
f23	: AMG2013/struct_mv/struct_mv.h
f24	: /include/abc/assert.h
f25	: AMG2013/IJ_mv/IJ_mv.h
f26	: AMG2013/seq_mv/seq_mv.h
f27	: AMG2013/parcsr_mv/parcsr_mv.h
f28	: AMG2013/IJ_mv/HYPRE_IJMatrix.c
f29	: AMG2013/IJ_mv/./IJ_mv.h
f30	: AMG2013/IJ_mv/./HYPRE_IJ_mv.h
f31	: AMG2013/IJ_mv/../HYPRE.h
f32	: AMG2013/IJ_mv/HYPRE_IJVector.c
f33	: AMG2013/IJ_mv/IJMatrix_parcsr.c
f34	: AMG2013/IJ_mv/headers.h
f35	: AMG2013/IJ_mv/IJVector_parcsr.c
f36	: AMG2013/IJ_mv/aux_par_vector.c
f37	: AMG2013/IJ_mv/aux_par_vector.h
f38	: AMG2013/IJ_mv/aux_parcsr_matrix.c
f39	: AMG2013/IJ_mv/aux_parcsr_matrix.h
f40	: AMG2013/krylov/HYPRE_gmres.c
f41	: AMG2013/krylov/HYPRE_pcg.c
f42	: AMG2013/krylov/gmres.c
f43	: AMG2013/krylov/pcg.c
f44	: AMG2013/parcsr_ls/HYPRE_parcsr_amg.c
f45	: AMG2013/parcsr_ls/headers.h
f46	: AMG2013/parcsr_ls/parcsr_ls.h
f47	: AMG2013/parcsr_ls/par_amg.h
f48	: AMG2013/parcsr_ls/HYPRE_parcsr_gmres.c
f49	: AMG2013/parcsr_ls/HYPRE_parcsr_pcg.c
f50	: AMG2013/parcsr_ls/aux_interp.c
f51	: AMG2013/parcsr_ls/gen_redcs_mat.c
f52	: AMG2013/parcsr_ls/par_amg.c
f53	: AMG2013/parcsr_ls/par_amg_setup.c
f54	: AMG2013/parcsr_ls/par_amg_solve.c
f55	: AMG2013/parcsr_ls/par_cg_relax_wt.c
f56	: AMG2013/parcsr_ls/par_coarse_parms.c
f57	: AMG2013/parcsr_ls/par_coarsen.c
f58	: AMG2013/parcsr_ls/par_cycle.c
f59	: AMG2013/parcsr_ls/par_indepset.c
f60	: AMG2013/parcsr_ls/par_interp.c
f61	: AMG2013/parcsr_ls/../utilities/hypre_smp_forloop.h
f62	: AMG2013/parcsr_ls/par_jacobi_interp.c
f63	: AMG2013/parcsr_ls/par_laplace.c
f64	: AMG2013/parcsr_ls/par_laplace_27pt.c
f65	: AMG2013/parcsr_ls/par_lr_interp.c
f66	: AMG2013/parcsr_ls/aux_interp.h
f67	: AMG2013/parcsr_ls/par_multi_interp.c
f68	: AMG2013/parcsr_ls/par_nodal_systems.c
f69	: AMG2013/parcsr_ls/par_rap.c
f70	: AMG2013/parcsr_ls/par_rap_communication.c
f71	: AMG2013/parcsr_ls/par_relax.c
f72	: AMG2013/parcsr_ls/par_relax_interface.c
f73	: AMG2013/parcsr_ls/par_relax_more.c
f74	: /include/abc/float.h
f75	: AMG2013/parcsr_ls/par_scaled_matnorm.c
f76	: AMG2013/parcsr_ls/par_stats.c
f77	: AMG2013/parcsr_ls/par_strength.c
f78	: AMG2013/parcsr_ls/par_vardifconv.c
f79	: AMG2013/parcsr_ls/partial.c
f80	: AMG2013/parcsr_ls/pcg_par.c
f81	: AMG2013/parcsr_mv/HYPRE_parcsr_matrix.c
f82	: AMG2013/parcsr_mv/headers.h
f83	: AMG2013/parcsr_mv/HYPRE_parcsr_vector.c
f84	: AMG2013/parcsr_mv/new_commpkg.c
f85	: AMG2013/parcsr_mv/par_csr_assumed_part.c
f86	: AMG2013/parcsr_mv/par_csr_communication.c
f87	: AMG2013/parcsr_mv/par_csr_matop.c
f88	: AMG2013/parcsr_mv/../parcsr_mv/parcsr_mv.h
f89	: AMG2013/parcsr_mv/../parcsr_mv/HYPRE_parcsr_mv.h
f90	: AMG2013/parcsr_mv/par_csr_matop_marked.c
f91	: AMG2013/parcsr_mv/par_csr_matrix.c
f92	: AMG2013/parcsr_mv/../seq_mv/HYPRE_seq_mv.h
f93	: AMG2013/parcsr_mv/../seq_mv/csr_matrix.h
f94	: AMG2013/parcsr_mv/par_csr_matvec.c
f95	: AMG2013/parcsr_mv/par_vector.c
f96	: AMG2013/seq_mv/HYPRE_csr_matrix.c
f97	: AMG2013/seq_mv/headers.h
f98	: AMG2013/seq_mv/HYPRE_vector.c
f99	: AMG2013/seq_mv/big_csr_matrix.c
f100	: AMG2013/seq_mv/csr_matop.c
f101	: AMG2013/seq_mv/csr_matrix.c
f102	: AMG2013/seq_mv/csr_matvec.c
f103	: AMG2013/seq_mv/genpart.c
f104	: AMG2013/seq_mv/vector.c
f105	: AMG2013/sstruct_mv/HYPRE_sstruct_graph.c
f106	: AMG2013/sstruct_mv/headers.h
f107	: AMG2013/sstruct_mv/HYPRE_sstruct_grid.c
f108	: AMG2013/sstruct_mv/HYPRE_sstruct_matrix.c
f109	: AMG2013/sstruct_mv/HYPRE_sstruct_stencil.c
f110	: AMG2013/sstruct_mv/HYPRE_sstruct_vector.c
f111	: AMG2013/sstruct_mv/box_map.c
f112	: AMG2013/sstruct_mv/sstruct_axpy.c
f113	: AMG2013/sstruct_mv/sstruct_copy.c
f114	: AMG2013/sstruct_mv/sstruct_graph.c
f115	: AMG2013/sstruct_mv/sstruct_grid.c
f116	: AMG2013/sstruct_mv/sstruct_innerprod.c
f117	: AMG2013/sstruct_mv/sstruct_matrix.c
f118	: AMG2013/sstruct_mv/sstruct_matvec.c
f119	: AMG2013/sstruct_mv/sstruct_overlap_innerprod.c
f120	: AMG2013/sstruct_mv/sstruct_scale.c
f121	: AMG2013/sstruct_mv/sstruct_stencil.c
f122	: AMG2013/sstruct_mv/sstruct_vector.c
f123	: AMG2013/struct_mv/HYPRE_struct_grid.c
f124	: AMG2013/struct_mv/headers.h
f125	: AMG2013/struct_mv/HYPRE_struct_matrix.c
f126	: AMG2013/struct_mv/HYPRE_struct_stencil.c
f127	: AMG2013/struct_mv/HYPRE_struct_vector.c
f128	: AMG2013/struct_mv/assumed_part.c
f129	: AMG2013/struct_mv/box.c
f130	: AMG2013/struct_mv/box_algebra.c
f131	: AMG2013/struct_mv/box_alloc.c
f132	: AMG2013/struct_mv/box_boundary.c
f133	: AMG2013/struct_mv/box_manager.c
f134	: AMG2013/struct_mv/box_neighbors.c
f135	: AMG2013/struct_mv/communication_info.c
f136	: AMG2013/struct_mv/computation.c
f137	: AMG2013/struct_mv/grow.c
f138	: AMG2013/struct_mv/new_assemble.c
f139	: AMG2013/struct_mv/new_box_neighbors.c
f140	: AMG2013/struct_mv/project.c
f141	: AMG2013/struct_mv/struct_axpy.c
f142	: AMG2013/struct_mv/struct_communication.c
f143	: AMG2013/struct_mv/struct_copy.c
f144	: AMG2013/struct_mv/struct_grid.c
f145	: AMG2013/struct_mv/struct_innerprod.c
f146	: AMG2013/struct_mv/struct_io.c
f147	: AMG2013/struct_mv/struct_matrix.c
f148	: AMG2013/struct_mv/struct_matrix_mask.c
f149	: AMG2013/struct_mv/struct_matvec.c
f150	: AMG2013/struct_mv/struct_overlap_innerprod.c
f151	: AMG2013/struct_mv/struct_scale.c
f152	: AMG2013/struct_mv/struct_stencil.c
f153	: AMG2013/struct_mv/struct_vector.c
f154	: AMG2013/utilities/amg_linklist.c
f155	: AMG2013/utilities/binsearch.c
f156	: AMG2013/utilities/exchange_data.c
f157	: AMG2013/utilities/hypre_error.c
f158	: AMG2013/utilities/hypre_memory.c
f159	: AMG2013/utilities/hypre_qsort.c
f160	: AMG2013/utilities/memory_dmalloc.c
f161	: AMG2013/utilities/mpistubs.c
f162	: AMG2013/utilities/qsplit.c
f163	: AMG2013/utilities/random.c
f164	: AMG2013/utilities/thread_mpistubs.c
f165	: AMG2013/utilities/threading.c
f166	: AMG2013/utilities/timer.c
f167	: /include/abc/time.h
f168	: /include/abc/unistd.h
f169	: /include/abc/sys/types.h
f170	: /include/abc/inttypes.h
f171	: /include/abc/stdint.h
f172	: /include/abc/sys/times.h
f173	: AMG2013/utilities/timing.c
f174	: AMG2013/utilities/timing.h
f175	: AMG2013/utilities/umalloc_local.c

Required source files:
f1	: AMG2013/test/amg2013.c
f2	: /include/abc/stdlib.h
f3	: /include/abc/stdio.h
f4	: /include/abc/civl-stdio.cvh
f5	: /include/abc/civlc.cvh
f6	: /include/abc/op.h
f8	: /include/abc/math.h
f9	: AMG2013/utilities/utilities.h
f10	: AMG2013/utilities/HYPRE_utilities.h
f12	: /include/abc/mpi.h
f13	: /include/abc/string.h
f15	: AMG2013/parcsr_mv/HYPRE_parcsr_mv.h
f16	: AMG2013/seq_mv/HYPRE_seq_mv.h
f17	: AMG2013/sstruct_mv/HYPRE_sstruct_mv.h
f18	: AMG2013/struct_mv/HYPRE_struct_mv.h
f19	: AMG2013/IJ_mv/HYPRE_IJ_mv.h
f20	: AMG2013/parcsr_ls/HYPRE_parcsr_ls.h
f21	: AMG2013/krylov/krylov.h
f22	: AMG2013/sstruct_mv/sstruct_mv.h
f23	: AMG2013/struct_mv/struct_mv.h
f25	: AMG2013/IJ_mv/IJ_mv.h
f26	: AMG2013/seq_mv/seq_mv.h
f27	: AMG2013/parcsr_mv/parcsr_mv.h
f28	: AMG2013/IJ_mv/HYPRE_IJMatrix.c
f32	: AMG2013/IJ_mv/HYPRE_IJVector.c
f33	: AMG2013/IJ_mv/IJMatrix_parcsr.c
f35	: AMG2013/IJ_mv/IJVector_parcsr.c
f36	: AMG2013/IJ_mv/aux_par_vector.c
f38	: AMG2013/IJ_mv/aux_parcsr_matrix.c
f40	: AMG2013/krylov/HYPRE_gmres.c
f41	: AMG2013/krylov/HYPRE_pcg.c
f42	: AMG2013/krylov/gmres.c
f43	: AMG2013/krylov/pcg.c
f44	: AMG2013/parcsr_ls/HYPRE_parcsr_amg.c
f45	: AMG2013/parcsr_ls/headers.h
f46	: AMG2013/parcsr_ls/parcsr_ls.h
f47	: AMG2013/parcsr_ls/par_amg.h
f48	: AMG2013/parcsr_ls/HYPRE_parcsr_gmres.c
f49	: AMG2013/parcsr_ls/HYPRE_parcsr_pcg.c
f50	: AMG2013/parcsr_ls/aux_interp.c
f51	: AMG2013/parcsr_ls/gen_redcs_mat.c
f52	: AMG2013/parcsr_ls/par_amg.c
f53	: AMG2013/parcsr_ls/par_amg_setup.c
f54	: AMG2013/parcsr_ls/par_amg_solve.c
f55	: AMG2013/parcsr_ls/par_cg_relax_wt.c
f56	: AMG2013/parcsr_ls/par_coarse_parms.c
f57	: AMG2013/parcsr_ls/par_coarsen.c
f58	: AMG2013/parcsr_ls/par_cycle.c
f59	: AMG2013/parcsr_ls/par_indepset.c
f60	: AMG2013/parcsr_ls/par_interp.c
f62	: AMG2013/parcsr_ls/par_jacobi_interp.c
f63	: AMG2013/parcsr_ls/par_laplace.c
f64	: AMG2013/parcsr_ls/par_laplace_27pt.c
f65	: AMG2013/parcsr_ls/par_lr_interp.c
f67	: AMG2013/parcsr_ls/par_multi_interp.c
f68	: AMG2013/parcsr_ls/par_nodal_systems.c
f69	: AMG2013/parcsr_ls/par_rap.c
f70	: AMG2013/parcsr_ls/par_rap_communication.c
f71	: AMG2013/parcsr_ls/par_relax.c
f72	: AMG2013/parcsr_ls/par_relax_interface.c
f73	: AMG2013/parcsr_ls/par_relax_more.c
f75	: AMG2013/parcsr_ls/par_scaled_matnorm.c
f76	: AMG2013/parcsr_ls/par_stats.c
f77	: AMG2013/parcsr_ls/par_strength.c
f78	: AMG2013/parcsr_ls/par_vardifconv.c
f79	: AMG2013/parcsr_ls/partial.c
f80	: AMG2013/parcsr_ls/pcg_par.c
f81	: AMG2013/parcsr_mv/HYPRE_parcsr_matrix.c
f83	: AMG2013/parcsr_mv/HYPRE_parcsr_vector.c
f85	: AMG2013/parcsr_mv/par_csr_assumed_part.c
f86	: AMG2013/parcsr_mv/par_csr_communication.c
f87	: AMG2013/parcsr_mv/par_csr_matop.c
f90	: AMG2013/parcsr_mv/par_csr_matop_marked.c
f91	: AMG2013/parcsr_mv/par_csr_matrix.c
f94	: AMG2013/parcsr_mv/par_csr_matvec.c
f95	: AMG2013/parcsr_mv/par_vector.c
f99	: AMG2013/seq_mv/big_csr_matrix.c
f100	: AMG2013/seq_mv/csr_matop.c
f101	: AMG2013/seq_mv/csr_matrix.c
f102	: AMG2013/seq_mv/csr_matvec.c
f103	: AMG2013/seq_mv/genpart.c
f104	: AMG2013/seq_mv/vector.c
f105	: AMG2013/sstruct_mv/HYPRE_sstruct_graph.c
f107	: AMG2013/sstruct_mv/HYPRE_sstruct_grid.c
f108	: AMG2013/sstruct_mv/HYPRE_sstruct_matrix.c
f109	: AMG2013/sstruct_mv/HYPRE_sstruct_stencil.c
f110	: AMG2013/sstruct_mv/HYPRE_sstruct_vector.c
f111	: AMG2013/sstruct_mv/box_map.c
f114	: AMG2013/sstruct_mv/sstruct_graph.c
f115	: AMG2013/sstruct_mv/sstruct_grid.c
f117	: AMG2013/sstruct_mv/sstruct_matrix.c
f118	: AMG2013/sstruct_mv/sstruct_matvec.c
f121	: AMG2013/sstruct_mv/sstruct_stencil.c
f122	: AMG2013/sstruct_mv/sstruct_vector.c
f123	: AMG2013/struct_mv/HYPRE_struct_grid.c
f125	: AMG2013/struct_mv/HYPRE_struct_matrix.c
f126	: AMG2013/struct_mv/HYPRE_struct_stencil.c
f129	: AMG2013/struct_mv/box.c
f130	: AMG2013/struct_mv/box_algebra.c
f132	: AMG2013/struct_mv/box_boundary.c
f134	: AMG2013/struct_mv/box_neighbors.c
f135	: AMG2013/struct_mv/communication_info.c
f136	: AMG2013/struct_mv/computation.c
f142	: AMG2013/struct_mv/struct_communication.c
f144	: AMG2013/struct_mv/struct_grid.c
f146	: AMG2013/struct_mv/struct_io.c
f147	: AMG2013/struct_mv/struct_matrix.c
f149	: AMG2013/struct_mv/struct_matvec.c
f151	: AMG2013/struct_mv/struct_scale.c
f152	: AMG2013/struct_mv/struct_stencil.c
f153	: AMG2013/struct_mv/struct_vector.c
f154	: AMG2013/utilities/amg_linklist.c
f155	: AMG2013/utilities/binsearch.c
f157	: AMG2013/utilities/hypre_error.c
f158	: AMG2013/utilities/hypre_memory.c
f159	: AMG2013/utilities/hypre_qsort.c
f163	: AMG2013/utilities/random.c
f166	: AMG2013/utilities/timer.c
f167	: /include/abc/time.h
f168	: /include/abc/unistd.h
f172	: /include/abc/sys/times.h
f173	: AMG2013/utilities/timing.c

Entities used from f1: AMG2013/test/amg2013.c :
  hypre_SStructStencil
  time_getWallclockSeconds
  HYPRE_GMRESSetTol
  hypre_StructStencilDestroy
  hypre_ParCSRMatrixRestoreRow
  hypre_CommInfo
  hypre_StructGrid
  hypre_BoxExpand
  hypre_Vector
  hypre_SeqVectorSetRandomValues
  sqrt
  hypre_SStructPMatvecDestroy
  hypre_BoxMapDestroy
  double_linked_list
  hypre_ExchangeLocalData
  hypre_SStructPMatrixSetSymmetric
  hypre_FinalizeTiming
  hypre_BoxArrayDestroy
  hypre_SubtractBoxArraysExceptBoxes
  HYPRE_SStructGraphDestroy
  MPI_Waitall
  MPI_Test
  HYPRE_IJVectorAssemble
  HYPRE_StructMatrixSetSymmetric
  hypre_SStructGrid_struct
  HYPRE_PCGSetTwoNorm
  MPI_Op_create
  hypre_SStructNBorBoxToBox
  hypre_SeqVectorCreate
  hypre_AuxParCSRMatrixCreate
  HYPRE_SStructGraphAssemble
  fgets
  hypre_BoxMapEntryGetExtents
  HYPRE_BoomerAMGSetCycleRelaxType
  hypre_GMRESSetPrintLevel
  hypre_StructVectorSetBoxValues
  HYPRE_ParCSRGMRESCreate
  enter_on_lists
  hypre_SStructMatvecCreate
  hypre_StructMatrixPrint
  hypre_SStructVector
  hypre_BoxMapEntry
  MPI_Group_incl
  strlen
  hypre_ParVectorSetPartitioningOwner
  MapProblemIndex
  calloc
  HYPRE_BoomerAMGSetTruncFactor
  hypre_CommInfoCreate
  hypre_SStructNeighbor
  hypre_SStructVectorRestore
  hypre_ParVectorScale
  hypre_SStructVectorParRestore
  HYPRE_StructMatrix
  hypre_SeqVectorDestroy
  hypre_BoxArrayArrayDestroy
  HYPRE_IJMatrixPrint
  atof
  hypre_ParCSRMatrixCopy
  hypre_SStructPMatvecCreate
  hypre_CAlloc
  hypre_StructVectorAssemble
  hypre_ParCSRMatrixDestroyAssumedPartition
  hypre_ParCSRMatrixGetRow
  hypre_ParCSRMatrixDestroy
  hypre_EndTiming
  HYPRE_IJVectorSetObjectType
  hypre_AuxParVectorInitialize
  hypre_SStructPVectorInitializeShell
  hypre_SStructStencilRef
  hypre_SStructPVectorDestroy
  hypre_Free
  HYPRE_BoomerAMGSetAggNumLevels
  hypre_IJMatrix_struct
  HYPRE_IJMatrixSetValues
  hypre_StructGrid_struct
  HYPRE_GMRESSolve
  HYPRE_Solver
  HYPRE_PCGGetNumIterations
  MPI_Group
  hypre_BoxDuplicate
  hypre_CommPkg
  HYPRE_SStructGrid
  hypre_BoxBoundaryDNT
  hypre_ComputePkgCreate
  hypre_StructVectorClearBoundGhostValues
  hypre_CreateCommInfoFromStencil
  hypre_ParVectorToVectorAll
  hypre_SStructVectorInitializeShell
  MPI_Comm_rank
  hypre_ParVectorDestroyAssumedPartition
  HYPRE_StructGridCreate
  HYPRE_BoomerAMGSetRelaxOrder
  ProblemIndex
  HYPRE_IJMatrixAddToValues
  MPI_COMM_WORLD
  MPI_Allreduce
  hypre_SStructBoxToNBorBox
  hypre_CSRMatrixTranspose
  fabs
  HYPRE_SStructVector
  hypre_StructStencilCreate
  hypre_BoxMap
  hypre_IJVectorAssemblePar
  hypre_CreateComputeInfo
  swap2
  atoi
  hypre_GMRESDestroy
  HYPRE_StructStencilSetElement
  hypre_ParVectorSetRandomValues
  hypre_CommEntryType
  DestroyData
  realloc
  hypre_PCGFunctions
  hypre_ParCSRMatrixMatvec
  FILE
  hypre_StructMatrixInitializeShell
  hypre_ParCSRMatrixSetColStartsOwner
  hypre_Index
  hypre_BigQsortbi
  HYPRE_IJMatrixSetRowSizes
  hypre_StructVectorCreate
  hypre_BoxMapIncSize
  HYPRE_IJMatrix
  HYPRE_ParCSRPCGSolve
  hypre__global_error
  MPI_COMM_NULL
  HYPRE_BoomerAMGSetStrongThreshold
  HYPRE_BoomerAMGSetGridRelaxType
  hypre_SStructUCVar
  HYPRE_GMRESSetMaxIter
  MPI_Get_count
  hypre_ParVectorPrintIJ
  hypre_SStructPMatrixAssemble
  HYPRE_SStructMatrixAssemble
  HYPRE_StructStencilDestroy
  hypre_SubtractBoxArrays
  hypre_global_timing
  HYPRE_IJVectorCreate
  hypre_SStructMapInfo
  hypre_ParVectorCreate
  hypre_IndexRef
  memcpy
  HYPRE_SStructVectorSetBoxValues
  hypre_ParCSRMatrixPrintIJ
  HYPRE_BoomerAMGSetPrintLevel
  MPI_Gatherv
  hypre_SStructPVectorSetBoxValues
  hypre_AppendBox
  hypre_StructMatvecDestroy
  hypre_SStructMapEntryGetBox
  time_getCPUSeconds
  MPI_Irecv
  hypre_IJMatrixDestroyParCSR
  free
  hypre_Rand
  MPI_Bcast
  MPI_Datatype
  hypre_MAlloc
  hypre_SStructVariable_enum
  GenerateLaplacian27pt
  hypre_PCGSetTol
  hypre_StructMatvecSetup
  HYPRE_StructStencilCreate
  HYPRE_BoomerAMGSetRelaxWeight
  hypre_ParVector
  HYPRE_IJVectorGetObject
  hypre_FinalizeCommunication
  HYPRE_StructGridSetExtents
  hypre_GMRESCreate
  HYPRE_SStructGraphSetObjectType
  hypre_StructMatrixSetNumGhost
  hypre_CSRMatrixCopy
  hypre_SStructGridAssembleMaps
  SScanIntArray
  HYPRE_SStructVariable
  hypre_StructMatrixInitializeData
  hypre_OutOfMemory
  hypre_Solver_struct
  HYPRE_BoomerAMGSolve
  HYPRE_PtrToSolverFcn
  hypre_SStructGridFindMapEntry
  hypre_error_handler
  hypre_BigCSRMatrixDestroy
  hypre_StructVector_struct
  pow
  HYPRE_BoomerAMGCreate
  abs
  hypre_ParMatmul_RowSizes_Marked
  hypre_GMRESSetKDim
  sprintf
  hypre_StructGridSetBoxes
  MPI_Status
  hypre_PCGFunctionsCreate
  HYPRE_ParCSRMatrixPrintIJ
  hypre_CSRMatrixCreate
  hypre_IJVector
  HYPRE_IJMatrixAssemble
  hypre_BinarySearch
  HYPRE_StructGrid
  HYPRE_SStructVectorAssemble
  HYPRE_SStructGridSetPeriodic
  HYPRE_PCGSetPrecond
  hypre_BoxNeighbors
  hypre_ParCSRMatrix
  HYPRE_PCGSetTol
  hypre_PCGSetPrintLevel
  hypre_SStructMapEntryGetGlobalGhrank
  HYPRE_Matrix
  hypre_SStructMapEntryGetGhstrides
  HYPRE_ParCSRMatrix
  hypre_SStructPMatrixSetBoxValues
  hypre_StructMatrixAssemble
  Operation
  hypre_SStructVector_struct
  MPI_Comm_group
  hypre_Vector_struct
  hypre_SStructUMatrixInitialize
  HYPRE_SStructGraphAddEntries
  hypre_BoxArrayArray
  hypre_StructMatrixInitialize
  hypre_StructMatvecCC2
  HYPRE_Vector
  hypre_SStructGridBoxProcFindMapEntry
  hypre_GMRESSetLogging
  hypre_PCGGetNumIterations
  hypre_RankLink
  HYPRE_SStructGraph
  hypre_IJVectorInitializePar
  HYPRE_SStructVectorInitialize
  hypre_Box
  HYPRE_GMRESSetPrecond
  HYPRE_GMRESSetLogging
  HYPRE_SStructVectorGetObject
  HYPRE_ParCSRMatrixMatvec
  hypre_SStructVectorConvert
  hypre_SStructMapEntryGetCSRstrides
  hypre_BigSwap
  hypre_PCGSetMaxIter
  hypre_CommPkgCreate
  hypre_StructVectorInitializeShell
  hypre_CSRMatrixUnion
  hypre_GMRESFunctionsCreate
  hypre_SeqVectorInitialize
  hypre_SStructPMatvecSetup
  fprintf
  HYPRE_BoomerAMGSetPMaxElmts
  hypre_GMRESSetPrecond
  hypre_FindProc
  HYPRE_GMRESSetup
  hypre_StructGridDestroy
  hypre_PCGSetup
  SScanDblArray
  create_elt
  HYPRE_ParCSRMatrixRestoreRow
  hypre_SStructPMatvecCompute
  hypre_BoxMapFindEntry
  HYPRE_BoomerAMGSetMaxRowSum
  IntersectBoxes
  hypre_SStructPVector
  HYPRE_SStructMatrixSetBoxValues
  strspn
  hypre_SeqVectorInnerProd
  sscanf
  hypre_PCGSetRelChange
  hypre_PCGSetPrecond
  infile_default
  HYPRE_StructGridDestroy
  hypre_CommHandle
  hypre_SStructVariableGetOffset
  fclose
  HYPRE_BoomerAMGSetTol
  hypre_StructGridCreate
  hypre_ParMatmul
  hypre_ParMatScaleDiagInv_F
  HYPRE_SStructGridCreate
  HYPRE_PCGSolve
  hypre_ParVectorDestroy
  hypre_SStructGraphFindUVEntry
  HYPRE_GMRESGetFinalRelativeResidualNorm
  hypre_StructGridAssemble
  hypre_SStructPMatrixPrint
  hypre_SStructPMatrixCreate
  hypre_SStructMapEntryGetGlobalRank
  hypre_ParMatMinus_F
  strtol
  hypre_SStructStencil_struct
  HYPRE_SStructMatrixSetValues
  hypre_BoxArrayDuplicate
  hypre_IJMatrixSetRowSizesParCSR
  hypre_CommPkgDestroy
  hypre_StructMatvecCC0
  main
  HYPRE_ParCSRMatrixGetRow
  hypre_SStructNMapInfo
  hypre_LinkList
  HYPRE_PCGSetMaxIter
  hypre_StructGridPrint
  hypre_TimingType
  hypre_BoxMapIntersect
  HYPRE_GMRESGetNumIterations
  hypre_SStructPMatrix
  hypre_ComputeInfo
  hypre_SStructPMatrixDestroy
  hypre_BoxGetStrideSize
  hypre_BoxNeighborsCreate
  hypre_SStructGraph
  hypre_BoxArrayCreate
  hypre_BoxMapEntryGetInfo
  hypre_GMRESSetTol
  hypre_StructVectorDestroy
  HYPRE_StructGridSetPeriodic
  HYPRE_BoomerAMGSetInterpType
  hypre_BoxSetExtents
  hypre_SStructGraphRef
  hypre_GMRESGetNumIterations
  hypre_StructMatrixExtractPointerByIndex
  HYPRE_IJMatrixGetValues
  HYPRE_SStructMatrixInitialize
  hypre_PrintCCBoxArrayData
  MPI_Finalize
  hypre_BoxCreate
  hypre_BigCSRMatrix
  hypre_ParCSRMatrixInitialize
  hypre_BoxNeighborsAssemble
  hypre_InitializeIndtComputations
  HYPRE_SStructGridSetExtents
  hypre_AuxParCSRMatrix
  hypre_BoxArray
  strcspn
  HYPRE_IJMatrixInitialize
  hypre_SStructGridRef
  hypre_IJAssumedPart
  hypre_ParVectorAxpy
  hypre_SStructGraph_struct
  hypre_PrintCCVDBoxArrayData
  hypre_SStructVectorParConvert
  HYPRE_ParVectorPrintIJ
  hypre_GMRESSolve
  hypre_StructStencil_struct
  MPI_User_function
  hypre_ClearTiming
  HYPRE_SStructMatrix
  HYPRE_IJVectorDestroy
  hypre_PrintTiming
  HYPRE_ParCSRDiagScale
  hypre_SStructPVectorPrint
  hypre_SStructMatvecSetup
  hypre_StructStencilRef
  MPI_Allgatherv
  hypre_GeneratePartitioning
  hypre_IntersectBoxes
  hypre_AuxParCSRMatrixInitialize
  HYPRE_IJMatrixCreate
  hypre_GatherAllBoxes
  strtod
  MPI_Comm
  hypre_StructMatrix
  printf
  hypre_SStructUMatrixSetValues
  hypre_StructMatrixDestroy
  hypre_CommPkg_struct
  hypre_RankLinkCreate
  hypre_BeginTiming
  hypre_PCGCreate
  hypre_BoxNeighborsDestroy
  HYPRE_BoomerAMGSetGridRelaxPoints
  HYPRE_BoomerAMGSetMaxIter
  hypre_PrintBoxArrayData
  hypre_BoxMapAddEntry
  dispose_elt
  hypre_BoxArrayArrayDuplicate
  hypre_BoxBoundaryNT
  hypre_BoxMapAssemble
  hypre_InitializeTiming
  hypre_StructMatrix_struct
  HYPRE_SStructStencilCreate
  hypre_PCGGetFinalRelativeResidualNorm
  hypre_ParCSRMatrixCopy_C
  hypre_BoxGetStrideVolume
  hypre_SStructPGridSetExtents
  hypre_StructScale
  PrintUsage
  hypre_ParVector_struct
  HYPRE_GMRESSetPrintLevel
  hypre_ParCSRMatrixZero_F
  HYPRE_PCGSetRelChange
  hypre_IJVectorCreatePar
  HYPRE_BoomerAMGSetRelaxType
  fflush
  hypre_SStructMatrixSplitEntries
  HYPRE_SStructGraphSetStencil
  BuildParLaplacian27pt
  HYPRE_SStructStencil
  hypre_ParCSRMatrix_struct
  hypre_StructVectorPrint
  hypre_AuxParVectorCreate
  hypre_SStructUVar
  hypre_StructMatrixCreate
  hypre_StructVectorRef
  hypre_ListElement
  hypre_ParCSRMatrixSetNumNonzeros
  HYPRE_StructStencil
  hypre_StructMatvecCC1
  hypre_StructGridSetPeriodic
  HYPRE_SStructVectorCreate
  hypre_CSRMatrixMatvecT
  HYPRE_SStructGridSetVariables
  SScanProblemIndex
  hypre_StructStencil
  hypre_SStructUEntry
  MPI_Barrier
  hypre_ParCSRMatrixToCSRMatrixAll
  hypre_PCGData
  MPI_Send
  qsort0
  DistributeData
  hypre_BoxArrayArrayCreate
  hypre_ParVectorInnerProd
  MPI_Recv
  hypre_SStructPVectorAssemble
  hypre_IJVectorDestroyPar
  HYPRE_ParCSRPCGCreate
  hypre_MergeDiagAndOffd
  hypre_StructGridRef
  hypre_SStructGrid
  hypre_ParCSRCommHandleDestroy
  hypre_SStructPVectorGather
  HYPRE_GMRESSetKDim
  hypre_ParVectorSetConstantValues
  hypre_IJMatrixCreateParCSR
  hypre_Matrix_struct
  hypre_IJMatrixAssembleParCSR
  hypre_CommTypeSetEntries
  fopen
  hypre_ReAlloc
  hypre_ParMatmul_FC
  HYPRE_StructGridAssemble
  hypre_BoxMapSetNumGhost
  hypre_ParCSRMatrixSetRowStartsOwner
  hypre_SStructVariable
  GetVariableBox
  HYPRE_SStructVectorGather
  hypre_SStructPMatrixInitialize
  hypre_ComputeInfoDestroy
  HYPRE_SStructGridAssemble
  hypre_BoxMapFindBoxProcEntry
  HYPRE_IJVector
  hypre_IJMatrixAssembleOffProcValsParCSR
  hypre_SStructUMatrixSetBoxValues
  HYPRE_SStructGridSetNeighborBox
  hypre_StructMatrixSetBoxValues
  hypre_GMRESGetFinalRelativeResidualNorm
  cos
  BuildParLaplacian
  BuildParVarDifConv
  hypre_SeqVectorCopy
  HYPRE_PCGSetPrintLevel
  Index
  HYPRE_BoomerAMGSetNumGridSweeps
  hypre_BigQsort0
  hypre_SeqVectorAxpy
  hypre_SStructMatvec
  hypre_SStructGridAssembleNBorMaps
  MPI_Scatterv
  hypre_SStructMapInfoType
  MPI_Init
  hypre_ParCSRMatrixMatvecT
  strncpy
  hypre_CommType
  exit
  HYPRE_IJVectorInitialize
  hypre_StructStencilSymmetrize
  hypre_IJMatrixSetValuesParCSR
  GenerateVarDifConv
  hypre_ParCSRCommHandleCreate
  MPI_Gather
  MPI_Isend
  hypre_BigCSRMatrixCreate
  hypre_SStructMatvecDestroy
  hypre_SStructPGrid
  hypre_SeqVectorScale
  hypre_GMRESData
  hypre_IJMatrixGetValuesParCSR
  hypre_ParCSRMatrixExtractBigExt
  HYPRE_SStructStencilSetEntry
  hypre_GMRESFunctions
  hypre_GMRESSetup
  hypre_MatvecCommPkgCreate_core
  hypre_SStructMapEntryGetProcess
  HYPRE_PCGSetup
  hypre_MatvecCommPkgDestroy
  HYPRE_BoomerAMGSetCoarsenType
  hypre_RankLinkDestroy
  hypre_ParCSRCommHandle
  hypre_PCGSolve
  hypre_BoxArraySubtractAdjacentBoxArrayD
  hypre_PCGDestroy
  HYPRE_SStructMatrixDestroy
  size_t
  MPI_Op_free
  HYPRE_ParCSRPCGSetup
  HYPRE_BoomerAMGDestroy
  MPI_Comm_size
  stdout
  MPI_COMM_SELF
  hypre_CSRMatrixInitialize
  hypre_ParCSRMatrixSetDNumNonzeros
  hypre_CSRMatrixMatvec
  hypre_StructMatvecCreate
  hypre_BigBinarySearch
  hypre_SStructPVectorCreate
  malloc
  hypre_CommTypeSetEntry
  HYPRE_BoomerAMGSetup
  GenerateLaplacian
  HYPRE_IJMatrixGetObject
  hypre_AuxParVectorDestroy
  HYPRE_SStructMatrixCreate
  hypre_InitializeCommunication
  hypre_StructMatvecCompute
  hypre_SStructMapEntryGetGlobalCSRank
  HYPRE_SStructMatrixSetSymmetric
  ProblemPartData
  hypre_SStructMatvecCompute
  hypre_PCGSetTwoNorm
  HYPRE_SStructMatrixSetNSSymmetric
  hypre_SStructPGridAssemble
  hypre_SeqVectorSetConstantValues
  HYPRE_IJMatrixDestroy
  hypre_ParVectorCopy
  hypre_ParVectorInitialize
  hypre_ParCSRMatrixExtractConvBExt
  hypre_IJMatrix
  hypre_CreateCommInfoFromNumGhost
  hypre_SStructMapEntryGetStrides
  swap
  HYPRE_SStructVectorDestroy
  hypre_StructMatrixSetValues
  remove_point
  HYPRE_BoomerAMGSetPrintFileName
  hypre_AppendBoxArray
  hypre_BoxGetSize
  hypre_IJVectorAssembleOffProcValsPar
  hypre_CSRMatrixDestroy
  hypre_SStructUMatrixAssemble
  hypre_StructMatrixRef
  hypre_BoxBoundaryG
  hypre_SStructPGridSetPNeighbor
  HYPRE_SStructGraphCreate
  hypre_StructStencilElementRank
  MPI_Op
  hypre_CommInfoDestroy
  hypre_SStructMatrix_struct
  hypre_BoxMapCreate
  MPI_Request
  MPI_Testall
  HYPRE_SStructStencilDestroy
  HYPRE_ParCSRPCGDestroy
  hypre_IJMatrixAddToValuesParCSR
  hypre_ComputePkgDestroy
  hypre_ParMatmul_RowSizes
  strcmp
  hypre_SStructPGridDestroy
  hypre_BoxArraySetSize
  hypre_ParCSRMatrixUnion
  hypre_GMRESSetMaxIter
  HYPRE_SStructVectorSetObjectType
  hypre_SStructPMatrixSetValues
  HYPRE_SStructMatrixGetObject
  hypre_StructVectorInitializeData
  hypre_AuxParVector
  HYPRE_BoomerAMGSetNumFunctions
  hypre_AuxParCSRMatrixDestroy
  hypre_SStructPGridCreate
  SetCosineVector
  hypre_StructVector
  stderr
  HYPRE_SStructGridDestroy
  hypre_SStructMatrix
  MPI_Allgather
  HYPRE_SStructMatrixSetObjectType
  HYPRE_ParCSRMatrixDestroy
  HYPRE_IJMatrixSetObjectType
  HYPRE_SStructVectorPrint
  HYPRE_ParCSRDiagScaleSetup
  ProblemData
  hypre_CSRMatrix
  hypre_IJMatrixInitializeParCSR
  HYPRE_ParVector
  HYPRE_SStructMatrixPrint
  HYPRE_PCGGetFinalRelativeResidualNorm
  MPI_Group_free
  hypre_SStructPGridSetVariables
  hypre_IJVector_struct
  HYPRE_SStructMatrixAddToBoxValues
  hypre_StructGridSetExtents
  MPI_Comm_create
  hypre_MatvecCommPkgCreate
  HYPRE_ParCSRGMRESDestroy
  ReadData
  hypre_ParCSRMatrixCreate
  hypre_FinalizeIndtComputations
  hypre_ComputePkg
  hypre_CSRMatrixSetRownnz
  hypre_SeedRand
  hypre_SubtractBoxes
  HYPRE_ParVectorDestroy
  hypre_BoxDestroy
  hypre_ComputeInfoCreate
  hypre_BigSwapbi
  hypre_SStructUVEntry
  MPI_Iprobe
  hypre_ComputeBoxnums
  HYPRE_BoomerAMGSetCycleNumSweeps
  hypre_ParCSRCommPkg

Entities used from f2: /include/abc/stdlib.h :
  realloc
  abs
  size_t
  atof
  free
  malloc
  atoi
  calloc
  exit
  strtod
  strtol

Entities used from f3: /include/abc/stdio.h :
  fprintf
  sscanf
  Operation
  sprintf
  FILE
  fclose
  fopen
  printf
  stderr
  stdout
  fflush
  fgets

Entities used from f4: /include/abc/civl-stdio.cvh :
  Operation
  FILE

Entities used from f5: /include/abc/civlc.cvh :
  Operation

Entities used from f6: /include/abc/op.h :
  Operation

Entities used from f8: /include/abc/math.h :
  sqrt
  pow
  cos
  fabs

Entities used from f9: AMG2013/utilities/utilities.h :
  MPI_Comm_rank
  time_getWallclockSeconds
  strcspn
  hypre_OutOfMemory
  MPI_Barrier
  MPI_COMM_WORLD
  MPI_Gather
  MPI_Allreduce
  hypre_error_handler
  MPI_Op
  MPI_Isend
  create_elt
  MPI_Send
  qsort0
  MPI_User_function
  hypre_ClearTiming
  swap2
  strspn
  double_linked_list
  MPI_Request
  MPI_Testall
  MPI_Status
  hypre_PrintTiming
  MPI_Recv
  hypre_FinalizeTiming
  MPI_Waitall
  MPI_Test
  strcmp
  MPI_Allgatherv
  MPI_Op_create
  hypre_BinarySearch
  MPI_Comm
  hypre_BigQsortbi
  MPI_Op_free
  enter_on_lists
  hypre_ReAlloc
  hypre__global_error
  MPI_COMM_NULL
  MPI_Comm_size
  MPI_COMM_SELF
  MPI_Allgather
  MPI_Get_count
  MPI_Group_incl
  hypre_BigBinarySearch
  strlen
  hypre_BeginTiming
  hypre_LinkList
  MPI_Comm_group
  hypre_global_timing
  hypre_TimingType
  dispose_elt
  hypre_InitializeTiming
  hypre_CAlloc
  memcpy
  hypre_EndTiming
  MPI_Group_free
  MPI_Gatherv
  time_getCPUSeconds
  MPI_Irecv
  MPI_Comm_create
  hypre_Free
  hypre_Rand
  hypre_BigQsort0
  MPI_Bcast
  MPI_Datatype
  hypre_MAlloc
  MPI_Scatterv
  hypre_SeedRand
  swap
  MPI_Group
  MPI_Finalize
  hypre_ListElement
  MPI_Init
  hypre_BigSwapbi
  hypre_BigSwap
  MPI_Iprobe
  strncpy
  remove_point

Entities used from f10: AMG2013/utilities/HYPRE_utilities.h :
  MPI_Allgather
  MPI_Comm_rank
  MPI_Get_count
  MPI_Group_incl
  MPI_Barrier
  MPI_COMM_WORLD
  MPI_Gather
  MPI_Allreduce
  MPI_Op
  MPI_Isend
  MPI_Send
  MPI_Comm_group
  MPI_User_function
  MPI_Request
  MPI_Testall
  MPI_Status
  MPI_Recv
  MPI_Group_free
  MPI_Gatherv
  MPI_Waitall
  MPI_Test
  MPI_Irecv
  MPI_Comm_create
  MPI_Allgatherv
  MPI_Op_create
  MPI_Bcast
  MPI_Datatype
  MPI_Comm
  MPI_Scatterv
  MPI_Group
  MPI_Finalize
  MPI_Init
  MPI_Op_free
  MPI_Iprobe
  MPI_COMM_NULL
  MPI_Comm_size
  MPI_COMM_SELF

Entities used from f12: /include/abc/mpi.h :
  MPI_Allgather
  MPI_Comm_rank
  MPI_Get_count
  MPI_Group_incl
  MPI_Barrier
  MPI_COMM_WORLD
  MPI_Gather
  MPI_Allreduce
  MPI_Op
  MPI_Isend
  MPI_Send
  MPI_Comm_group
  MPI_User_function
  MPI_Request
  MPI_Testall
  MPI_Status
  MPI_Recv
  MPI_Group_free
  MPI_Gatherv
  MPI_Waitall
  MPI_Test
  MPI_Irecv
  MPI_Comm_create
  MPI_Allgatherv
  MPI_Op_create
  MPI_Bcast
  MPI_Datatype
  MPI_Comm
  MPI_Scatterv
  MPI_Group
  MPI_Finalize
  MPI_Init
  MPI_Op_free
  MPI_Iprobe
  MPI_COMM_NULL
  MPI_Comm_size
  MPI_COMM_SELF

Entities used from f13: /include/abc/string.h :
  strcspn
  strcmp
  strlen
  strspn
  memcpy
  strncpy

Entities used from f15: AMG2013/parcsr_mv/HYPRE_parcsr_mv.h :
  HYPRE_ParCSRMatrixDestroy
  HYPRE_ParCSRMatrix
  hypre_ParVector_struct
  HYPRE_ParCSRMatrixGetRow
  HYPRE_ParCSRMatrixRestoreRow
  HYPRE_ParVector
  HYPRE_ParVectorPrintIJ
  hypre_ParCSRMatrix_struct
  hypre_Vector_struct
  HYPRE_ParCSRMatrixMatvec
  HYPRE_ParVectorDestroy
  HYPRE_Vector
  HYPRE_ParCSRMatrixPrintIJ

Entities used from f16: AMG2013/seq_mv/HYPRE_seq_mv.h :
  hypre_Vector_struct
  HYPRE_Vector

Entities used from f17: AMG2013/sstruct_mv/HYPRE_sstruct_mv.h :
  HYPRE_SStructGridSetExtents
  HYPRE_SStructVariable
  HYPRE_IJVectorInitialize
  HYPRE_SStructVectorCreate
  HYPRE_SStructGridSetVariables
  HYPRE_StructGridCreate
  HYPRE_SStructGraphCreate
  HYPRE_IJMatrixInitialize
  HYPRE_IJMatrixAddToValues
  hypre_StructVector_struct
  hypre_SStructGraph_struct
  HYPRE_SStructVector
  hypre_StructStencil_struct
  HYPRE_SStructMatrix
  HYPRE_SStructMatrixSetBoxValues
  HYPRE_IJVectorDestroy
  hypre_SStructMatrix_struct
  HYPRE_SStructStencilSetEntry
  HYPRE_SStructStencilDestroy
  HYPRE_StructStencilSetElement
  HYPRE_SStructGraphDestroy
  HYPRE_StructGridDestroy
  HYPRE_IJMatrixAssemble
  HYPRE_IJVectorAssemble
  HYPRE_StructMatrixSetSymmetric
  hypre_SStructGrid_struct
  HYPRE_StructGrid
  HYPRE_IJMatrixCreate
  HYPRE_SStructGraphAssemble
  HYPRE_SStructGridCreate
  HYPRE_SStructVectorAssemble
  HYPRE_SStructVectorSetObjectType
  HYPRE_IJMatrixSetRowSizes
  HYPRE_SStructGridSetPeriodic
  HYPRE_SStructMatrixGetObject
  HYPRE_SStructMatrixDestroy
  HYPRE_IJMatrix
  HYPRE_StructGridAssemble
  hypre_CommPkg_struct
  HYPRE_SStructGridDestroy
  hypre_SStructStencil_struct
  HYPRE_SStructMatrixSetValues
  HYPRE_SStructMatrixSetObjectType
  HYPRE_IJMatrixSetObjectType
  HYPRE_SStructVectorPrint
  HYPRE_SStructMatrixAssemble
  HYPRE_SStructVectorGather
  HYPRE_IJMatrixGetObject
  HYPRE_SStructGridAssemble
  HYPRE_StructStencilDestroy
  HYPRE_IJVector
  HYPRE_SStructMatrixCreate
  hypre_SStructVector_struct
  HYPRE_StructMatrix
  HYPRE_IJVectorCreate
  HYPRE_SStructMatrixSetSymmetric
  HYPRE_SStructMatrixPrint
  HYPRE_IJMatrixPrint
  HYPRE_SStructGridSetNeighborBox
  HYPRE_SStructGraphAddEntries
  HYPRE_SStructMatrixSetNSSymmetric
  hypre_StructMatrix_struct
  HYPRE_SStructStencilCreate
  HYPRE_IJVectorSetObjectType
  HYPRE_SStructVectorSetBoxValues
  HYPRE_IJMatrixDestroy
  hypre_IJVector_struct
  HYPRE_SStructMatrixAddToBoxValues
  HYPRE_SStructGraph
  HYPRE_StructGridSetPeriodic
  hypre_IJMatrix_struct
  HYPRE_IJMatrixSetValues
  HYPRE_SStructVectorInitialize
  hypre_StructGrid_struct
  hypre_SStructVariable_enum
  HYPRE_SStructGraphSetStencil
  HYPRE_SStructStencil
  HYPRE_SStructVectorGetObject
  HYPRE_StructStencilCreate
  HYPRE_IJMatrixGetValues
  HYPRE_IJVectorGetObject
  HYPRE_SStructMatrixInitialize
  HYPRE_StructStencil
  HYPRE_SStructGrid
  HYPRE_StructGridSetExtents
  HYPRE_SStructVectorDestroy
  HYPRE_SStructGraphSetObjectType

Entities used from f18: AMG2013/struct_mv/HYPRE_struct_mv.h :
  HYPRE_StructStencilSetElement
  HYPRE_StructGridCreate
  HYPRE_StructGridDestroy
  HYPRE_StructMatrixSetSymmetric
  HYPRE_StructGridSetPeriodic
  HYPRE_StructGrid
  hypre_StructVector_struct
  hypre_StructGrid_struct
  HYPRE_StructStencilDestroy
  hypre_StructStencil_struct
  HYPRE_StructStencilCreate
  HYPRE_StructMatrix
  HYPRE_StructStencil
  HYPRE_StructGridSetExtents
  HYPRE_StructGridAssemble
  hypre_StructMatrix_struct
  hypre_CommPkg_struct

Entities used from f19: AMG2013/IJ_mv/HYPRE_IJ_mv.h :
  HYPRE_IJMatrixDestroy
  hypre_IJVector_struct
  HYPRE_IJVectorInitialize
  HYPRE_IJMatrixSetObjectType
  HYPRE_IJMatrixAssemble
  HYPRE_IJVectorAssemble
  HYPRE_IJMatrixInitialize
  HYPRE_IJMatrixAddToValues
  hypre_IJMatrix_struct
  HYPRE_IJMatrixCreate
  HYPRE_IJMatrixSetValues
  HYPRE_IJMatrixGetObject
  HYPRE_IJVector
  HYPRE_IJMatrixSetRowSizes
  HYPRE_IJMatrixGetValues
  HYPRE_IJVectorCreate
  HYPRE_IJVectorGetObject
  HYPRE_IJMatrixPrint
  HYPRE_IJVectorDestroy
  HYPRE_IJMatrix
  HYPRE_IJVectorSetObjectType

Entities used from f20: AMG2013/parcsr_ls/HYPRE_parcsr_ls.h :
  HYPRE_BoomerAMGSetGridRelaxType
  HYPRE_BoomerAMGSetPMaxElmts
  hypre_Solver_struct
  HYPRE_BoomerAMGSolve
  HYPRE_BoomerAMGSetRelaxOrder
  GenerateVarDifConv
  HYPRE_ParCSRDiagScaleSetup
  HYPRE_BoomerAMGSetup
  GenerateLaplacian
  HYPRE_BoomerAMGSetGridRelaxPoints
  HYPRE_BoomerAMGSetTruncFactor
  HYPRE_BoomerAMGSetMaxIter
  HYPRE_BoomerAMGCreate
  HYPRE_BoomerAMGSetMaxRowSum
  HYPRE_ParCSRDiagScale
  HYPRE_ParCSRPCGDestroy
  HYPRE_BoomerAMGSetPrintLevel
  HYPRE_ParCSRPCGCreate
  HYPRE_BoomerAMGSetNumGridSweeps
  HYPRE_BoomerAMGSetAggNumLevels
  HYPRE_BoomerAMGSetTol
  HYPRE_ParCSRGMRESDestroy
  HYPRE_BoomerAMGSetRelaxType
  HYPRE_BoomerAMGSetInterpType
  GenerateLaplacian27pt
  HYPRE_Solver
  HYPRE_BoomerAMGSetCoarsenType
  HYPRE_BoomerAMGSetCycleRelaxType
  HYPRE_BoomerAMGSetRelaxWeight
  HYPRE_BoomerAMGSetNumFunctions
  HYPRE_ParCSRPCGSetup
  HYPRE_ParCSRGMRESCreate
  HYPRE_ParCSRPCGSolve
  HYPRE_BoomerAMGDestroy
  HYPRE_BoomerAMGSetPrintFileName
  HYPRE_BoomerAMGSetStrongThreshold
  HYPRE_BoomerAMGSetCycleNumSweeps

Entities used from f21: AMG2013/krylov/krylov.h :
  hypre_GMRESSetPrecond
  HYPRE_GMRESSetup
  HYPRE_GMRESSetTol
  hypre_PCGSetup
  HYPRE_PtrToSolverFcn
  hypre_PCGData
  hypre_GMRESSolve
  hypre_GMRESSetKDim
  hypre_GMRESData
  hypre_PCGFunctionsCreate
  hypre_GMRESDestroy
  hypre_PCGSetRelChange
  hypre_PCGSetPrecond
  hypre_GMRESFunctions
  hypre_GMRESSetup
  hypre_PCGFunctions
  HYPRE_PCGSetTwoNorm
  HYPRE_PCGSetup
  HYPRE_GMRESSetKDim
  hypre_Matrix_struct
  HYPRE_PCGSolve
  hypre_GMRESSetMaxIter
  HYPRE_PCGSetPrecond
  hypre_PCGSolve
  hypre_PCGDestroy
  hypre_GMRESSetPrintLevel
  HYPRE_GMRESGetFinalRelativeResidualNorm
  HYPRE_PCGSetTol
  hypre_PCGSetPrintLevel
  HYPRE_Matrix
  HYPRE_GMRESSetMaxIter
  hypre_PCGCreate
  HYPRE_PCGSetMaxIter
  HYPRE_GMRESGetNumIterations
  hypre_GMRESGetFinalRelativeResidualNorm
  hypre_PCGSetTwoNorm
  HYPRE_PCGGetFinalRelativeResidualNorm
  hypre_GMRESSetLogging
  hypre_PCGGetFinalRelativeResidualNorm
  hypre_PCGGetNumIterations
  HYPRE_PCGSetPrintLevel
  hypre_GMRESSetTol
  HYPRE_GMRESSetPrintLevel
  HYPRE_PCGSetRelChange
  HYPRE_GMRESSolve
  HYPRE_GMRESSetPrecond
  HYPRE_GMRESSetLogging
  hypre_PCGSetTol
  HYPRE_PCGGetNumIterations
  hypre_GMRESGetNumIterations
  hypre_PCGSetMaxIter
  hypre_GMRESCreate
  hypre_GMRESFunctionsCreate

Entities used from f22: AMG2013/sstruct_mv/sstruct_mv.h :
  hypre_SStructStencil
  hypre_AuxParCSRMatrix
  hypre_BoxArray
  hypre_StructStencilDestroy
  hypre_ParCSRMatrixRestoreRow
  hypre_CommInfo
  hypre_StructGrid
  hypre_SStructGridRef
  hypre_BoxExpand
  hypre_IJAssumedPart
  hypre_ParVectorAxpy
  hypre_PrintCCVDBoxArrayData
  hypre_SStructVectorParConvert
  hypre_Vector
  hypre_SeqVectorSetRandomValues
  hypre_SStructPMatvecDestroy
  hypre_BoxMapDestroy
  hypre_ExchangeLocalData
  hypre_SStructPMatrixSetSymmetric
  hypre_BoxArrayDestroy
  hypre_SubtractBoxArraysExceptBoxes
  hypre_SStructPVectorPrint
  hypre_SStructMatvecSetup
  hypre_StructStencilRef
  hypre_GeneratePartitioning
  hypre_IntersectBoxes
  hypre_SStructNBorBoxToBox
  hypre_SeqVectorCreate
  hypre_AuxParCSRMatrixCreate
  hypre_AuxParCSRMatrixInitialize
  hypre_GatherAllBoxes
  hypre_BoxMapEntryGetExtents
  hypre_StructMatrix
  hypre_StructVectorSetBoxValues
  hypre_SStructUMatrixSetValues
  hypre_StructMatrixDestroy
  hypre_SStructMatvecCreate
  hypre_StructMatrixPrint
  hypre_SStructVector
  hypre_BoxMapEntry
  hypre_RankLinkCreate
  hypre_ParVectorSetPartitioningOwner
  hypre_BoxNeighborsDestroy
  hypre_CommInfoCreate
  hypre_PrintBoxArrayData
  hypre_SStructNeighbor
  hypre_SStructVectorRestore
  hypre_ParVectorScale
  hypre_SStructVectorParRestore
  hypre_SeqVectorDestroy
  hypre_BoxArrayArrayDestroy
  hypre_BoxMapAddEntry
  hypre_BoxArrayArrayDuplicate
  hypre_BoxBoundaryNT
  hypre_ParCSRMatrixCopy
  hypre_BoxMapAssemble
  hypre_SStructPMatvecCreate
  hypre_StructVectorAssemble
  hypre_ParCSRMatrixDestroyAssumedPartition
  hypre_ParCSRMatrixGetRow
  hypre_ParCSRMatrixDestroy
  hypre_ParCSRMatrixCopy_C
  HYPRE_SStructStencilCreate
  hypre_BoxGetStrideVolume
  hypre_SStructPGridSetExtents
  hypre_StructScale
  hypre_AuxParVectorInitialize
  hypre_SStructPVectorInitializeShell
  hypre_SStructStencilRef
  hypre_SStructPVectorDestroy
  hypre_ParCSRMatrixZero_F
  hypre_IJVectorCreatePar
  hypre_SStructMatrixSplitEntries
  hypre_StructVectorPrint
  hypre_AuxParVectorCreate
  hypre_SStructUVar
  hypre_BoxDuplicate
  hypre_StructMatrixCreate
  hypre_StructVectorRef
  hypre_CommPkg
  hypre_ParCSRMatrixSetNumNonzeros
  hypre_BoxBoundaryDNT
  hypre_ComputePkgCreate
  hypre_StructMatvecCC1
  hypre_StructGridSetPeriodic
  hypre_StructVectorClearBoundGhostValues
  hypre_CreateCommInfoFromStencil
  hypre_ParVectorToVectorAll
  hypre_SStructVectorInitializeShell
  hypre_CSRMatrixMatvecT
  hypre_ParVectorDestroyAssumedPartition
  HYPRE_SStructVectorCreate
  hypre_StructStencil
  HYPRE_StructGridCreate
  hypre_SStructUEntry
  hypre_ParCSRMatrixToCSRMatrixAll
  hypre_SStructBoxToNBorBox
  hypre_CSRMatrixTranspose
  hypre_StructStencilCreate
  hypre_BoxArrayArrayCreate
  hypre_BoxMap
  hypre_IJVectorAssemblePar
  hypre_CreateComputeInfo
  hypre_ParVectorInnerProd
  hypre_SStructPVectorAssemble
  HYPRE_StructStencilSetElement
  hypre_IJVectorDestroyPar
  hypre_MergeDiagAndOffd
  hypre_ParVectorSetRandomValues
  hypre_StructGridRef
  hypre_SStructGrid
  hypre_CommEntryType
  hypre_ParCSRCommHandleDestroy
  hypre_ParCSRMatrixMatvec
  hypre_SStructPVectorGather
  hypre_StructMatrixInitializeShell
  hypre_ParCSRMatrixSetColStartsOwner
  hypre_ParVectorSetConstantValues
  hypre_IJMatrixCreateParCSR
  hypre_Index
  hypre_IJMatrixAssembleParCSR
  hypre_StructVectorCreate
  hypre_CommTypeSetEntries
  hypre_BoxMapIncSize
  hypre_ParMatmul_FC
  hypre_BoxMapSetNumGhost
  hypre_SStructUCVar
  hypre_ParCSRMatrixSetRowStartsOwner
  hypre_SStructVariable
  hypre_ParVectorPrintIJ
  hypre_SStructPMatrixAssemble
  hypre_SStructPMatrixInitialize
  hypre_ComputeInfoDestroy
  hypre_BoxMapFindBoxProcEntry
  hypre_SubtractBoxArrays
  hypre_IJMatrixAssembleOffProcValsParCSR
  hypre_SStructMapInfo
  hypre_SStructUMatrixSetBoxValues
  hypre_ParVectorCreate
  hypre_StructMatrixSetBoxValues
  hypre_IndexRef
  hypre_ParCSRMatrixPrintIJ
  hypre_SeqVectorCopy
  hypre_SStructPVectorSetBoxValues
  hypre_AppendBox
  hypre_StructMatvecDestroy
  hypre_SStructMapEntryGetBox
  hypre_IJMatrixDestroyParCSR
  hypre_SeqVectorAxpy
  hypre_SStructMatvec
  hypre_SStructGridAssembleNBorMaps
  hypre_StructMatvecSetup
  HYPRE_StructStencilCreate
  hypre_ParVector
  hypre_SStructMapInfoType
  hypre_FinalizeCommunication
  hypre_ParCSRMatrixMatvecT
  hypre_CommType
  hypre_StructMatrixSetNumGhost
  hypre_CSRMatrixCopy
  hypre_SStructGridAssembleMaps
  hypre_StructStencilSymmetrize
  hypre_IJMatrixSetValuesParCSR
  hypre_StructMatrixInitializeData
  hypre_ParCSRCommHandleCreate
  hypre_SStructGridFindMapEntry
  hypre_BigCSRMatrixDestroy
  hypre_BigCSRMatrixCreate
  hypre_SStructMatvecDestroy
  hypre_ParMatmul_RowSizes_Marked
  hypre_SStructPGrid
  hypre_SeqVectorScale
  hypre_StructGridSetBoxes
  hypre_IJMatrixGetValuesParCSR
  hypre_ParCSRMatrixExtractBigExt
  HYPRE_ParCSRMatrixPrintIJ
  hypre_CSRMatrixCreate
  hypre_IJVector
  hypre_MatvecCommPkgCreate_core
  hypre_SStructMapEntryGetProcess
  hypre_MatvecCommPkgDestroy
  hypre_RankLinkDestroy
  hypre_ParCSRCommHandle
  hypre_BoxArraySubtractAdjacentBoxArrayD
  hypre_BoxNeighbors
  hypre_ParCSRMatrix
  hypre_SStructMapEntryGetGlobalGhrank
  hypre_CSRMatrixInitialize
  hypre_ParCSRMatrixSetDNumNonzeros
  hypre_CSRMatrixMatvec
  hypre_StructMatvecCreate
  hypre_SStructMapEntryGetGhstrides
  hypre_SStructPVectorCreate
  hypre_CommTypeSetEntry
  hypre_SStructPMatrixSetBoxValues
  hypre_StructMatrixAssemble
  hypre_AuxParVectorDestroy
  HYPRE_SStructMatrixCreate
  hypre_InitializeCommunication
  hypre_StructMatvecCompute
  hypre_SStructMapEntryGetGlobalCSRank
  hypre_SStructUMatrixInitialize
  hypre_SStructMatvecCompute
  hypre_BoxArrayArray
  hypre_StructMatrixInitialize
  hypre_StructMatvecCC2
  hypre_SStructGridBoxProcFindMapEntry
  hypre_SStructPGridAssemble
  hypre_RankLink
  hypre_SeqVectorSetConstantValues
  hypre_ParVectorCopy
  hypre_ParVectorInitialize
  hypre_ParCSRMatrixExtractConvBExt
  hypre_IJMatrix
  hypre_CreateCommInfoFromNumGhost
  hypre_IJVectorInitializePar
  hypre_Box
  hypre_SStructMapEntryGetStrides
  hypre_SStructVectorConvert
  hypre_SStructMapEntryGetCSRstrides
  hypre_CommPkgCreate
  hypre_StructVectorInitializeShell
  hypre_CSRMatrixUnion
  hypre_StructMatrixSetValues
  hypre_SeqVectorInitialize
  hypre_AppendBoxArray
  hypre_SStructPMatvecSetup
  hypre_FindProc
  hypre_BoxGetSize
  hypre_StructGridDestroy
  hypre_IJVectorAssembleOffProcValsPar
  hypre_CSRMatrixDestroy
  hypre_SStructUMatrixAssemble
  hypre_StructMatrixRef
  hypre_BoxBoundaryG
  hypre_SStructPGridSetPNeighbor
  HYPRE_SStructGraphCreate
  hypre_StructStencilElementRank
  hypre_SStructPMatvecCompute
  hypre_BoxMapFindEntry
  hypre_CommInfoDestroy
  hypre_SStructPVector
  hypre_BoxMapCreate
  hypre_SeqVectorInnerProd
  hypre_IJMatrixAddToValuesParCSR
  hypre_CommHandle
  hypre_ComputePkgDestroy
  hypre_ParMatmul_RowSizes
  hypre_SStructVariableGetOffset
  hypre_SStructPGridDestroy
  hypre_StructGridCreate
  hypre_ParMatmul
  hypre_BoxArraySetSize
  hypre_ParMatScaleDiagInv_F
  HYPRE_SStructGridCreate
  hypre_ParCSRMatrixUnion
  hypre_SStructPMatrixSetValues
  hypre_StructVectorInitializeData
  hypre_AuxParVector
  hypre_ParVectorDestroy
  hypre_AuxParCSRMatrixDestroy
  hypre_SStructGraphFindUVEntry
  hypre_SStructPGridCreate
  hypre_StructGridAssemble
  hypre_SStructPMatrixPrint
  hypre_StructVector
  hypre_SStructPMatrixCreate
  hypre_SStructMapEntryGetGlobalRank
  hypre_ParMatMinus_F
  hypre_SStructMatrix
  hypre_BoxArrayDuplicate
  hypre_IJMatrixSetRowSizesParCSR
  hypre_CSRMatrix
  hypre_CommPkgDestroy
  hypre_StructMatvecCC0
  hypre_IJMatrixInitializeParCSR
  hypre_SStructNMapInfo
  hypre_StructGridPrint
  hypre_BoxMapIntersect
  hypre_SStructPMatrix
  hypre_ComputeInfo
  hypre_SStructPMatrixDestroy
  hypre_BoxGetStrideSize
  hypre_BoxNeighborsCreate
  hypre_SStructGraph
  hypre_BoxArrayCreate
  hypre_BoxMapEntryGetInfo
  hypre_SStructPGridSetVariables
  hypre_StructGridSetExtents
  hypre_StructVectorDestroy
  hypre_MatvecCommPkgCreate
  hypre_ParCSRMatrixCreate
  hypre_FinalizeIndtComputations
  hypre_ComputePkg
  hypre_BoxSetExtents
  hypre_SStructGraphRef
  hypre_CSRMatrixSetRownnz
  hypre_SubtractBoxes
  hypre_StructMatrixExtractPointerByIndex
  hypre_BoxDestroy
  hypre_ComputeInfoCreate
  hypre_PrintCCBoxArrayData
  hypre_SStructUVEntry
  hypre_BoxCreate
  hypre_ComputeBoxnums
  hypre_BigCSRMatrix
  hypre_ParCSRMatrixInitialize
  hypre_BoxNeighborsAssemble
  hypre_InitializeIndtComputations
  hypre_ParCSRCommPkg

Entities used from f23: AMG2013/struct_mv/struct_mv.h :
  hypre_BoxArray
  hypre_StructStencilDestroy
  hypre_StructStencilSymmetrize
  hypre_StructMatrixInitializeData
  hypre_CommInfo
  hypre_StructGrid
  hypre_BoxExpand
  hypre_PrintCCVDBoxArrayData
  hypre_ExchangeLocalData
  hypre_StructGridSetBoxes
  hypre_BoxArrayDestroy
  hypre_SubtractBoxArraysExceptBoxes
  hypre_StructStencilRef
  hypre_IntersectBoxes
  hypre_GatherAllBoxes
  hypre_StructMatrix
  hypre_RankLinkDestroy
  hypre_BoxArraySubtractAdjacentBoxArrayD
  hypre_StructVectorSetBoxValues
  hypre_StructMatrixDestroy
  hypre_BoxNeighbors
  hypre_StructMatrixPrint
  hypre_StructMatvecCreate
  hypre_RankLinkCreate
  hypre_CommTypeSetEntry
  hypre_BoxNeighborsDestroy
  hypre_CommInfoCreate
  hypre_StructMatrixAssemble
  hypre_PrintBoxArrayData
  hypre_InitializeCommunication
  hypre_StructMatvecCompute
  hypre_BoxArrayArrayDestroy
  hypre_BoxArrayArrayDuplicate
  hypre_BoxArrayArray
  hypre_BoxBoundaryNT
  hypre_StructMatrixInitialize
  hypre_StructMatvecCC2
  hypre_StructVectorAssemble
  hypre_RankLink
  hypre_BoxGetStrideVolume
  hypre_StructScale
  hypre_CreateCommInfoFromNumGhost
  hypre_Box
  hypre_StructVectorPrint
  hypre_BoxDuplicate
  hypre_StructMatrixCreate
  hypre_StructVectorRef
  hypre_CommPkg
  hypre_BoxBoundaryDNT
  hypre_ComputePkgCreate
  hypre_CommPkgCreate
  hypre_StructMatvecCC1
  hypre_StructVectorInitializeShell
  hypre_StructMatrixSetValues
  hypre_StructGridSetPeriodic
  hypre_AppendBoxArray
  hypre_StructVectorClearBoundGhostValues
  hypre_BoxGetSize
  hypre_CreateCommInfoFromStencil
  hypre_StructGridDestroy
  hypre_StructStencil
  HYPRE_StructGridCreate
  hypre_StructMatrixRef
  hypre_BoxBoundaryG
  hypre_StructStencilElementRank
  hypre_StructStencilCreate
  hypre_BoxArrayArrayCreate
  hypre_CommInfoDestroy
  hypre_CreateComputeInfo
  HYPRE_StructStencilSetElement
  hypre_StructGridRef
  hypre_CommEntryType
  hypre_CommHandle
  hypre_ComputePkgDestroy
  hypre_StructMatrixInitializeShell
  hypre_StructGridCreate
  hypre_BoxArraySetSize
  hypre_Index
  hypre_StructVectorCreate
  hypre_CommTypeSetEntries
  hypre_StructVectorInitializeData
  hypre_StructGridAssemble
  hypre_StructVector
  hypre_BoxArrayDuplicate
  hypre_ComputeInfoDestroy
  hypre_CommPkgDestroy
  hypre_StructMatvecCC0
  hypre_SubtractBoxArrays
  hypre_StructGridPrint
  hypre_ComputeInfo
  hypre_StructMatrixSetBoxValues
  hypre_IndexRef
  hypre_BoxGetStrideSize
  hypre_BoxNeighborsCreate
  hypre_BoxArrayCreate
  hypre_AppendBox
  hypre_StructMatvecDestroy
  hypre_StructGridSetExtents
  hypre_StructVectorDestroy
  hypre_FinalizeIndtComputations
  hypre_ComputePkg
  hypre_BoxSetExtents
  hypre_SubtractBoxes
  hypre_StructMatvecSetup
  HYPRE_StructStencilCreate
  hypre_StructMatrixExtractPointerByIndex
  hypre_BoxDestroy
  hypre_ComputeInfoCreate
  hypre_PrintCCBoxArrayData
  hypre_FinalizeCommunication
  hypre_BoxCreate
  hypre_ComputeBoxnums
  hypre_CommType
  hypre_BoxNeighborsAssemble
  hypre_InitializeIndtComputations
  hypre_StructMatrixSetNumGhost

Entities used from f25: AMG2013/IJ_mv/IJ_mv.h :
  hypre_AuxParCSRMatrix
  hypre_ParCSRMatrixRestoreRow
  hypre_IJMatrixSetValuesParCSR
  hypre_ParCSRCommHandleCreate
  hypre_BigCSRMatrixDestroy
  hypre_IJAssumedPart
  hypre_ParVectorAxpy
  hypre_Vector
  hypre_BigCSRMatrixCreate
  hypre_SeqVectorSetRandomValues
  hypre_ParMatmul_RowSizes_Marked
  hypre_SeqVectorScale
  hypre_IJMatrixGetValuesParCSR
  hypre_ParCSRMatrixExtractBigExt
  HYPRE_ParCSRMatrixPrintIJ
  hypre_CSRMatrixCreate
  hypre_IJVector
  hypre_GeneratePartitioning
  hypre_MatvecCommPkgCreate_core
  hypre_SeqVectorCreate
  hypre_MatvecCommPkgDestroy
  hypre_AuxParCSRMatrixCreate
  hypre_AuxParCSRMatrixInitialize
  hypre_ParCSRCommHandle
  hypre_ParCSRMatrix
  hypre_CSRMatrixInitialize
  hypre_ParCSRMatrixSetDNumNonzeros
  hypre_CSRMatrixMatvec
  hypre_ParVectorSetPartitioningOwner
  hypre_AuxParVectorDestroy
  hypre_ParVectorScale
  hypre_SeqVectorDestroy
  hypre_ParCSRMatrixCopy
  hypre_ParCSRMatrixDestroyAssumedPartition
  hypre_ParCSRMatrixGetRow
  hypre_ParCSRMatrixDestroy
  hypre_ParCSRMatrixCopy_C
  hypre_SeqVectorSetConstantValues
  hypre_ParVectorCopy
  hypre_ParVectorInitialize
  hypre_ParCSRMatrixExtractConvBExt
  hypre_AuxParVectorInitialize
  hypre_IJMatrix
  hypre_ParCSRMatrixZero_F
  hypre_IJVectorInitializePar
  hypre_IJVectorCreatePar
  hypre_AuxParVectorCreate
  hypre_ParCSRMatrixSetNumNonzeros
  hypre_CSRMatrixUnion
  hypre_SeqVectorInitialize
  hypre_FindProc
  hypre_ParVectorToVectorAll
  hypre_IJVectorAssembleOffProcValsPar
  hypre_CSRMatrixDestroy
  hypre_CSRMatrixMatvecT
  hypre_ParVectorDestroyAssumedPartition
  hypre_ParCSRMatrixToCSRMatrixAll
  hypre_CSRMatrixTranspose
  hypre_IJVectorAssemblePar
  hypre_SeqVectorInnerProd
  hypre_ParVectorInnerProd
  hypre_IJVectorDestroyPar
  hypre_MergeDiagAndOffd
  hypre_ParVectorSetRandomValues
  hypre_IJMatrixAddToValuesParCSR
  hypre_ParCSRCommHandleDestroy
  hypre_ParMatmul_RowSizes
  hypre_ParCSRMatrixMatvec
  hypre_ParCSRMatrixSetColStartsOwner
  hypre_ParMatmul
  hypre_ParVectorSetConstantValues
  hypre_IJMatrixCreateParCSR
  hypre_ParMatScaleDiagInv_F
  hypre_ParCSRMatrixUnion
  hypre_IJMatrixAssembleParCSR
  hypre_AuxParVector
  hypre_ParVectorDestroy
  hypre_AuxParCSRMatrixDestroy
  hypre_ParMatmul_FC
  hypre_ParMatMinus_F
  hypre_ParCSRMatrixSetRowStartsOwner
  hypre_ParVectorPrintIJ
  hypre_IJMatrixSetRowSizesParCSR
  hypre_CSRMatrix
  hypre_IJMatrixInitializeParCSR
  hypre_IJMatrixAssembleOffProcValsParCSR
  hypre_ParVectorCreate
  hypre_ParCSRMatrixPrintIJ
  hypre_SeqVectorCopy
  hypre_MatvecCommPkgCreate
  hypre_IJMatrixDestroyParCSR
  hypre_SeqVectorAxpy
  hypre_ParCSRMatrixCreate
  hypre_CSRMatrixSetRownnz
  hypre_ParVector
  hypre_ParCSRMatrixMatvecT
  hypre_BigCSRMatrix
  hypre_ParCSRMatrixInitialize
  hypre_CSRMatrixCopy
  hypre_ParCSRCommPkg

Entities used from f26: AMG2013/seq_mv/seq_mv.h :
  hypre_CSRMatrixInitialize
  hypre_CSRMatrixCreate
  hypre_SeqVectorCopy
  hypre_CSRMatrixDestroy
  hypre_CSRMatrixMatvecT
  hypre_CSRMatrixMatvec
  hypre_GeneratePartitioning
  hypre_CSRMatrix
  hypre_SeqVectorAxpy
  hypre_BigCSRMatrixDestroy
  hypre_SeqVectorCreate
  hypre_CSRMatrixTranspose
  hypre_Vector
  hypre_BigCSRMatrixCreate
  hypre_CSRMatrixSetRownnz
  hypre_SeqVectorSetRandomValues
  hypre_SeqVectorDestroy
  hypre_SeqVectorScale
  hypre_BigCSRMatrix
  hypre_SeqVectorInnerProd
  hypre_CSRMatrixUnion
  hypre_SeqVectorInitialize
  hypre_CSRMatrixCopy
  hypre_SeqVectorSetConstantValues

Entities used from f27: AMG2013/parcsr_mv/parcsr_mv.h :
  hypre_ParVectorToVectorAll
  hypre_ParCSRMatrixRestoreRow
  hypre_ParVectorDestroyAssumedPartition
  hypre_ParCSRCommHandleCreate
  hypre_ParCSRMatrixToCSRMatrixAll
  hypre_IJAssumedPart
  hypre_ParVectorAxpy
  hypre_ParMatmul_RowSizes_Marked
  hypre_ParVectorInnerProd
  hypre_ParCSRMatrixExtractBigExt
  HYPRE_ParCSRMatrixPrintIJ
  hypre_MergeDiagAndOffd
  hypre_ParVectorSetRandomValues
  hypre_ParCSRCommHandleDestroy
  hypre_ParMatmul_RowSizes
  hypre_ParCSRMatrixMatvec
  hypre_MatvecCommPkgCreate_core
  hypre_ParCSRMatrixSetColStartsOwner
  hypre_MatvecCommPkgDestroy
  hypre_ParMatmul
  hypre_ParVectorSetConstantValues
  hypre_ParMatScaleDiagInv_F
  hypre_ParCSRMatrixUnion
  hypre_ParCSRCommHandle
  hypre_ParVectorDestroy
  hypre_ParMatmul_FC
  hypre_ParCSRMatrix
  hypre_ParMatMinus_F
  hypre_ParCSRMatrixSetRowStartsOwner
  hypre_ParCSRMatrixSetDNumNonzeros
  hypre_ParVectorPrintIJ
  hypre_ParVectorSetPartitioningOwner
  hypre_ParVectorScale
  hypre_ParVectorCreate
  hypre_ParCSRMatrixCopy
  hypre_ParCSRMatrixDestroyAssumedPartition
  hypre_ParCSRMatrixGetRow
  hypre_ParCSRMatrixDestroy
  hypre_ParCSRMatrixCopy_C
  hypre_ParCSRMatrixPrintIJ
  hypre_ParVectorCopy
  hypre_ParVectorInitialize
  hypre_ParCSRMatrixExtractConvBExt
  hypre_MatvecCommPkgCreate
  hypre_ParCSRMatrixZero_F
  hypre_ParCSRMatrixCreate
  hypre_ParVector
  hypre_ParCSRMatrixSetNumNonzeros
  hypre_ParCSRMatrixMatvecT
  hypre_ParCSRMatrixInitialize
  hypre_ParCSRCommPkg

Entities used from f28: AMG2013/IJ_mv/HYPRE_IJMatrix.c :
  HYPRE_IJMatrixDestroy
  HYPRE_IJMatrixSetRowSizes
  HYPRE_IJMatrixGetValues
  HYPRE_IJMatrixSetObjectType
  HYPRE_IJMatrixAssemble
  HYPRE_IJMatrixPrint
  HYPRE_IJMatrixInitialize
  HYPRE_IJMatrixAddToValues
  HYPRE_IJMatrixCreate
  HYPRE_IJMatrixSetValues
  HYPRE_IJMatrixGetObject

Entities used from f32: AMG2013/IJ_mv/HYPRE_IJVector.c :
  HYPRE_IJVectorInitialize
  HYPRE_IJVectorCreate
  HYPRE_IJVectorGetObject
  HYPRE_IJVectorAssemble
  HYPRE_IJVectorDestroy
  HYPRE_IJVectorSetObjectType

Entities used from f33: AMG2013/IJ_mv/IJMatrix_parcsr.c :
  hypre_IJMatrixAssembleParCSR
  hypre_FindProc
  hypre_IJMatrixSetValuesParCSR
  hypre_IJMatrixAssembleOffProcValsParCSR
  hypre_IJMatrixAddToValuesParCSR
  hypre_IJMatrixSetRowSizesParCSR
  hypre_IJMatrixDestroyParCSR
  hypre_IJMatrixInitializeParCSR
  hypre_IJMatrixCreateParCSR
  hypre_IJMatrixGetValuesParCSR

Entities used from f35: AMG2013/IJ_mv/IJVector_parcsr.c :
  hypre_IJVectorDestroyPar
  hypre_IJVectorAssembleOffProcValsPar
  hypre_IJVectorAssemblePar
  hypre_IJVectorInitializePar
  hypre_IJVectorCreatePar

Entities used from f36: AMG2013/IJ_mv/aux_par_vector.c :
  hypre_AuxParVectorCreate
  hypre_AuxParVectorInitialize
  hypre_AuxParVectorDestroy

Entities used from f38: AMG2013/IJ_mv/aux_parcsr_matrix.c :
  hypre_AuxParCSRMatrixDestroy
  hypre_AuxParCSRMatrixCreate
  hypre_AuxParCSRMatrixInitialize

Entities used from f40: AMG2013/krylov/HYPRE_gmres.c :
  HYPRE_GMRESSetMaxIter
  HYPRE_GMRESSetLogging
  HYPRE_GMRESSetup
  HYPRE_GMRESSetTol
  HYPRE_GMRESGetNumIterations
  HYPRE_GMRESGetFinalRelativeResidualNorm
  HYPRE_GMRESSetPrintLevel
  HYPRE_GMRESSetKDim
  HYPRE_GMRESSolve
  HYPRE_GMRESSetPrecond

Entities used from f41: AMG2013/krylov/HYPRE_pcg.c :
  HYPRE_PCGSolve
  HYPRE_PCGGetNumIterations
  HYPRE_PCGSetMaxIter
  HYPRE_PCGSetPrecond
  HYPRE_PCGSetPrintLevel
  HYPRE_PCGSetTwoNorm
  HYPRE_PCGSetup
  HYPRE_PCGSetRelChange
  HYPRE_PCGGetFinalRelativeResidualNorm
  HYPRE_PCGSetTol

Entities used from f42: AMG2013/krylov/gmres.c :
  hypre_GMRESSetPrecond
  hypre_GMRESSetup
  hypre_GMRESSetTol
  hypre_GMRESSetMaxIter
  hypre_GMRESSolve
  hypre_GMRESGetNumIterations
  hypre_GMRESSetKDim
  hypre_GMRESSetPrintLevel
  hypre_GMRESGetFinalRelativeResidualNorm
  hypre_GMRESCreate
  hypre_GMRESDestroy
  hypre_GMRESSetLogging
  hypre_GMRESFunctionsCreate

Entities used from f43: AMG2013/krylov/pcg.c :
  hypre_PCGSetRelChange
  hypre_PCGSetPrecond
  hypre_PCGSetup
  hypre_PCGCreate
  hypre_PCGSetTol
  hypre_PCGSolve
  hypre_PCGDestroy
  hypre_PCGSetTwoNorm
  hypre_PCGSetMaxIter
  hypre_PCGFunctionsCreate
  hypre_PCGGetFinalRelativeResidualNorm
  hypre_PCGGetNumIterations
  hypre_PCGSetPrintLevel

Entities used from f44: AMG2013/parcsr_ls/HYPRE_parcsr_amg.c :
  hypre_ParCSRRelax_L1
  hypre_BoomerAMGWriteSolverParams
  hypre_BoomerAMGSetNumIterations
  hypre_ParCSRMatrix_dof_func_offd
  hypre_ParKrylovCommInfo
  HYPRE_BoomerAMGSolve
  hypre_BoomerAMGBuildInterp
  hypre_ParKrylovCreateVector
  big_insert_new_nodes
  hypre_BoomerAMGSetNumGridSweeps
  hypre_ParCSRComputeL1NormsThreads
  hypre_BoomerAMGSetInterpType
  hypre_BoomerAMGSetPrintLevel
  gfun
  hypre_BoomerAMGJacobiInterp
  HYPRE_BoomerAMGCreate
  efun
  hypre_Bisection
  hypre_BoomerAMGCreate2ndS
  hypre_ParCSRRelax_L1_Jacobi
  hypre_BoomerAMGSetup
  hypre_BoomerAMGCreateSabs
  hypre_BoomerAMGCorrectCFMarker2
  hypre_ParCSRRelax_CG
  hypre_BoomerAMGSetPostInterpType
  hypre_BoomerAMGCoarsenRuge
  hypre_BoomerAMGSetRelaxOrder
  hypre_BoomerAMGSetNumSweeps
  HYPRE_BoomerAMGSetCoarsenType
  hypre_BoomerAMGSetNumSamples
  HYPRE_BoomerAMGSetCycleRelaxType
  hypre_SeqAMGData
  hypre_BoomerAMGSetNumPaths
  hypre_BoomerAMGSetMaxLevels
  hypre_ParCSRRelax_Cheby
  hypre_BoomerAMGRelaxIF
  hypre_BoomerAMGCreateScalarCFS
  HYPRE_BoomerAMGDestroy
  hypre_BoomerAMGSetCycleNumSweeps
  hypre_BoomerAMGSetGSMG
  hypre_BoomerAMGSetCoarsenType
  hypre_ParCSRComputeL1Norms
  hypre_BoomerAMGSetPMax1
  hypre_BoomerAMGBuildStdInterp
  hypre_seqAMGCycle
  dfun
  hypre_ParKrylovIdentitySetup
  hypre_ParKrylovScaleVector
  HYPRE_BoomerAMGSetup
  hypre_BoomerAMGDestroy
  HYPRE_BoomerAMGSetGridRelaxPoints
  hypre_BoomerAMGSetAggInterpType
  HYPRE_BoomerAMGSetTruncFactor
  HYPRE_BoomerAMGSetMaxIter
  gselim
  hypre_BoomerAMGSetRelaxWt
  new_offd_nodes
  hypre_BoomerAMGInterpTruncation
  hypre_BoomerAMGBuildFF1Interp
  hypre_BoomerAMGRelax_FCFJacobi
  hypre_BoomerAMGSetSCommPkgSwitch
  hypre_ParKrylovCreateVectorArray
  hypre_BoomerAMGCreateNodalA
  afun
  hypre_BoomerAMGSetNodal
  hypre_BoomerAMGCoarseParms
  hypre_BoomerAMGSetSmoothNumLevels
  hypre_ParKrylovInnerProd
  hypre_BoomerAMGSetSmoothNumSweeps
  HYPRE_BoomerAMGSetAggNumLevels
  hypre_BoomerAMGSetRestriction
  HYPRE_BoomerAMGSetRelaxType
  hypre_BoomerAMGCoarsenPMIS
  hypre_BoomerAMGIndepSet
  hypre_BoomerAMGCoarsen
  hypre_BoomerAMGCGRelaxWt
  hypre_BoomerAMGSetAggTruncFactor
  hypre_BoomerAMGSetTruncFactor
  hypre_BoomerAMGRelax
  hypre_ParKrylovMatvecDestroy
  hypre_ParKrylovIdentity
  rfun
  hypre_BoomerAMGSetOuterWt
  HYPRE_BoomerAMGSetPrintFileName
  HYPRE_BoomerAMGSetPMaxElmts
  hypre_BoomerAMGSetOverlap
  hypre_BoomerAMGSetISType
  HYPRE_BoomerAMGSetRelaxOrder
  hypre_qsort2abs
  hypre_BoomerAMGSetLogging
  hypre_ExchangeRAPData
  hypre_BoomerAMGBuildExtPIInterp
  hypre_BoomerAMGSetupStats
  HYPRE_BoomerAMGSetMaxRowSum
  hypre_BoomerAMGBuildPartialExtPIInterp
  hypre_GenerateSubComm
  hypre_BoomerAMGSetTol
  hypre_BoomerAMGBuildExtInterp
  hypre_BoomerAMGSetChebyOrder
  hypre_ParCSRMaxEigEstimateCG
  hypre_BoomerAMGSetCRRate
  hypre_BoomerAMGSetJacobiTruncThreshold
  hypre_ParKrylovMatvec
  hypre_BoomerAMGSetCycleType
  HYPRE_BoomerAMGSetTol
  alt_insert_new_nodes
  hypre_BoomerAMGSetSmoothType
  hypre_BoomerAMGSetMaxIter
  hypre_BoomerAMGCoarsenFalgout
  HYPRE_BoomerAMGSetNumFunctions
  hypre_merge_lists
  hypre_BoomerAMGSetPMaxElmts
  hypre_BoomerAMGCreate
  hypre_ParKrylovClearVector
  hypre_BoomerAMGCreateS
  hypre_BoomerAMGSetAggPMaxElmts
  hypre_BoomerAMGSetGridRelaxType
  hypre_BoomerAMGSetPrintFileName
  HYPRE_BoomerAMGSetStrongThreshold
  HYPRE_BoomerAMGSetGridRelaxType
  hypre_BoomerAMGSetRelaxType
  hypre_map
  hypre_BoomerAMGCreateSCommPkg
  hypre_ParAMGData
  hypre_BoomerAMGSetChebyEigRatio
  hypre_BoomerAMGBuildPartialStdInterp
  hypre_BoomerAMGBuildMultipass
  hypre_BoomerAMGCorrectCFMarker
  hypre_BoomerAMGTruncateInterp
  hypre_BoomerAMGSetPMax2
  ffun
  hypre_ParKrylovAxpy
  hypre_BoomerAMGSetCycleRelaxType
  hypre_ParKrylovDestroyVector
  hypre_BoomerAMGSetRelaxWeight
  hypre_BoomerAMGSetMinIter
  hypre_BoomerAMGSetCRUseCG
  hypre_ParKrylovFree
  hypre_BoomerAMGSolve
  hypre_GetCommPkgRTFromCommPkgA
  bfun
  hypre_BoomerAMGSetDebugFlag
  hypre_BoomerAMGSetNumFunctions
  hypre_BoomerAMGSetGridRelaxPoints
  hypre_seqAMGSetup
  HYPRE_BoomerAMGSetPrintLevel
  hypre_ParKrylovCopyVector
  hypre_ParCSRMatrixScaledNorm
  hypre_BoomerAMGSetSetupType
  hypre_BoomerAMGSetStrongThreshold
  hypre_BoomerAMGSetMeasureType
  HYPRE_BoomerAMGSetNumGridSweeps
  hypre_ParCSRFindExtendCommPkg
  hypre_BoomerAMGCoarsenHMIS
  hypre_BoomerAMGCycle
  bndfun
  cfun
  hypre_BoomerAMGIndepSetInit
  hypre_ParCSRRelax_L1_GS
  hypre_BoomerAMGSetNumCRRelaxSteps
  hypre_ParKrylovMatvecCreate
  HYPRE_BoomerAMGSetInterpType
  hypre_BoomerAMGSetMaxRowSum
  hypre_BoomerAMGSetVariant
  HYPRE_BoomerAMGSetRelaxWeight
  hypre_BoomerAMGBuildExtPICCInterp
  hypre_BoomerAMGBuildCoarseOperator
  hypre_BoomerAMGSetAggNumLevels
  hypre_BoomerAMGJacobiInterp_1
  hypre_BoomerAMGBuildPartialExtInterp
  HYPRE_BoomerAMGSetCycleNumSweeps

Entities used from f45: AMG2013/parcsr_ls/headers.h :
  hypre_ParCSRRelax_L1
  hypre_BoomerAMGWriteSolverParams
  hypre_BoomerAMGSetNumIterations
  hypre_ParCSRMatrix_dof_func_offd
  hypre_ParKrylovCommInfo
  hypre_BoomerAMGBuildInterp
  hypre_ParKrylovCreateVector
  big_insert_new_nodes
  hypre_BoomerAMGSetNumGridSweeps
  hypre_ParCSRComputeL1NormsThreads
  hypre_BoomerAMGSetInterpType
  hypre_BoomerAMGSetPrintLevel
  gfun
  hypre_BoomerAMGJacobiInterp
  efun
  hypre_Bisection
  hypre_BoomerAMGCreate2ndS
  hypre_ParCSRRelax_L1_Jacobi
  hypre_BoomerAMGSetup
  hypre_BoomerAMGCreateSabs
  hypre_BoomerAMGCorrectCFMarker2
  hypre_ParCSRRelax_CG
  hypre_BoomerAMGSetPostInterpType
  hypre_BoomerAMGCoarsenRuge
  hypre_BoomerAMGSetRelaxOrder
  hypre_BoomerAMGSetNumSweeps
  hypre_BoomerAMGSetNumSamples
  hypre_SeqAMGData
  hypre_BoomerAMGSetNumPaths
  hypre_BoomerAMGSetMaxLevels
  hypre_ParCSRRelax_Cheby
  hypre_BoomerAMGRelaxIF
  hypre_BoomerAMGCreateScalarCFS
  hypre_BoomerAMGSetCycleNumSweeps
  hypre_BoomerAMGSetGSMG
  hypre_BoomerAMGSetCoarsenType
  hypre_ParCSRComputeL1Norms
  hypre_BoomerAMGSetPMax1
  hypre_BoomerAMGBuildStdInterp
  hypre_seqAMGCycle
  dfun
  hypre_ParKrylovIdentitySetup
  hypre_ParKrylovScaleVector
  hypre_BoomerAMGDestroy
  hypre_BoomerAMGSetAggInterpType
  gselim
  hypre_BoomerAMGSetRelaxWt
  new_offd_nodes
  hypre_BoomerAMGInterpTruncation
  hypre_BoomerAMGBuildFF1Interp
  hypre_BoomerAMGRelax_FCFJacobi
  hypre_BoomerAMGSetSCommPkgSwitch
  hypre_ParKrylovCreateVectorArray
  hypre_BoomerAMGCreateNodalA
  afun
  hypre_BoomerAMGSetNodal
  hypre_BoomerAMGCoarseParms
  hypre_BoomerAMGSetSmoothNumLevels
  hypre_ParKrylovInnerProd
  hypre_BoomerAMGSetSmoothNumSweeps
  hypre_BoomerAMGSetRestriction
  hypre_BoomerAMGCoarsenPMIS
  hypre_BoomerAMGIndepSet
  hypre_BoomerAMGCoarsen
  hypre_BoomerAMGCGRelaxWt
  hypre_BoomerAMGSetAggTruncFactor
  hypre_BoomerAMGSetTruncFactor
  hypre_BoomerAMGRelax
  hypre_ParKrylovMatvecDestroy
  hypre_ParKrylovIdentity
  rfun
  hypre_BoomerAMGSetOuterWt
  hypre_BoomerAMGSetOverlap
  hypre_BoomerAMGSetISType
  hypre_qsort2abs
  hypre_BoomerAMGSetLogging
  hypre_ExchangeRAPData
  hypre_BoomerAMGBuildExtPIInterp
  hypre_BoomerAMGSetupStats
  hypre_BoomerAMGBuildPartialExtPIInterp
  hypre_GenerateSubComm
  hypre_BoomerAMGSetTol
  hypre_BoomerAMGBuildExtInterp
  hypre_BoomerAMGSetChebyOrder
  hypre_ParCSRMaxEigEstimateCG
  hypre_BoomerAMGSetCRRate
  hypre_BoomerAMGSetJacobiTruncThreshold
  hypre_ParKrylovMatvec
  hypre_BoomerAMGSetCycleType
  alt_insert_new_nodes
  hypre_BoomerAMGSetSmoothType
  hypre_BoomerAMGSetMaxIter
  hypre_BoomerAMGCoarsenFalgout
  hypre_merge_lists
  hypre_BoomerAMGSetPMaxElmts
  hypre_BoomerAMGCreate
  hypre_ParKrylovClearVector
  hypre_BoomerAMGCreateS
  hypre_BoomerAMGSetAggPMaxElmts
  hypre_BoomerAMGSetGridRelaxType
  hypre_BoomerAMGSetPrintFileName
  hypre_BoomerAMGSetRelaxType
  hypre_map
  hypre_BoomerAMGCreateSCommPkg
  hypre_ParAMGData
  hypre_BoomerAMGSetChebyEigRatio
  hypre_BoomerAMGBuildPartialStdInterp
  hypre_BoomerAMGBuildMultipass
  hypre_BoomerAMGCorrectCFMarker
  hypre_BoomerAMGTruncateInterp
  hypre_BoomerAMGSetPMax2
  ffun
  hypre_ParKrylovAxpy
  hypre_BoomerAMGSetCycleRelaxType
  hypre_ParKrylovDestroyVector
  hypre_BoomerAMGSetRelaxWeight
  hypre_BoomerAMGSetMinIter
  hypre_BoomerAMGSetCRUseCG
  hypre_ParKrylovFree
  hypre_BoomerAMGSolve
  hypre_GetCommPkgRTFromCommPkgA
  bfun
  hypre_BoomerAMGSetDebugFlag
  hypre_BoomerAMGSetNumFunctions
  hypre_BoomerAMGSetGridRelaxPoints
  hypre_seqAMGSetup
  hypre_ParKrylovCopyVector
  hypre_ParCSRMatrixScaledNorm
  hypre_BoomerAMGSetSetupType
  hypre_BoomerAMGSetStrongThreshold
  hypre_BoomerAMGSetMeasureType
  hypre_ParCSRFindExtendCommPkg
  hypre_BoomerAMGCoarsenHMIS
  hypre_BoomerAMGCycle
  bndfun
  cfun
  hypre_BoomerAMGIndepSetInit
  hypre_ParCSRRelax_L1_GS
  hypre_BoomerAMGSetNumCRRelaxSteps
  hypre_ParKrylovMatvecCreate
  hypre_BoomerAMGSetMaxRowSum
  hypre_BoomerAMGSetVariant
  hypre_BoomerAMGBuildExtPICCInterp
  hypre_BoomerAMGBuildCoarseOperator
  hypre_BoomerAMGSetAggNumLevels
  hypre_BoomerAMGJacobiInterp_1
  hypre_BoomerAMGBuildPartialExtInterp

Entities used from f46: AMG2013/parcsr_ls/parcsr_ls.h :
  hypre_ParCSRRelax_L1
  hypre_BoomerAMGWriteSolverParams
  hypre_BoomerAMGSetNumIterations
  hypre_ParCSRMatrix_dof_func_offd
  hypre_ParKrylovCommInfo
  hypre_BoomerAMGBuildInterp
  hypre_ParKrylovCreateVector
  big_insert_new_nodes
  hypre_BoomerAMGSetNumGridSweeps
  hypre_ParCSRComputeL1NormsThreads
  hypre_BoomerAMGSetInterpType
  hypre_BoomerAMGSetPrintLevel
  gfun
  hypre_BoomerAMGJacobiInterp
  efun
  hypre_Bisection
  hypre_BoomerAMGCreate2ndS
  hypre_ParCSRRelax_L1_Jacobi
  hypre_BoomerAMGSetup
  hypre_BoomerAMGCreateSabs
  hypre_BoomerAMGCorrectCFMarker2
  hypre_ParCSRRelax_CG
  hypre_BoomerAMGSetPostInterpType
  hypre_BoomerAMGCoarsenRuge
  hypre_BoomerAMGSetRelaxOrder
  hypre_BoomerAMGSetNumSweeps
  hypre_BoomerAMGSetNumSamples
  hypre_SeqAMGData
  hypre_BoomerAMGSetNumPaths
  hypre_BoomerAMGSetMaxLevels
  hypre_ParCSRRelax_Cheby
  hypre_BoomerAMGRelaxIF
  hypre_BoomerAMGCreateScalarCFS
  hypre_BoomerAMGSetCycleNumSweeps
  hypre_BoomerAMGSetGSMG
  hypre_BoomerAMGSetCoarsenType
  hypre_ParCSRComputeL1Norms
  hypre_BoomerAMGSetPMax1
  hypre_BoomerAMGBuildStdInterp
  hypre_seqAMGCycle
  dfun
  hypre_ParKrylovIdentitySetup
  hypre_ParKrylovScaleVector
  hypre_BoomerAMGDestroy
  hypre_BoomerAMGSetAggInterpType
  gselim
  hypre_BoomerAMGSetRelaxWt
  new_offd_nodes
  hypre_BoomerAMGInterpTruncation
  hypre_BoomerAMGBuildFF1Interp
  hypre_BoomerAMGRelax_FCFJacobi
  hypre_BoomerAMGSetSCommPkgSwitch
  hypre_ParKrylovCreateVectorArray
  hypre_BoomerAMGCreateNodalA
  afun
  hypre_BoomerAMGSetNodal
  hypre_BoomerAMGCoarseParms
  hypre_BoomerAMGSetSmoothNumLevels
  hypre_ParKrylovInnerProd
  hypre_BoomerAMGSetSmoothNumSweeps
  hypre_BoomerAMGSetRestriction
  hypre_BoomerAMGCoarsenPMIS
  hypre_BoomerAMGIndepSet
  hypre_BoomerAMGCoarsen
  hypre_BoomerAMGCGRelaxWt
  hypre_BoomerAMGSetAggTruncFactor
  hypre_BoomerAMGSetTruncFactor
  hypre_BoomerAMGRelax
  hypre_ParKrylovMatvecDestroy
  hypre_ParKrylovIdentity
  rfun
  hypre_BoomerAMGSetOuterWt
  hypre_BoomerAMGSetOverlap
  hypre_BoomerAMGSetISType
  hypre_qsort2abs
  hypre_BoomerAMGSetLogging
  hypre_ExchangeRAPData
  hypre_BoomerAMGBuildExtPIInterp
  hypre_BoomerAMGSetupStats
  hypre_BoomerAMGBuildPartialExtPIInterp
  hypre_GenerateSubComm
  hypre_BoomerAMGSetTol
  hypre_BoomerAMGBuildExtInterp
  hypre_BoomerAMGSetChebyOrder
  hypre_ParCSRMaxEigEstimateCG
  hypre_BoomerAMGSetCRRate
  hypre_BoomerAMGSetJacobiTruncThreshold
  hypre_ParKrylovMatvec
  hypre_BoomerAMGSetCycleType
  alt_insert_new_nodes
  hypre_BoomerAMGSetSmoothType
  hypre_BoomerAMGSetMaxIter
  hypre_BoomerAMGCoarsenFalgout
  hypre_merge_lists
  hypre_BoomerAMGSetPMaxElmts
  hypre_BoomerAMGCreate
  hypre_ParKrylovClearVector
  hypre_BoomerAMGCreateS
  hypre_BoomerAMGSetAggPMaxElmts
  hypre_BoomerAMGSetGridRelaxType
  hypre_BoomerAMGSetPrintFileName
  hypre_BoomerAMGSetRelaxType
  hypre_map
  hypre_BoomerAMGCreateSCommPkg
  hypre_ParAMGData
  hypre_BoomerAMGSetChebyEigRatio
  hypre_BoomerAMGBuildPartialStdInterp
  hypre_BoomerAMGBuildMultipass
  hypre_BoomerAMGCorrectCFMarker
  hypre_BoomerAMGTruncateInterp
  hypre_BoomerAMGSetPMax2
  ffun
  hypre_ParKrylovAxpy
  hypre_BoomerAMGSetCycleRelaxType
  hypre_ParKrylovDestroyVector
  hypre_BoomerAMGSetRelaxWeight
  hypre_BoomerAMGSetMinIter
  hypre_BoomerAMGSetCRUseCG
  hypre_ParKrylovFree
  hypre_BoomerAMGSolve
  hypre_GetCommPkgRTFromCommPkgA
  bfun
  hypre_BoomerAMGSetDebugFlag
  hypre_BoomerAMGSetNumFunctions
  hypre_BoomerAMGSetGridRelaxPoints
  hypre_seqAMGSetup
  hypre_ParKrylovCopyVector
  hypre_ParCSRMatrixScaledNorm
  hypre_BoomerAMGSetSetupType
  hypre_BoomerAMGSetStrongThreshold
  hypre_BoomerAMGSetMeasureType
  hypre_ParCSRFindExtendCommPkg
  hypre_BoomerAMGCoarsenHMIS
  hypre_BoomerAMGCycle
  bndfun
  cfun
  hypre_BoomerAMGIndepSetInit
  hypre_ParCSRRelax_L1_GS
  hypre_BoomerAMGSetNumCRRelaxSteps
  hypre_ParKrylovMatvecCreate
  hypre_BoomerAMGSetMaxRowSum
  hypre_BoomerAMGSetVariant
  hypre_BoomerAMGBuildExtPICCInterp
  hypre_BoomerAMGBuildCoarseOperator
  hypre_BoomerAMGSetAggNumLevels
  hypre_BoomerAMGJacobiInterp_1
  hypre_BoomerAMGBuildPartialExtInterp

Entities used from f47: AMG2013/parcsr_ls/par_amg.h :
  hypre_SeqAMGData
  hypre_ParAMGData

Entities used from f48: AMG2013/parcsr_ls/HYPRE_parcsr_gmres.c :
  HYPRE_ParCSRGMRESCreate
  HYPRE_ParCSRGMRESDestroy

Entities used from f49: AMG2013/parcsr_ls/HYPRE_parcsr_pcg.c :
  HYPRE_ParCSRPCGDestroy
  HYPRE_ParCSRPCGCreate
  HYPRE_ParCSRPCGSetup
  HYPRE_ParCSRDiagScaleSetup
  HYPRE_ParCSRPCGSolve
  HYPRE_ParCSRDiagScale

Entities used from f50: AMG2013/parcsr_ls/aux_interp.c :
  new_offd_nodes
  hypre_ParCSRFindExtendCommPkg
  big_insert_new_nodes
  alt_insert_new_nodes

Entities used from f51: AMG2013/parcsr_ls/gen_redcs_mat.c :
  hypre_seqAMGSetup
  hypre_seqAMGCycle
  hypre_merge_lists
  hypre_GenerateSubComm

Entities used from f52: AMG2013/parcsr_ls/par_amg.c :
  hypre_BoomerAMGSetOverlap
  hypre_BoomerAMGSetISType
  hypre_BoomerAMGSetNumIterations
  hypre_BoomerAMGSetNumGridSweeps
  hypre_BoomerAMGSetLogging
  hypre_BoomerAMGSetInterpType
  hypre_BoomerAMGSetPrintLevel
  hypre_BoomerAMGSetTol
  hypre_BoomerAMGSetChebyOrder
  hypre_BoomerAMGSetCRRate
  hypre_BoomerAMGSetJacobiTruncThreshold
  hypre_BoomerAMGSetPostInterpType
  hypre_BoomerAMGSetCycleType
  hypre_BoomerAMGSetRelaxOrder
  hypre_BoomerAMGSetNumSweeps
  hypre_BoomerAMGSetSmoothType
  hypre_BoomerAMGSetNumSamples
  hypre_BoomerAMGSetNumPaths
  hypre_BoomerAMGSetMaxLevels
  hypre_BoomerAMGSetMaxIter
  hypre_BoomerAMGSetPMaxElmts
  hypre_BoomerAMGCreate
  hypre_BoomerAMGSetAggPMaxElmts
  hypre_BoomerAMGSetCycleNumSweeps
  hypre_BoomerAMGSetGSMG
  hypre_BoomerAMGSetCoarsenType
  hypre_BoomerAMGSetGridRelaxType
  hypre_BoomerAMGSetPrintFileName
  hypre_BoomerAMGSetPMax1
  hypre_BoomerAMGSetRelaxType
  hypre_BoomerAMGSetChebyEigRatio
  hypre_BoomerAMGSetPMax2
  hypre_BoomerAMGDestroy
  hypre_BoomerAMGSetAggInterpType
  hypre_BoomerAMGSetCycleRelaxType
  hypre_BoomerAMGSetRelaxWeight
  hypre_BoomerAMGSetMinIter
  hypre_BoomerAMGSetCRUseCG
  hypre_BoomerAMGSetRelaxWt
  hypre_BoomerAMGSetSCommPkgSwitch
  hypre_BoomerAMGSetDebugFlag
  hypre_BoomerAMGSetNumFunctions
  hypre_BoomerAMGSetGridRelaxPoints
  hypre_BoomerAMGSetNodal
  hypre_BoomerAMGSetSmoothNumLevels
  hypre_BoomerAMGSetSetupType
  hypre_BoomerAMGSetStrongThreshold
  hypre_BoomerAMGSetMeasureType
  hypre_BoomerAMGSetSmoothNumSweeps
  hypre_BoomerAMGSetRestriction
  hypre_BoomerAMGSetNumCRRelaxSteps
  hypre_BoomerAMGSetMaxRowSum
  hypre_BoomerAMGSetVariant
  hypre_BoomerAMGSetAggTruncFactor
  hypre_BoomerAMGSetTruncFactor
  hypre_BoomerAMGSetAggNumLevels
  hypre_BoomerAMGSetOuterWt

Entities used from f53: AMG2013/parcsr_ls/par_amg_setup.c :
  hypre_BoomerAMGSetup

Entities used from f54: AMG2013/parcsr_ls/par_amg_solve.c :
  hypre_BoomerAMGSolve

Entities used from f55: AMG2013/parcsr_ls/par_cg_relax_wt.c :
  hypre_BoomerAMGCGRelaxWt
  hypre_Bisection

Entities used from f56: AMG2013/parcsr_ls/par_coarse_parms.c :
  hypre_BoomerAMGCoarseParms

Entities used from f57: AMG2013/parcsr_ls/par_coarsen.c :
  hypre_BoomerAMGCoarsen
  hypre_BoomerAMGCoarsenFalgout
  hypre_BoomerAMGCoarsenRuge
  hypre_BoomerAMGCoarsenHMIS
  hypre_BoomerAMGCoarsenPMIS

Entities used from f58: AMG2013/parcsr_ls/par_cycle.c :
  hypre_BoomerAMGCycle

Entities used from f59: AMG2013/parcsr_ls/par_indepset.c :
  hypre_BoomerAMGIndepSet
  hypre_BoomerAMGIndepSetInit

Entities used from f60: AMG2013/parcsr_ls/par_interp.c :
  hypre_BoomerAMGInterpTruncation
  hypre_BoomerAMGBuildInterp
  hypre_qsort2abs

Entities used from f62: AMG2013/parcsr_ls/par_jacobi_interp.c :
  hypre_BoomerAMGJacobiInterp
  hypre_ParCSRMatrix_dof_func_offd
  hypre_BoomerAMGTruncateInterp
  hypre_BoomerAMGJacobiInterp_1

Entities used from f63: AMG2013/parcsr_ls/par_laplace.c :
  hypre_map
  GenerateLaplacian

Entities used from f64: AMG2013/parcsr_ls/par_laplace_27pt.c :
  GenerateLaplacian27pt

Entities used from f65: AMG2013/parcsr_ls/par_lr_interp.c :
  hypre_BoomerAMGBuildExtPIInterp
  hypre_BoomerAMGBuildStdInterp
  hypre_BoomerAMGBuildFF1Interp
  hypre_BoomerAMGBuildExtPICCInterp
  hypre_BoomerAMGBuildExtInterp

Entities used from f67: AMG2013/parcsr_ls/par_multi_interp.c :
  hypre_BoomerAMGBuildMultipass

Entities used from f68: AMG2013/parcsr_ls/par_nodal_systems.c :
  hypre_BoomerAMGCreateScalarCFS
  hypre_BoomerAMGCreateNodalA

Entities used from f69: AMG2013/parcsr_ls/par_rap.c :
  hypre_BoomerAMGBuildCoarseOperator
  hypre_ExchangeRAPData

Entities used from f70: AMG2013/parcsr_ls/par_rap_communication.c :
  hypre_GetCommPkgRTFromCommPkgA

Entities used from f71: AMG2013/parcsr_ls/par_relax.c :
  gselim
  hypre_BoomerAMGRelax

Entities used from f72: AMG2013/parcsr_ls/par_relax_interface.c :
  hypre_BoomerAMGRelaxIF

Entities used from f73: AMG2013/parcsr_ls/par_relax_more.c :
  hypre_ParCSRMaxEigEstimateCG
  hypre_ParCSRRelax_L1_Jacobi
  hypre_ParCSRComputeL1Norms
  hypre_ParCSRRelax_L1
  hypre_ParCSRRelax_Cheby
  hypre_LINPACKcgpthy
  hypre_ParCSRRelax_CG
  hypre_BoomerAMGRelax_FCFJacobi
  hypre_LINPACKcgtql1
  hypre_ParCSRComputeL1NormsThreads
  hypre_ParCSRRelax_L1_GS

Entities used from f75: AMG2013/parcsr_ls/par_scaled_matnorm.c :
  hypre_ParCSRMatrixScaledNorm

Entities used from f76: AMG2013/parcsr_ls/par_stats.c :
  hypre_BoomerAMGSetupStats
  hypre_BoomerAMGWriteSolverParams

Entities used from f77: AMG2013/parcsr_ls/par_strength.c :
  hypre_BoomerAMGCreateSabs
  hypre_BoomerAMGCreateSCommPkg
  hypre_BoomerAMGCorrectCFMarker2
  hypre_BoomerAMGCorrectCFMarker
  hypre_BoomerAMGCreateS
  hypre_BoomerAMGCreate2ndS

Entities used from f78: AMG2013/parcsr_ls/par_vardifconv.c :
  dfun
  GenerateVarDifConv
  bfun
  efun
  ffun
  rfun
  bndfun
  afun
  cfun
  gfun

Entities used from f79: AMG2013/parcsr_ls/partial.c :
  hypre_BoomerAMGBuildPartialStdInterp
  hypre_BoomerAMGBuildPartialExtPIInterp
  hypre_BoomerAMGBuildPartialExtInterp

Entities used from f80: AMG2013/parcsr_ls/pcg_par.c :
  hypre_ParKrylovInnerProd
  hypre_ParKrylovCopyVector
  hypre_ParKrylovCommInfo
  hypre_ParKrylovIdentitySetup
  hypre_ParKrylovMatvec
  hypre_ParKrylovCreateVector
  hypre_ParKrylovScaleVector
  hypre_ParKrylovAxpy
  hypre_ParKrylovDestroyVector
  hypre_ParKrylovMatvecCreate
  hypre_ParKrylovFree
  hypre_ParKrylovMatvecDestroy
  hypre_ParKrylovClearVector
  hypre_ParKrylovIdentity
  hypre_ParKrylovCreateVectorArray

Entities used from f81: AMG2013/parcsr_mv/HYPRE_parcsr_matrix.c :
  HYPRE_ParCSRMatrixMatvec
  HYPRE_ParCSRMatrixDestroy
  HYPRE_ParCSRMatrixGetRow
  HYPRE_ParCSRMatrixPrintIJ
  HYPRE_ParCSRMatrixRestoreRow

Entities used from f83: AMG2013/parcsr_mv/HYPRE_parcsr_vector.c :
  HYPRE_ParVectorPrintIJ
  HYPRE_ParVectorDestroy

Entities used from f85: AMG2013/parcsr_mv/par_csr_assumed_part.c :
  hypre_ParVectorDestroyAssumedPartition
  hypre_ParCSRMatrixDestroyAssumedPartition

Entities used from f86: AMG2013/parcsr_mv/par_csr_communication.c :
  hypre_ParCSRCommHandleDestroy
  hypre_ParCSRCommHandleCreate
  hypre_MatvecCommPkgCreate
  hypre_MatvecCommPkgCreate_core
  hypre_MatvecCommPkgDestroy

Entities used from f87: AMG2013/parcsr_mv/par_csr_matop.c :
  hypre_ParCSRMatrixExtractConvBExt
  hypre_ParMatmul_RowSizes
  hypre_ParMatmul
  hypre_ParCSRMatrixExtractBigExt

Entities used from f90: AMG2013/parcsr_mv/par_csr_matop_marked.c :
  hypre_ParMatmul_RowSizes_Marked
  hypre_ParCSRMatrixZero_F
  hypre_ParMatmul_FC
  hypre_ParMatMinus_F
  hypre_ParCSRMatrixCopy_C
  hypre_ParMatScaleDiagInv_F

Entities used from f91: AMG2013/parcsr_mv/par_csr_matrix.c :
  hypre_ParCSRMatrixPrintIJ
  hypre_ParCSRMatrixSetRowStartsOwner
  hypre_ParCSRMatrixSetDNumNonzeros
  hypre_ParCSRMatrixRestoreRow
  hypre_MergeDiagAndOffd
  hypre_ParCSRMatrixSetColStartsOwner
  hypre_ParCSRMatrixCreate
  hypre_ParCSRMatrixToCSRMatrixAll
  hypre_ParCSRMatrixUnion
  hypre_ParCSRMatrixSetNumNonzeros
  hypre_ParCSRMatrixCopy
  hypre_ParCSRMatrixInitialize
  hypre_ParCSRMatrixGetRow
  hypre_ParCSRMatrixDestroy

Entities used from f94: AMG2013/parcsr_mv/par_csr_matvec.c :
  hypre_ParCSRMatrixMatvec
  hypre_ParCSRMatrixMatvecT

Entities used from f95: AMG2013/parcsr_mv/par_vector.c :
  hypre_ParVectorToVectorAll
  hypre_ParVectorCopy
  hypre_ParVectorInitialize
  hypre_ParVectorSetRandomValues
  hypre_ParVectorScale
  hypre_ParVectorDestroy
  hypre_ParVectorPrintIJ
  hypre_ParVectorCreate
  hypre_ParVectorSetPartitioningOwner
  hypre_ParVectorInnerProd
  hypre_ParVectorSetConstantValues
  hypre_ParVectorAxpy

Entities used from f99: AMG2013/seq_mv/big_csr_matrix.c :
  hypre_BigCSRMatrixCreate
  hypre_BigCSRMatrixDestroy

Entities used from f100: AMG2013/seq_mv/csr_matop.c :
  hypre_CSRMatrixTranspose

Entities used from f101: AMG2013/seq_mv/csr_matrix.c :
  hypre_CSRMatrixInitialize
  hypre_CSRMatrixCreate
  hypre_CSRMatrixSetRownnz
  hypre_CSRMatrixDestroy
  hypre_CSRMatrixUnion
  hypre_CSRMatrixCopy

Entities used from f102: AMG2013/seq_mv/csr_matvec.c :
  hypre_CSRMatrixMatvecT
  hypre_CSRMatrixMatvec

Entities used from f103: AMG2013/seq_mv/genpart.c :
  hypre_GeneratePartitioning

Entities used from f104: AMG2013/seq_mv/vector.c :
  hypre_SeqVectorSetRandomValues
  hypre_SeqVectorCopy
  hypre_SeqVectorDestroy
  hypre_SeqVectorScale
  hypre_SeqVectorAxpy
  hypre_SeqVectorInnerProd
  hypre_SeqVectorCreate
  hypre_SeqVectorInitialize
  hypre_SeqVectorSetConstantValues

Entities used from f105: AMG2013/sstruct_mv/HYPRE_sstruct_graph.c :
  HYPRE_SStructGraphSetStencil
  HYPRE_SStructGraphDestroy
  HYPRE_SStructGraphAddEntries
  HYPRE_SStructGraphCreate
  HYPRE_SStructGraphAssemble
  HYPRE_SStructGraphSetObjectType

Entities used from f107: AMG2013/sstruct_mv/HYPRE_sstruct_grid.c :
  HYPRE_SStructGridSetExtents
  HYPRE_SStructGridSetPeriodic
  HYPRE_SStructGridSetVariables
  HYPRE_SStructGridSetNeighborBox
  HYPRE_SStructGridAssemble
  HYPRE_SStructGridCreate
  HYPRE_SStructGridDestroy

Entities used from f108: AMG2013/sstruct_mv/HYPRE_sstruct_matrix.c :
  HYPRE_SStructMatrixSetValues
  HYPRE_SStructMatrixCreate
  HYPRE_SStructMatrixAddToBoxValues
  HYPRE_SStructMatrixSetObjectType
  HYPRE_SStructMatrixGetObject
  HYPRE_SStructMatrixInitialize
  HYPRE_SStructMatrixSetSymmetric
  HYPRE_SStructMatrixPrint
  HYPRE_SStructMatrixDestroy
  HYPRE_SStructMatrixSetBoxValues
  HYPRE_SStructMatrixAssemble
  HYPRE_SStructMatrixSetNSSymmetric

Entities used from f109: AMG2013/sstruct_mv/HYPRE_sstruct_stencil.c :
  HYPRE_SStructStencilDestroy
  HYPRE_SStructStencilCreate
  HYPRE_SStructStencilSetEntry

Entities used from f110: AMG2013/sstruct_mv/HYPRE_sstruct_vector.c :
  HYPRE_SStructVectorSetBoxValues
  HYPRE_SStructVectorAssemble
  HYPRE_SStructVectorSetObjectType
  HYPRE_SStructVectorGetObject
  HYPRE_SStructVectorCreate
  HYPRE_SStructVectorPrint
  HYPRE_SStructVectorGather
  HYPRE_SStructVectorDestroy
  HYPRE_SStructVectorInitialize

Entities used from f111: AMG2013/sstruct_mv/box_map.c :
  hypre_BoxMapEntryGetInfo
  hypre_BoxMapFindEntry
  hypre_BoxMapIntersect
  hypre_BoxMapIncSize
  hypre_BoxMapAddEntry
  hypre_BoxMapAssemble
  hypre_BoxMapDestroy
  hypre_BoxMapCreate
  hypre_BoxMapSetNumGhost
  hypre_BoxMapFindBoxProcEntry
  hypre_BoxMapEntryGetExtents

Entities used from f114: AMG2013/sstruct_mv/sstruct_graph.c :
  hypre_SStructGraphRef
  hypre_SStructGraphFindUVEntry

Entities used from f115: AMG2013/sstruct_mv/sstruct_grid.c :
  hypre_SStructGridAssembleMaps
  hypre_SStructPGridSetExtents
  hypre_SStructPGridSetVariables
  hypre_SStructMapEntryGetBox
  hypre_SStructMapEntryGetGhstrides
  hypre_SStructPGridSetPNeighbor
  hypre_SStructVariableGetOffset
  hypre_SStructPGridDestroy
  hypre_SStructGridRef
  hypre_SStructMapEntryGetProcess
  hypre_SStructGridFindMapEntry
  hypre_SStructNBorBoxToBox
  hypre_SStructGridAssembleNBorMaps
  hypre_SStructBoxToNBorBox
  hypre_SStructMapEntryGetStrides
  hypre_SStructMapEntryGetGlobalCSRank
  hypre_SStructMapEntryGetCSRstrides
  hypre_SStructPGridCreate
  hypre_SStructGridBoxProcFindMapEntry
  hypre_SStructMapEntryGetGlobalRank
  hypre_SStructPGridAssemble
  hypre_SStructMapEntryGetGlobalGhrank

Entities used from f117: AMG2013/sstruct_mv/sstruct_matrix.c :
  hypre_SStructUMatrixAssemble
  hypre_SStructPMatrixAssemble
  hypre_SStructPMatrixInitialize
  hypre_SStructPMatrixSetBoxValues
  hypre_SStructMatrixSplitEntries
  hypre_SStructPMatrixSetValues
  hypre_SStructUMatrixSetBoxValues
  hypre_SStructUMatrixInitialize
  hypre_SStructPMatrixPrint
  hypre_SStructPMatrixDestroy
  hypre_SStructPMatrixSetSymmetric
  hypre_SStructUMatrixSetValues
  hypre_SStructPMatrixCreate

Entities used from f118: AMG2013/sstruct_mv/sstruct_matvec.c :
  hypre_SStructPMatvecCompute
  hypre_SStructMatvecData
  hypre_SStructMatvecDestroy
  hypre_SStructMatvecSetup
  hypre_SStructPMatvecData
  hypre_SStructMatvecCompute
  hypre_SStructPMatvecDestroy
  hypre_SStructPMatvecCreate
  hypre_SStructMatvecCreate
  hypre_SStructMatvec
  hypre_SStructPMatvecSetup

Entities used from f121: AMG2013/sstruct_mv/sstruct_stencil.c :
  hypre_SStructStencilRef

Entities used from f122: AMG2013/sstruct_mv/sstruct_vector.c :
  hypre_SStructVectorInitializeShell
  hypre_SStructPVectorSetBoxValues
  hypre_SStructVectorRestore
  hypre_SStructPVectorPrint
  hypre_SStructVectorParRestore
  hypre_SStructVectorConvert
  hypre_SStructPVectorInitializeShell
  hypre_SStructPVectorDestroy
  hypre_SStructPVectorGather
  hypre_SStructPVectorCreate
  hypre_SStructPVectorAssemble
  hypre_SStructVectorParConvert

Entities used from f123: AMG2013/struct_mv/HYPRE_struct_grid.c :
  HYPRE_StructGridCreate
  HYPRE_StructGridDestroy
  HYPRE_StructGridSetExtents
  HYPRE_StructGridSetPeriodic
  HYPRE_StructGridAssemble

Entities used from f125: AMG2013/struct_mv/HYPRE_struct_matrix.c :
  HYPRE_StructMatrixSetSymmetric

Entities used from f126: AMG2013/struct_mv/HYPRE_struct_stencil.c :
  HYPRE_StructStencilSetElement
  HYPRE_StructStencilCreate
  HYPRE_StructStencilDestroy

Entities used from f129: AMG2013/struct_mv/box.c :
  hypre_BoxArrayCreate
  hypre_BoxArrayDuplicate
  hypre_BoxGetSize
  hypre_BoxGetStrideVolume
  hypre_AppendBox
  hypre_BoxArraySetSize
  hypre_BoxExpand
  hypre_BoxSetExtents
  hypre_BoxArrayArrayCreate
  hypre_BoxDestroy
  hypre_BoxArrayArrayDestroy
  hypre_BoxDuplicate
  hypre_BoxArrayArrayDuplicate
  hypre_BoxCreate
  hypre_BoxArrayDestroy
  hypre_BoxGetStrideSize
  hypre_AppendBoxArray

Entities used from f130: AMG2013/struct_mv/box_algebra.c :
  hypre_SubtractBoxes
  hypre_SubtractBoxArrays
  hypre_IntersectBoxes
  hypre_SubtractBoxArraysExceptBoxes

Entities used from f132: AMG2013/struct_mv/box_boundary.c :
  hypre_BoxArraySubtractAdjacentBoxArrayD
  hypre_BoxBoundaryG
  hypre_BoxBoundaryDNT
  hypre_BoxBoundaryNT

Entities used from f134: AMG2013/struct_mv/box_neighbors.c :
  hypre_RankLinkDestroy
  hypre_RankLinkCreate
  hypre_BoxNeighborsDestroy
  hypre_BoxNeighborsCreate
  hypre_BoxNeighborsAssemble

Entities used from f135: AMG2013/struct_mv/communication_info.c :
  hypre_CreateCommInfoFromStencil
  hypre_CommInfoDestroy
  hypre_CreateCommInfoFromNumGhost
  hypre_CommInfoCreate

Entities used from f136: AMG2013/struct_mv/computation.c :
  hypre_ComputeInfoCreate
  hypre_ComputePkgDestroy
  hypre_CreateComputeInfo
  hypre_ComputePkgCreate
  hypre_ComputeInfoDestroy
  hypre_InitializeIndtComputations
  hypre_FinalizeIndtComputations

Entities used from f142: AMG2013/struct_mv/struct_communication.c :
  hypre_CommTypeSetEntries
  hypre_InitializeCommunication
  hypre_FinalizeCommunication
  hypre_CommTypeSetEntry
  hypre_ExchangeLocalData
  hypre_CommPkgCreate
  hypre_CommPkgDestroy

Entities used from f144: AMG2013/struct_mv/struct_grid.c :
  hypre_StructGridDestroy
  hypre_StructGridPrint
  hypre_StructGridRef
  hypre_StructGridSetExtents
  hypre_StructGridAssemble
  hypre_StructGridSetBoxes
  hypre_ComputeBoxnums
  hypre_StructGridCreate
  hypre_StructGridSetPeriodic
  hypre_GatherAllBoxes

Entities used from f146: AMG2013/struct_mv/struct_io.c :
  hypre_PrintBoxArrayData
  hypre_PrintCCBoxArrayData
  hypre_PrintCCVDBoxArrayData

Entities used from f147: AMG2013/struct_mv/struct_matrix.c :
  hypre_StructMatrixPrint
  hypre_StructMatrixExtractPointerByIndex
  hypre_StructMatrixInitializeData
  hypre_StructMatrixCreate
  hypre_StructMatrixRef
  hypre_StructMatrixSetBoxValues
  hypre_StructMatrixInitialize
  hypre_StructMatrixInitializeShell
  hypre_StructMatrixDestroy
  hypre_StructMatrixSetValues
  hypre_StructMatrixAssemble
  hypre_StructMatrixSetNumGhost

Entities used from f149: AMG2013/struct_mv/struct_matvec.c :
  hypre_StructMatvecSetup
  hypre_StructMatvecDestroy
  hypre_StructMatvecCompute
  hypre_StructMatvecCreate
  hypre_StructMatvecData
  hypre_StructMatvecCC2
  hypre_StructMatvecCC0
  hypre_StructMatvecCC1

Entities used from f151: AMG2013/struct_mv/struct_scale.c :
  hypre_StructScale

Entities used from f152: AMG2013/struct_mv/struct_stencil.c :
  hypre_StructStencilCreate
  hypre_StructStencilDestroy
  hypre_StructStencilSymmetrize
  hypre_StructStencilRef
  hypre_StructStencilElementRank

Entities used from f153: AMG2013/struct_mv/struct_vector.c :
  hypre_StructVectorClearBoundGhostValues
  hypre_StructVectorPrint
  hypre_StructVectorCreate
  hypre_StructVectorInitializeData
  hypre_StructVectorRef
  hypre_StructVectorSetBoxValues
  hypre_StructVectorDestroy
  hypre_StructVectorAssemble
  hypre_StructVectorInitializeShell

Entities used from f154: AMG2013/utilities/amg_linklist.c :
  dispose_elt
  enter_on_lists
  remove_point
  create_elt

Entities used from f155: AMG2013/utilities/binsearch.c :
  hypre_BigBinarySearch
  hypre_BinarySearch

Entities used from f157: AMG2013/utilities/hypre_error.c :
  hypre__global_error
  hypre_error_handler

Entities used from f158: AMG2013/utilities/hypre_memory.c :
  hypre_OutOfMemory
  hypre_Free
  hypre_CAlloc
  hypre_ReAlloc
  hypre_MAlloc

Entities used from f159: AMG2013/utilities/hypre_qsort.c :
  qsort0
  hypre_BigQsortbi
  swap
  hypre_BigSwapbi
  swap2
  hypre_BigSwap
  hypre_BigQsort0

Entities used from f163: AMG2013/utilities/random.c :
  hypre_SeedRand
  hypre_Rand
  Seed

Entities used from f166: AMG2013/utilities/timer.c :
  $anon_enum_0
  time_getWallclockSeconds
  clock
  tms
  clock_t
  times
  time_getCPUSeconds
  sysconf

Entities used from f167: /include/abc/time.h :
  clock
  clock_t

Entities used from f168: /include/abc/unistd.h :
  $anon_enum_0
  sysconf

Entities used from f172: /include/abc/sys/times.h :
  tms
  times

Entities used from f173: AMG2013/utilities/timing.c :
  hypre_global_timing
  hypre_ClearTiming
  hypre_BeginTiming
  hypre_InitializeTiming
  hypre_PrintTiming
  hypre_FinalizeTiming
  hypre_EndTiming
