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