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 *
10 *****************************************************************************/
11
12 /* following should be in a header file */
13
14
15 #include "_hypre_parcsr_ls.h"
16
17
18
19 /*==========================================================================*/
20 /*==========================================================================*/
21 /**
22 Generates global coarse_size and dof_func for next coarser level
23
24 Notes:
25 \begin{itemize}
26 \item The routine returns the following:
27 \begin{itemize}
28 \item an integer array containing the
29 function values for the local coarse points
30 \item the global number of coarse points
31 \end{itemize}
32 \end{itemize}
33
34 {\bf Input files:}
35 _hypre_parcsr_ls.h
36
37 @return Error code.
38
39 @param comm [IN]
40 MPI Communicator
41 @param local_num_variables [IN]
42 number of points on local processor
43 @param dof_func [IN]
44 array that contains the function numbers for all local points
45 @param CF_marker [IN]
46 marker array for coarse points
47 @param coarse_dof_func_ptr [OUT]
48 pointer to array which contains the function numbers for local coarse points
49 @param coarse_pnts_global_ptr [OUT]
50 pointer to array which contains the number of the first coarse point on each processor and the total number of coarse points in its last element
51
52 @see */
53 /*--------------------------------------------------------------------------*/
54
55 HYPRE_Int
hypre_BoomerAMGCoarseParmsHost(MPI_Comm comm,HYPRE_Int local_num_variables,HYPRE_Int num_functions,hypre_IntArray * dof_func,hypre_IntArray * CF_marker,hypre_IntArray ** coarse_dof_func_ptr,HYPRE_BigInt ** coarse_pnts_global_ptr)56 hypre_BoomerAMGCoarseParmsHost(MPI_Comm comm,
57 HYPRE_Int local_num_variables,
58 HYPRE_Int num_functions,
59 hypre_IntArray *dof_func,
60 hypre_IntArray *CF_marker,
61 hypre_IntArray **coarse_dof_func_ptr,
62 HYPRE_BigInt **coarse_pnts_global_ptr)
63 {
64 #ifdef HYPRE_PROFILE
65 hypre_profile_times[HYPRE_TIMER_ID_COARSE_PARAMS] -= hypre_MPI_Wtime();
66 #endif
67
68 HYPRE_Int i;
69 HYPRE_Int num_procs;
70 HYPRE_BigInt local_coarse_size = 0;
71
72 HYPRE_Int *coarse_dof_func;
73 HYPRE_BigInt *coarse_pnts_global;
74
75 /*--------------------------------------------------------------
76 *----------------------------------------------------------------*/
77
78 hypre_MPI_Comm_size(comm,&num_procs);
79
80 for (i = 0; i < local_num_variables; i++)
81 {
82 if (hypre_IntArrayData(CF_marker)[i] == 1)
83 {
84 local_coarse_size++;
85 }
86 }
87 if (num_functions > 1)
88 {
89 *coarse_dof_func_ptr = hypre_IntArrayCreate(local_coarse_size);
90 hypre_IntArrayInitialize(*coarse_dof_func_ptr);
91 coarse_dof_func = hypre_IntArrayData(*coarse_dof_func_ptr);
92
93 local_coarse_size = 0;
94 for (i = 0; i < local_num_variables; i++)
95 {
96 if (hypre_IntArrayData(CF_marker)[i] == 1)
97 {
98 coarse_dof_func[local_coarse_size++] = hypre_IntArrayData(dof_func)[i];
99 }
100 }
101 }
102
103 {
104 HYPRE_BigInt scan_recv;
105
106 coarse_pnts_global = hypre_CTAlloc(HYPRE_BigInt, 2, HYPRE_MEMORY_HOST);
107 hypre_MPI_Scan(&local_coarse_size, &scan_recv, 1, HYPRE_MPI_BIG_INT, hypre_MPI_SUM, comm);
108
109 /* first point in my range */
110 coarse_pnts_global[0] = scan_recv - local_coarse_size;
111
112 /* first point in next proc's range */
113 coarse_pnts_global[1] = scan_recv;
114 }
115
116 if (*coarse_pnts_global_ptr)
117 {
118 hypre_TFree(*coarse_pnts_global_ptr, HYPRE_MEMORY_HOST);
119 }
120 *coarse_pnts_global_ptr = coarse_pnts_global;
121
122 #ifdef HYPRE_PROFILE
123 hypre_profile_times[HYPRE_TIMER_ID_COARSE_PARAMS] += hypre_MPI_Wtime();
124 #endif
125
126 return hypre_error_flag;
127 }
128
129 HYPRE_Int
hypre_BoomerAMGCoarseParms(MPI_Comm comm,HYPRE_Int local_num_variables,HYPRE_Int num_functions,hypre_IntArray * dof_func,hypre_IntArray * CF_marker,hypre_IntArray ** coarse_dof_func_ptr,HYPRE_BigInt ** coarse_pnts_global_ptr)130 hypre_BoomerAMGCoarseParms(MPI_Comm comm,
131 HYPRE_Int local_num_variables,
132 HYPRE_Int num_functions,
133 hypre_IntArray *dof_func,
134 hypre_IntArray *CF_marker,
135 hypre_IntArray **coarse_dof_func_ptr,
136 HYPRE_BigInt **coarse_pnts_global_ptr)
137 {
138 HYPRE_Int ierr = 0;
139
140 #if defined(HYPRE_USING_CUDA) || defined(HYPRE_USING_HIP)
141 HYPRE_ExecutionPolicy exec = hypre_GetExecPolicy1(hypre_IntArrayMemoryLocation(CF_marker));
142 if (num_functions > 1)
143 {
144 exec = hypre_GetExecPolicy2(hypre_IntArrayMemoryLocation(CF_marker), hypre_IntArrayMemoryLocation(dof_func));
145 }
146
147 if (exec == HYPRE_EXEC_DEVICE)
148 {
149 ierr = hypre_BoomerAMGCoarseParmsDevice(comm, local_num_variables, num_functions, dof_func,
150 CF_marker, coarse_dof_func_ptr, coarse_pnts_global_ptr);
151 }
152 else
153 #endif
154 {
155 ierr = hypre_BoomerAMGCoarseParmsHost(comm, local_num_variables, num_functions, dof_func,
156 CF_marker, coarse_dof_func_ptr, coarse_pnts_global_ptr);
157 }
158
159 return ierr;
160 }
161