1 /******************************************************************************
2  * Copyright 1998-2019 Lawrence Livermore National Security, LLC and other
3  * HYPRE Project Developers. See the top-level COPYRIGHT file for details.
4  *
5  * SPDX-License-Identifier: (Apache-2.0 OR MIT)
6  ******************************************************************************/
7 
8 /*----------------------------------------------------
9  * Functions for the IJ assumed partition fir IJ_Matrix
10  *-----------------------------------------------------*/
11 
12 #include "_hypre_IJ_mv.h"
13 
14 /*------------------------------------------------------------------
15  * hypre_IJMatrixCreateAssumedPartition -
16  * Each proc gets it own range. Then
17  * each needs to reconcile its actual range with its assumed
18  * range - the result is essentila a partition of its assumed range -
19  * this is the assumed partition.
20  *--------------------------------------------------------------------*/
21 
22 
23 HYPRE_Int
hypre_IJMatrixCreateAssumedPartition(hypre_IJMatrix * matrix)24 hypre_IJMatrixCreateAssumedPartition( hypre_IJMatrix *matrix)
25 {
26    HYPRE_BigInt global_num_rows;
27    HYPRE_BigInt global_first_row;
28    HYPRE_Int myid;
29    HYPRE_BigInt row_start = 0, row_end = 0;
30    HYPRE_BigInt *row_partitioning = hypre_IJMatrixRowPartitioning(matrix);
31 
32    MPI_Comm   comm;
33 
34    hypre_IJAssumedPart *apart;
35 
36    global_num_rows = hypre_IJMatrixGlobalNumRows(matrix);
37    global_first_row = hypre_IJMatrixGlobalFirstRow(matrix);
38    comm = hypre_IJMatrixComm(matrix);
39 
40    /* find out my actual range of rows and rowumns */
41    row_start = row_partitioning[0];
42    row_end = row_partitioning[1]-1;
43    hypre_MPI_Comm_rank(comm, &myid );
44 
45    /* allocate space */
46    apart = hypre_CTAlloc(hypre_IJAssumedPart,  1, HYPRE_MEMORY_HOST);
47 
48    /* get my assumed partitioning  - we want row partitioning of the matrix
49       for off processor values - so we use the row start and end
50       Note that this is different from the assumed partitioning for the parcsr matrix
51       which needs it for matvec multiplications and therefore needs to do it for
52       the col partitioning */
53    hypre_GetAssumedPartitionRowRange( comm, myid, global_first_row,
54 			global_num_rows, &(apart->row_start), &(apart->row_end));
55 
56    /*allocate some space for the partition of the assumed partition */
57    apart->length = 0;
58    /*room for 10 owners of the assumed partition*/
59    apart->storage_length = 10; /*need to be >=1 */
60    apart->proc_list = hypre_TAlloc(HYPRE_Int,  apart->storage_length, HYPRE_MEMORY_HOST);
61    apart->row_start_list =   hypre_TAlloc(HYPRE_BigInt,  apart->storage_length, HYPRE_MEMORY_HOST);
62    apart->row_end_list =   hypre_TAlloc(HYPRE_BigInt,  apart->storage_length, HYPRE_MEMORY_HOST);
63 
64    /* now we want to reconcile our actual partition with the assumed partition */
65    hypre_LocateAssumedPartition(comm, row_start, row_end, global_first_row,
66                                  global_num_rows, apart, myid);
67 
68    /* this partition will be saved in the matrix data structure until the matrix is destroyed */
69    hypre_IJMatrixAssumedPart(matrix) = apart;
70 
71    return hypre_error_flag;
72 }
73 
74 /*--------------------------------------------------------------------
75  * hypre_IJVectorCreateAssumedPartition -
76 
77  * Essentially the same as for a matrix!
78 
79  * Each proc gets it own range. Then
80  * each needs to reconcile its actual range with its assumed
81  * range - the result is essentila a partition of its assumed range -
82  * this is the assumed partition.
83  *--------------------------------------------------------------------*/
84 
85 HYPRE_Int
hypre_IJVectorCreateAssumedPartition(hypre_IJVector * vector)86 hypre_IJVectorCreateAssumedPartition( hypre_IJVector *vector)
87 {
88    HYPRE_BigInt global_num, global_first_row;
89    HYPRE_Int myid;
90    HYPRE_Int  start=0, end=0;
91    HYPRE_BigInt *partitioning = hypre_IJVectorPartitioning(vector);
92 
93    MPI_Comm   comm;
94 
95    hypre_IJAssumedPart *apart;
96 
97    global_num = hypre_IJVectorGlobalNumRows(vector);
98    global_first_row = hypre_IJVectorGlobalFirstRow(vector);
99    comm = hypre_ParVectorComm(vector);
100 
101    /* find out my actualy range of rows */
102    start =  partitioning[0];
103    end = partitioning[1]-1;
104 
105    hypre_MPI_Comm_rank(comm, &myid );
106 
107    /* allocate space */
108    apart = hypre_CTAlloc(hypre_IJAssumedPart,  1, HYPRE_MEMORY_HOST);
109 
110    /* get my assumed partitioning  - we want partitioning of the vector that the
111       matrix multiplies - so we use the col start and end */
112    hypre_GetAssumedPartitionRowRange(comm, myid, global_first_row,
113                                      global_num, &(apart->row_start), &(apart->row_end));
114 
115    /*allocate some space for the partition of the assumed partition */
116    apart->length = 0;
117    /*room for 10 owners of the assumed partition*/
118    apart->storage_length = 10; /*need to be >=1 */
119    apart->proc_list = hypre_TAlloc(HYPRE_Int,  apart->storage_length, HYPRE_MEMORY_HOST);
120    apart->row_start_list =   hypre_TAlloc(HYPRE_BigInt,  apart->storage_length, HYPRE_MEMORY_HOST);
121    apart->row_end_list =   hypre_TAlloc(HYPRE_BigInt,  apart->storage_length, HYPRE_MEMORY_HOST);
122 
123    /* now we want to reconcile our actual partition with the assumed partition */
124    hypre_LocateAssumedPartition(comm, start, end, global_first_row,
125                                 global_num, apart, myid);
126 
127    /* this partition will be saved in the vector data structure until the vector is destroyed */
128    hypre_IJVectorAssumedPart(vector) = apart;
129 
130    return hypre_error_flag;
131 }
132