37 using impl_scalar_type =
typename KokkosKernels::ArithTraits<Scalar>::val_type;
39 using exec_space =
typename Node::execution_space;
40 using memory_space =
typename Node::memory_space;
41 using range_policy = Kokkos::RangePolicy<exec_space>;
43 Kokkos::View<impl_scalar_type *, memory_space> a(
"a", VECTOR_SIZE);
44 Kokkos::View<impl_scalar_type *, memory_space> b(
"b", VECTOR_SIZE);
45 Kokkos::View<impl_scalar_type *, memory_space> c(
"c", VECTOR_SIZE);
46 double total_test_time = 0.0;
48 impl_scalar_type ONE = Teuchos::ScalarTraits<impl_scalar_type>::one();
51 "stream/fill", range_policy(0, VECTOR_SIZE), KOKKOS_LAMBDA(
const size_t i) {
52 a(i) = ONE * (double)i;
57 using clock = std::chrono::high_resolution_clock;
59 clock::time_point start, stop;
61 for (
int i = 0; i < KERNEL_REPEATS; i++) {
64 "stream/add", range_policy(0, VECTOR_SIZE), KOKKOS_LAMBDA(
const size_t j) {
70 double my_test_time = std::chrono::duration<double>(stop - start).count();
71 total_test_time += my_test_time;
74 return total_test_time / KERNEL_REPEATS;
80 using impl_scalar_type =
typename KokkosKernels::ArithTraits<Scalar>::val_type;
82 using exec_space =
typename Node::execution_space;
83 using memory_space =
typename Node::memory_space;
84 using range_policy = Kokkos::RangePolicy<exec_space>;
86 Kokkos::View<impl_scalar_type *, memory_space> a(
"a", VECTOR_SIZE);
87 Kokkos::View<impl_scalar_type *, memory_space> b(
"b", VECTOR_SIZE);
88 double total_test_time = 0.0;
90 impl_scalar_type ONE = Teuchos::ScalarTraits<impl_scalar_type>::one();
93 "stream/fill", range_policy(0, VECTOR_SIZE), KOKKOS_LAMBDA(
const size_t i) {
98 using clock = std::chrono::high_resolution_clock;
99 clock::time_point start, stop;
101 for (
int i = 0; i < KERNEL_REPEATS; i++) {
102 start = clock::now();
103 Kokkos::parallel_for(
104 "stream/copy", range_policy(0, VECTOR_SIZE), KOKKOS_LAMBDA(
const size_t j) {
108 exec_space().fence();
110 double my_test_time = std::chrono::duration<double>(stop - start).count();
111 total_test_time += my_test_time;
114 return total_test_time / KERNEL_REPEATS;
165 int rank = comm.getRank();
166 int nproc = comm.getSize();
168 if (nproc < 2)
return;
170 const int buff_size = (int)pow(2, MAX_SIZE);
172 sizes.resize(MAX_SIZE + 1);
173 times.resize(MAX_SIZE + 1);
176 Kokkos::View<char *, memory_space> r_buf(
"recv", buff_size), s_buf(
"send", buff_size);
177 Kokkos::deep_copy(s_buf, 1);
182 int buddy = odd ? rank - 1 : rank + 1;
184 for (
int i = 0; i < MAX_SIZE + 1; i++) {
185 int msg_size = (int)pow(2, i);
188 double t0 = MPI_Wtime();
189 for (
int j = 0; j < KERNEL_REPEATS; j++) {
192 comm.send(msg_size, (
char *)s_buf.data(), buddy);
193 comm.receive(buddy, msg_size, (
char *)r_buf.data());
195 comm.receive(buddy, msg_size, (
char *)r_buf.data());
196 comm.send(msg_size, (
char *)s_buf.data(), buddy);
201 double time_per_call = (MPI_Wtime() - t0) / (2.0 * KERNEL_REPEATS);
203 times[i] = time_per_call;
211void halopong_basic(
int KERNEL_REPEATS,
int MAX_SIZE,
const RCP<
const Xpetra::Import<LocalOrdinal, GlobalOrdinal, Node> > &
import, std::vector<int> &sizes, std::vector<double> ×) {
212 int nproc =
import->getSourceMap()->getComm()->getSize();
213 if (nproc < 2)
return;
214#if defined(HAVE_MUELU_TPETRA) && defined(HAVE_MPI)
217 using x_import_type = Xpetra::TpetraImport<LocalOrdinal, GlobalOrdinal, Node>;
218 RCP<const x_import_type> Ximport = Teuchos::rcp_dynamic_cast<const x_import_type>(
import);
219 RCP<const Teuchos::MpiComm<int> > mcomm = Teuchos::rcp_dynamic_cast<const Teuchos::MpiComm<int> >(
import->getSourceMap()->getComm());
220 MPI_Comm communicator = *mcomm->getRawMpiComm();
222 if (Ximport.is_null() || mcomm.is_null())
return;
223 auto Timport = Ximport->getTpetra_Import();
224 auto distor = Timport->getDistributor();
227 Teuchos::ArrayView<const int> procsFrom = distor.getProcsFrom();
228 Teuchos::ArrayView<const int> procsTo = distor.getProcsTo();
229 int num_recvs = (int)distor.getNumReceives();
230 int num_sends = (int)distor.getNumSends();
232 const int buff_size_per_msg = (int)pow(2, MAX_SIZE);
233 sizes.resize(MAX_SIZE + 1);
234 times.resize(MAX_SIZE + 1);
237 Kokkos::View<char *, memory_space> f_recv_buf(
"forward_recv", buff_size_per_msg * num_recvs), f_send_buf(
"forward_send", buff_size_per_msg * num_sends);
238 Kokkos::View<char *, memory_space> r_recv_buf(
"reverse_recv", buff_size_per_msg * num_sends), r_send_buf(
"reverse_send", buff_size_per_msg * num_recvs);
239 Kokkos::deep_copy(f_send_buf, 1);
240 Kokkos::deep_copy(r_send_buf, 1);
242 std::vector<MPI_Request> requests(num_sends + num_recvs);
243 std::vector<MPI_Status> status(num_sends + num_recvs);
245 for (
int i = 0; i < MAX_SIZE + 1; i++) {
246 int msg_size = (int)pow(2, i);
248 MPI_Barrier(communicator);
250 double t0 = MPI_Wtime();
251 for (
int j = 0; j < KERNEL_REPEATS; j++) {
254 for (
int r = 0; r < num_recvs; r++) {
255 const int tag = 1000 + j;
256 MPI_Irecv(f_recv_buf.data() + msg_size * r, msg_size, MPI_CHAR, procsFrom[r], tag, communicator, &requests[ct]);
259 for (
int s = 0; s < num_sends; s++) {
260 const int tag = 1000 + j;
261 MPI_Isend(f_send_buf.data() + msg_size * s, msg_size, MPI_CHAR, procsTo[s], tag, communicator, &requests[ct]);
265 MPI_Waitall(ct, requests.data(), status.data());
269 for (
int r = 0; r < num_sends; r++) {
270 const int tag = 2000 + j;
271 MPI_Irecv(r_recv_buf.data() + msg_size * r, msg_size, MPI_CHAR, procsTo[r], tag, communicator, &requests[ct]);
274 for (
int s = 0; s < num_recvs; s++) {
275 const int tag = 2000 + j;
276 MPI_Isend(r_send_buf.data() + msg_size * s, msg_size, MPI_CHAR, procsFrom[s], tag, communicator, &requests[ct]);
280 MPI_Waitall(ct, requests.data(), status.data());
283 double time_per_call = (MPI_Wtime() - t0) / (2.0 * KERNEL_REPEATS);
285 times[i] = time_per_call;