27#include <alien/kernels/sycl/data/SYCLEnvInternal.h>
28#include <alien/kernels/sycl/data/SYCLEnv.h>
30#include <alien/kernels/sycl/data/SYCLVectorInternal.h>
31#include <alien/kernels/sycl/data/SYCLVector.h>
33#include <alien/kernels/sycl/data/SYCLBEllPackInternal.h>
34#include <alien/kernels/sycl/data/SYCLBEllPackMatrix.h>
43 SYCLInternal::EnvInternal::printPlatformInfo() ;
44 m_internal.reset(
new SYCLInternal::EnvInternal{});
47SYCLEnv::SYCLEnv(
int device_id)
49 SYCLInternal::EnvInternal::printPlatformInfo() ;
50 auto gpu_devices = sycl::device::get_devices(sycl::info::device_type::gpu);
51 if(device_id < gpu_devices.size())
53 sycl::device selected_device = gpu_devices[device_id];
54 m_internal.reset(
new SYCLInternal::EnvInternal{selected_device,device_id});
57 m_internal.reset(
new SYCLInternal::EnvInternal{});
65SYCLEnv* SYCLEnv::m_instance =
nullptr;
70 m_instance =
new SYCLEnv{};
74SYCLEnv* SYCLEnv::instance(
int device_id)
77 m_instance =
new SYCLEnv{device_id};
78 if (m_instance->deviceId()!= device_id)
81 m_instance =
new SYCLEnv{device_id};
86int SYCLEnv::deviceId()
88 return m_internal->deviceId() ;
91std::size_t SYCLEnv::maxNumGroups()
93 return m_internal->maxNumGroups();
96std::size_t SYCLEnv::maxWorkGroupSize()
98 return m_internal->maxWorkGroupSize();
101std::size_t SYCLEnv::maxNumThreads()
103 return m_internal->maxNumThreads();
106template <
int EllpackSize,
typename IndexT>
107void BEllPackStructInfo<EllpackSize, IndexT>::computeBlockRowOffset(std::vector<int>& block_row_offset,
111 std::size_t block_nrows = BEllPackStructInfo<EllpackSize, IndexT>::nbBlocks(nrows);
112 block_row_offset.resize(block_nrows + 1);
114 for (std::size_t ib = 0; ib < block_nrows; ++ib) {
115 block_row_offset[ib] = offset;
116 int max_row_size = 0;
117 for (
int i = 0; i < std::min(EllpackSize,
int(nrows - ib * EllpackSize)); ++i) {
118 auto irow = ib * EllpackSize + i;
119 int row_size = kcol[irow + 1] - kcol[irow];
120 max_row_size = std::max(max_row_size, row_size);
122 offset += max_row_size;
124 block_row_offset[block_nrows] = offset;
127template <
int EllpackSize,
typename IndexT>
131 std::size_t block_nrows,
132 std::size_t block_nnz,
135 int const* h_block_row_offset,
136 int const* h_local_row_size)
139, m_block_nrows(block_nrows)
140, m_block_nnz(block_nnz)
141, m_h_kcol(h_kcol, h_kcol + nrows + 1)
142, m_h_cols(h_cols, h_cols + nnz)
143, m_h_block_cols(block_nnz * ellpack_size)
144, m_block_row_offset(h_block_row_offset, sycl::range<1>(m_block_nrows + 1))
145, m_block_cols(m_h_block_cols.data(), sycl::range<1>(m_block_nnz * ellpack_size))
146, m_kcol(m_h_kcol.data(), sycl::range<1>(m_nrows + 1))
148 auto env = SYCLEnv::instance();
150 auto& queue = env->internal()->queue();
152 auto num_groups = env->internal()->maxNumGroups();
154 auto max_work_group_size = env->internal()->maxWorkGroupSize();
157 auto total_threads = num_groups * ellpack_size;
160 if(h_local_row_size==
nullptr)
162 IndexBufferType cols_buffer(m_h_cols.data(), sycl::range<1>(m_nnz));
164 queue.submit([&](sycl::handler& cgh)
166 auto access_kcol_buffer = m_kcol.template get_access<sycl::access::mode::read>(cgh);
167 auto access_block_row_offset = m_block_row_offset.template get_access<sycl::access::mode::read>(cgh);
169 auto access_cols_buffer = cols_buffer.template get_access<sycl::access::mode::read>(cgh);
170 auto access_block_cols = m_block_cols.template get_access<sycl::access::mode::discard_write>(cgh);
172 cgh.parallel_for<
class struct_info_sycl>(sycl::range<1>{total_threads},
173 [=] (sycl::item<1> itemId)
175 auto id = itemId.get_id(0);
177 for (
auto i =
id; i < nrows; i += itemId.get_range()[0])
179 auto block_id = i/ellpack_size ;
180 auto local_id = i%ellpack_size ;
182 int begin = access_kcol_buffer[i] ;
183 int end = access_kcol_buffer[i+1] ;
184 int row_size = end - begin ;
186 int block_row_offset = access_block_row_offset[block_id]*ellpack_size ;
187 auto block_row_size = access_block_row_offset[block_id+1]-access_block_row_offset[block_id] ;
196 for(
int k=begin;k<end;++k)
198 access_block_cols[block_row_offset+(k-begin)*ellpack_size+local_id] = access_cols_buffer[k] ;
200 for(
int k=row_size;k<block_row_size;++k)
202 access_block_cols[block_row_offset+k*ellpack_size+local_id] = -1 ;
211 IndexBufferType cols_buffer(m_h_cols.data(), sycl::range<1>(m_nnz));
212 IndexBufferType lrowsize_buffer(h_local_row_size, sycl::range<1>(nrows));
214 queue.submit([&](sycl::handler& cgh)
216 auto access_kcol_buffer = m_kcol.template get_access<sycl::access::mode::read>(cgh);
217 auto access_block_row_offset = m_block_row_offset.template get_access<sycl::access::mode::read>(cgh);
218 auto access_lrowsize_buffer = lrowsize_buffer.template get_access<sycl::access::mode::read>(cgh);
220 auto access_cols_buffer = cols_buffer.template get_access<sycl::access::mode::read>(cgh);
221 auto access_block_cols = m_block_cols.template get_access<sycl::access::mode::discard_write>(cgh);
223 cgh.parallel_for<
class struct_info_sycl2>(sycl::range<1>{total_threads},
224 [=] (sycl::item<1> itemId)
226 auto id = itemId.get_id(0);
228 for (
auto i =
id; i < nrows; i += itemId.get_range()[0])
230 auto block_id = i/ellpack_size ;
231 auto local_id = i%ellpack_size ;
233 int begin = access_kcol_buffer[i] ;
234 int lrow_size = access_lrowsize_buffer[i] ;
236 int block_row_offset = access_block_row_offset[block_id]*ellpack_size ;
237 auto block_row_size = access_block_row_offset[block_id+1]-access_block_row_offset[block_id] ;
239 for(
int k=begin;k<begin+lrow_size;++k)
241 access_block_cols[block_row_offset+(k-begin)*ellpack_size+local_id] = access_cols_buffer[k] ;
243 for(
int k=lrow_size;k<block_row_size;++k)
245 access_block_cols[block_row_offset+k*ellpack_size+local_id] = -1 ;
254template <
int EllpackSize,
typename IndexT>
255void SYCLInternal::StructInfoInternal<EllpackSize, IndexT>::getUpperDiagOffset()
const
257 if (m_h_dcol.size() == 0) {
258 m_h_dcol.resize(m_nrows);
259 for (std::size_t irow = 0; irow < m_nrows; ++irow) {
260 int index = m_h_kcol[irow];
261 for (
int k = m_h_kcol[irow]; k < m_h_kcol[irow + 1]; ++k) {
262 if ((std::size_t)m_h_cols[k] < irow)
267 m_h_dcol[irow] = index;
272template <
int EllpackSize,
typename IndexT>
273void SYCLInternal::StructInfoInternal<EllpackSize, IndexT>::computeLowerUpperMask()
const
276 if (not m_lower_upper_mask_ready) {
277 m_lower_mask.reset(
new MaskBufferType(sycl::range<1>(m_block_nnz * ellpack_size)));
278 m_upper_mask.reset(
new MaskBufferType(sycl::range<1>(m_block_nnz * ellpack_size)));
280 auto env = SYCLEnv::instance();
282 auto& queue = env->internal()->queue();
284 auto num_groups = env->internal()->maxNumGroups();
286 auto max_work_group_size = env->internal()->maxWorkGroupSize();
289 auto total_threads = num_groups * ellpack_size;
292 IndexBufferType dcol_buffer(m_h_dcol.data(), sycl::range<1>(m_nrows));
294 auto nrows = m_nrows;
297 queue.submit([&](sycl::handler& cgh)
299 auto access_dcol_buffer = dcol_buffer.template get_access<sycl::access::mode::read>(cgh);
301 auto access_kcol_buffer = m_kcol.template get_access<sycl::access::mode::read>(cgh);
302 auto access_block_row_offset = m_block_row_offset.template get_access<sycl::access::mode::read>(cgh);
304 auto access_lower_mask = sycl::accessor { *m_lower_mask, cgh, sycl::write_only, sycl::property::no_init{}};
305 auto access_upper_mask = sycl::accessor { *m_upper_mask, cgh, sycl::write_only, sycl::property::no_init{}};
308 cgh.parallel_for<
class lower_upper_mask>(sycl::range<1>{total_threads},
309 [=] (sycl::item<1> itemId)
311 auto id = itemId.get_id(0);
313 for (
auto i =
id; i < nrows; i += itemId.get_range()[0])
315 auto block_id = i/ellpack_size ;
316 auto local_id = i%ellpack_size ;
318 int begin = access_kcol_buffer[i] ;
319 int end = access_kcol_buffer[i+1] ;
320 int diag = access_dcol_buffer[i] ;
321 int row_size = end - begin ;
323 int block_row_offset = access_block_row_offset[block_id]*ellpack_size ;
324 auto block_row_size = access_block_row_offset[block_id+1]-access_block_row_offset[block_id] ;
326 access_lower_mask[block_row_offset+(diag-begin)*ellpack_size+local_id] = 0 ;
327 access_upper_mask[block_row_offset+(diag-begin)*ellpack_size+local_id] = 0 ;
329 for(
int k=begin;k<diag;++k)
331 access_lower_mask[block_row_offset+(k-begin)*ellpack_size+local_id] = 1 ;
332 access_upper_mask[block_row_offset+(k-begin)*ellpack_size+local_id] = 0 ;
334 for(
int k=diag+1;k<end;++k)
336 access_lower_mask[block_row_offset+(k-begin)*ellpack_size+local_id] = 0 ;
337 access_upper_mask[block_row_offset+(k-begin)*ellpack_size+local_id] = 1 ;
339 for(
int k=row_size;k<block_row_size;++k)
341 access_lower_mask[block_row_offset+k*ellpack_size+local_id] = 0 ;
342 access_upper_mask[block_row_offset+k*ellpack_size+local_id] = 0 ;
350 m_lower_upper_mask_ready =
true;
354template <
int EllpackSize,
typename IndexT>
355typename SYCLInternal::StructInfoInternal<EllpackSize, IndexT>::MaskBufferType&
356SYCLInternal::StructInfoInternal<EllpackSize, IndexT>::getLowerMask()
const
358 computeLowerUpperMask();
359 return *m_lower_mask;
362template <
int EllpackSize,
typename IndexT>
363typename SYCLInternal::StructInfoInternal<EllpackSize, IndexT>::MaskBufferType&
364SYCLInternal::StructInfoInternal<EllpackSize, IndexT>::getUpperMask()
const
366 computeLowerUpperMask();
367 return *m_upper_mask;
370template <
int EllpackSize,
typename IndexT>
371BEllPackStructInfo<EllpackSize, IndexT>::BEllPackStructInfo(std::size_t nrows,
374 int const* h_block_row_offset,
375 int const* h_local_row_size)
377: BaseBEllPackStructInfo(nrows, kcol[nrows])
378, m_block_nrows(BEllPackStructInfo<EllpackSize, IndexT>::nbBlocks(nrows))
379, m_block_nnz(h_block_row_offset[m_block_nrows])
380, m_h_local_row_size(h_local_row_size)
384 cout() <<
"COMPUTE BELLPACK PROFILE";
385 cout() <<
" NROWS : "<<this->m_nrows;
386 cout() <<
" NNZ : "<<this->m_nnz;
387 cout() <<
" BLOCK NROWS : "<<m_block_nrows;
388 cout() <<
" BLOCK NNZ : "<<m_block_nnz;
393 m_internal =
new InternalType{ this->m_nrows,
403template <
int EllpackSize,
typename IndexT>
404BEllPackStructInfo<EllpackSize, IndexT>::~BEllPackStructInfo()
409template <
int EllpackSize,
typename IndexT>
410typename BEllPackStructInfo<EllpackSize, IndexT>::IndexType
const*
411BEllPackStructInfo<EllpackSize, IndexT>::kcol()
const
413 return m_internal->kcol();
416template <
int EllpackSize,
typename IndexT>
417typename BEllPackStructInfo<EllpackSize, IndexT>::IndexType
const*
418BEllPackStructInfo<EllpackSize, IndexT>::cols()
const
420 return m_internal->cols();
423template <
int EllpackSize,
typename IndexT>
424typename BEllPackStructInfo<EllpackSize, IndexT>::IndexType
const*
425BEllPackStructInfo<EllpackSize, IndexT>::dcol()
const
427 return m_internal->dcol();
430namespace SYCLInternal
432 template <
typename ValueT,
int EllpackSize>
433 MatrixInternal<ValueT, EllpackSize>::MatrixInternal(ProfileType
const* profile,
int N)
437 , m_h_values(profile->getBlockNnz() * ellpack_size * N*N)
438 , m_values(m_h_values.data(), sycl::range<1>(profile->getBlockNnz() * ellpack_size * N*N))
444 template <
typename ValueT,
int EllpackSize>
445 bool MatrixInternal<ValueT, EllpackSize>::setMatrixValuesFromHost()
448 auto env = SYCLEnv::instance();
449 auto& queue = env->internal()->queue();
450 auto num_groups = env->internal()->maxNumGroups();
451 auto max_work_group_size = env->internal()->maxWorkGroupSize();
452 auto total_threads = num_groups * ellpack_size;
455 int NxN = this->m_NxN;
456 int pack_size = ellpack_size ;
457 auto nrows = m_profile->getNRows();
458 auto nnz = m_profile->getNnz();
459 auto block_nnz = m_profile->getBlockNnz();
461 auto internal_profile = m_profile->internal();
462 auto& kcol = internal_profile->getKCol();
463 auto& block_row_offset = internal_profile->getBlockRowOffset();
464 auto& block_cols = internal_profile->getBlockCols();
465 auto local_row_size = m_profile->localRowSize();
468 if (local_row_size ==
nullptr)
470 assert(m_h_csr_values.size()>=nnz) ;
471 ValueBufferType values_buffer(m_h_csr_values.data(), sycl::range<1>(nnz));
474 queue.submit([&](sycl::handler& cgh)
476 auto access_kcol_buffer = kcol.template get_access<sycl::access::mode::read>(cgh);
477 auto access_block_row_offset = block_row_offset.template get_access<sycl::access::mode::read>(cgh);
478 auto access_values_buffer = values_buffer.template get_access<sycl::access::mode::read>(cgh);
479 auto access_block_values = m_values.template get_access<sycl::access::mode::read_write>(cgh);
482 cgh.parallel_for<
class set_matrix_values>(
483 sycl::range<1>{total_threads},
484 [=] (sycl::item<1> item_id)
486 auto id = item_id.get_id(0);
491 for (
auto i =
id; i < nrows; i += item_id.get_range()[0])
493 auto block_id = i/ellpack_size ;
494 auto local_id = i%ellpack_size ;
496 auto begin = access_kcol_buffer[i] ;
497 auto end = access_kcol_buffer[i+1] ;
498 auto row_size = end - begin ;
500 int block_row_offset = access_block_row_offset[block_id];
501 auto block_row_size = access_block_row_offset[block_id+1]-access_block_row_offset[block_id] ;
503 for(
int k=0;k<row_size;++k)
505 access_block_values[(block_row_offset+k)*ellpack_size+local_id] = access_values_buffer[begin+k] ;
507 for(
int k=row_size;k<block_row_size;++k)
509 access_block_values[(block_row_offset+k)*ellpack_size+local_id] = 0 ;
515 m_values_is_update =
true;
519 ValueBufferType values_buffer(m_h_csr_values.data(), sycl::range<1>(nnz));
520 IndexBufferType lrowsize_buffer(local_row_size, sycl::range<1>(nrows));
523 queue.submit([&](sycl::handler& cgh)
525 auto access_kcol_buffer = internal_profile->getKCol().template get_access<sycl::access::mode::read>(cgh);
526 auto access_lrowsize_buffer = lrowsize_buffer.template get_access<sycl::access::mode::read>(cgh);
528 auto access_block_row_offset = internal_profile->getBlockRowOffset().template get_access<sycl::access::mode::read>(cgh);
529 auto access_values_buffer = values_buffer.template get_access<sycl::access::mode::read>(cgh);
530 auto access_block_values = m_values.template get_access<sycl::access::mode::read_write>(cgh);
533 cgh.parallel_for<
class set_matrix_values2>(
534 sycl::range<1>{total_threads},
535 [=] (sycl::item<1> item_id)
537 auto id = item_id.get_id(0);
542 for (
auto i =
id; i < nrows; i += item_id.get_range()[0])
544 auto block_id = i/pack_size ;
545 auto local_id = i%pack_size ;
547 auto begin = access_kcol_buffer[i] ;
548 auto lrow_size = access_lrowsize_buffer[i] ;
549 auto end = begin + lrow_size ;
551 int block_row_offset = access_block_row_offset[block_id];
552 auto block_row_size = access_block_row_offset[block_id+1]-access_block_row_offset[block_id] ;
554 for(
int k=0;k<lrow_size;++k)
556 access_block_values[(block_row_offset+k)*pack_size+local_id] = access_values_buffer[begin+k] ;
558 for(
int k=lrow_size;k<block_row_size;++k)
560 access_block_values[(block_row_offset+k)*pack_size+local_id] = 0. ;
566 auto interface_nrows = m_ext_profile->getNRows();
567 auto ext_nnz = m_ext_profile->getNnz();
568 auto ext_block_nnz = m_ext_profile->getBlockNnz();
570 auto ext_internal_profile = m_ext_profile->internal();
571 auto& ext_kcol = ext_internal_profile->getKCol();
572 auto& ext_block_row_offset = ext_internal_profile->getBlockRowOffset();
574 m_ext_values.reset(
new ValueBufferType(ext_block_nnz * ellpack_size * NxN)) ;
576 ValueBufferType ext_csr_values_buffer(m_h_csr_ext_values.data(), sycl::range<1>(ext_nnz * NxN));
577 queue.submit([&](sycl::handler& cgh)
579 auto access_kcol_buffer = ext_kcol.template get_access<sycl::access::mode::read>(cgh);
580 auto access_block_row_offset = ext_block_row_offset.template get_access<sycl::access::mode::read>(cgh);
581 auto access_values_buffer = ext_csr_values_buffer.template get_access<sycl::access::mode::read>(cgh);
583 auto access_block_values = sycl::accessor { *m_ext_values, cgh, sycl::write_only, sycl::property::no_init{}};
585 cgh.parallel_for<
class set_matrix_values3>(
586 sycl::range<1>{total_threads},
587 [=] (sycl::item<1> item_id)
589 auto id = item_id.get_id(0);
591 for (
auto i =
id; i < interface_nrows; i += item_id.get_range()[0])
593 auto block_id = i/ellpack_size ;
594 auto local_id = i%ellpack_size ;
595 auto begin = access_kcol_buffer[i] ;
596 auto end = access_kcol_buffer[i+1] ;
597 auto row_size = end - begin ;
599 int block_row_offset = access_block_row_offset[block_id]*ellpack_size*NxN ;
600 auto block_row_size = access_block_row_offset[block_id+1]-access_block_row_offset[block_id] ;
602 for(
int k=begin*NxN;k<end*NxN;++k)
604 access_block_values[block_row_offset+(k-begin*NxN)*ellpack_size+local_id] = access_values_buffer[k] ;
606 for(
int k=row_size*NxN;k<block_row_size*NxN;++k)
608 access_block_values[block_row_offset+k*ellpack_size+local_id] = 0 ;
615 m_values_is_update =
true;
620 if (local_row_size ==
nullptr)
622 assert(m_h_csr_values.size()>=nnz*NxN) ;
623 ValueBufferType values_buffer(m_h_csr_values.data(), sycl::range<1>(nnz*NxN));
626 queue.submit([&](sycl::handler& cgh)
628 auto access_kcol_buffer = kcol.template get_access<sycl::access::mode::read>(cgh);
629 auto access_cols_buffer = block_cols.template get_access<sycl::access::mode::read>(cgh);
630 auto access_block_row_offset = block_row_offset.template get_access<sycl::access::mode::read>(cgh);
631 auto access_values_buffer = values_buffer.template get_access<sycl::access::mode::read>(cgh);
632 auto access_block_values = m_values.template get_access<sycl::access::mode::read_write>(cgh);
635 cgh.parallel_for<
class set_block_matrix_values>(
636 sycl::range<1>{total_threads},
637 [=] (sycl::item<1> item_id)
639 auto id = item_id.get_id(0);
644 for (std::size_t i =
id; i < nrows; i += item_id.get_range()[0])
646 auto block_id = i/pack_size ;
647 auto local_id = i%pack_size ;
649 int begin = access_kcol_buffer[i] ;
650 int end = access_kcol_buffer[i+1] ;
651 int row_size = end - begin ;
653 int block_row_offset = access_block_row_offset[block_id] ;
654 int block_row_size = access_block_row_offset[block_id+1]-access_block_row_offset[block_id] ;
656 for(
int k=0;k<row_size;++k)
661 access_block_values[((block_row_offset+k)*NxN+i*N+j)*pack_size+local_id] = access_values_buffer[(begin+k)*NxN + i*N+j] ;
667 for(
int k=row_size;k<block_row_size;++k)
672 access_block_values[((block_row_offset+k)*NxN + i*N+j)*pack_size+local_id] = 0. ;
679 m_values_is_update =
true;
717 ValueBufferType values_buffer(m_h_csr_values.data(), sycl::range<1>(nnz*NxN));
718 IndexBufferType lrowsize_buffer(local_row_size, sycl::range<1>(nrows));
721 queue.submit([&](sycl::handler& cgh)
723 auto access_kcol_buffer = internal_profile->getKCol().template get_access<sycl::access::mode::read>(cgh);
724 auto access_lrowsize_buffer = lrowsize_buffer.template get_access<sycl::access::mode::read>(cgh);
726 auto access_block_row_offset = internal_profile->getBlockRowOffset().template get_access<sycl::access::mode::read>(cgh);
727 auto access_values_buffer = values_buffer.template get_access<sycl::access::mode::read>(cgh);
728 auto access_block_values = m_values.template get_access<sycl::access::mode::read_write>(cgh);
731 cgh.parallel_for<
class set_block_matrix_values2>(
732 sycl::range<1>{total_threads},
733 [=] (sycl::item<1> item_id)
735 auto id = item_id.get_id(0);
740 for (
auto i =
id; i < nrows; i += item_id.get_range()[0])
742 auto block_id = i/pack_size ;
743 auto local_id = i%pack_size ;
745 auto begin = access_kcol_buffer[i] ;
746 auto lrow_size = access_lrowsize_buffer[i] ;
747 auto end = begin + lrow_size ;
749 auto block_row_offset = access_block_row_offset[block_id];
750 auto block_row_size = access_block_row_offset[block_id+1]-access_block_row_offset[block_id] ;
752 for(
int k=0;k<lrow_size;++k)
757 access_block_values[((block_row_offset+k)*NxN+i*N+j)*pack_size+local_id] = access_values_buffer[(begin+k)*NxN+i*N+j] ;
760 for(
int k=lrow_size;k<block_row_size;++k)
765 access_block_values[((block_row_offset+k)*NxN+i*N+j)*pack_size+local_id] = 0. ;
773 auto interface_nrows = m_ext_profile->getNRows();
774 auto ext_nnz = m_ext_profile->getNnz();
775 auto ext_block_nnz = m_ext_profile->getBlockNnz();
777 auto ext_internal_profile = m_ext_profile->internal();
778 auto& ext_kcol = ext_internal_profile->getKCol();
779 auto& ext_block_row_offset = ext_internal_profile->getBlockRowOffset();
781 m_ext_values.reset(
new ValueBufferType(ext_block_nnz * ellpack_size * NxN)) ;
783 ValueBufferType ext_csr_values_buffer(m_h_csr_ext_values.data(), sycl::range<1>(ext_nnz * NxN));
784 queue.submit([&](sycl::handler& cgh)
786 auto access_kcol_buffer = ext_kcol.template get_access<sycl::access::mode::read>(cgh);
787 auto access_block_row_offset = ext_block_row_offset.template get_access<sycl::access::mode::read>(cgh);
788 auto access_values_buffer = ext_csr_values_buffer.template get_access<sycl::access::mode::read>(cgh);
790 auto access_block_values = sycl::accessor { *m_ext_values, cgh, sycl::write_only, sycl::property::no_init{}};
792 cgh.parallel_for<
class set_matrix_values3>(
793 sycl::range<1>{total_threads},
794 [=] (sycl::item<1> item_id)
796 auto id = item_id.get_id(0);
798 for (
auto i =
id; i < interface_nrows; i += item_id.get_range()[0])
800 auto block_id = i/pack_size ;
801 auto local_id = i%pack_size ;
802 auto begin = access_kcol_buffer[i] ;
803 auto end = access_kcol_buffer[i+1] ;
804 auto row_size = end - begin ;
806 int block_row_offset = access_block_row_offset[block_id] ;
807 auto block_row_size = access_block_row_offset[block_id+1]-access_block_row_offset[block_id] ;
809 for(
int k=0;k<row_size;++k)
814 access_block_values[((block_row_offset+k)*NxN+i*N+j)*pack_size+local_id] = access_values_buffer[(begin+k)*NxN+i*N+j] ;
817 for(
int k=row_size;k<block_row_size;++k)
822 access_block_values[((block_row_offset+k)*NxN+i*N+j)*pack_size+local_id] = 0 ;
852 m_values_is_update =
true;
858 template <
typename ValueT,
int EllpackSize>
859 bool MatrixInternal<ValueT, EllpackSize>::setMatrixValues(ValueBufferType& values_buffer)
862 auto env = SYCLEnv::instance();
863 auto& queue = env->internal()->queue();
864 auto num_groups = env->internal()->maxNumGroups();
865 auto max_work_group_size = env->internal()->maxWorkGroupSize();
866 auto total_threads = num_groups * ellpack_size;
868 int NxN = this->m_NxN;
870 auto nrows = m_profile->getNRows();
871 auto nnz = m_profile->getNnz();
872 auto block_nnz = m_profile->getBlockNnz();
874 auto internal_profile = m_profile->internal();
875 auto& kcol = internal_profile->getKCol();
876 auto& block_row_offset = internal_profile->getBlockRowOffset();
878 auto local_row_size = m_profile->localRowSize();
879 if (local_row_size ==
nullptr)
884 queue.submit([&](sycl::handler& cgh)
886 auto access_kcol_buffer = internal_profile->getKCol().template get_access<sycl::access::mode::read>(cgh);
887 auto access_block_row_offset = internal_profile->getBlockRowOffset().template get_access<sycl::access::mode::read>(cgh);
888 auto access_values_buffer = values_buffer.template get_access<sycl::access::mode::read>(cgh);
889 auto access_block_values = m_values.template get_access<sycl::access::mode::read_write>(cgh);
892 cgh.parallel_for<
class set_matrix_values4>(sycl::range<1>{total_threads},
893 [=] (sycl::item<1> item_id)
895 auto id = item_id.get_id(0);
900 for (
auto i =
id; i < nrows; i += item_id.get_range()[0])
902 auto block_id = i/ellpack_size ;
903 auto local_id = i%ellpack_size ;
905 auto begin = access_kcol_buffer[i] ;
906 auto end = access_kcol_buffer[i+1] ;
907 auto row_size = end - begin ;
909 int block_row_offset = access_block_row_offset[block_id]*ellpack_size*NxN ;
910 auto block_row_size = access_block_row_offset[block_id+1]-access_block_row_offset[block_id] ;
912 for(
int k=begin*NxN;k<end*NxN;++k)
914 access_block_values[block_row_offset+(k-begin*NxN)*ellpack_size+local_id] = access_values_buffer[k] ;
916 for(
int k=row_size*NxN;k<block_row_size*NxN;++k)
918 access_block_values[block_row_offset+k*ellpack_size+local_id] = 0 ;
924 m_values_is_update =
true;
929 IndexBufferType lrowsize_buffer(local_row_size, sycl::range<1>(nrows));
933 queue.submit([&](sycl::handler& cgh)
935 auto access_kcol_buffer = internal_profile->getKCol().template get_access<sycl::access::mode::read>(cgh);
936 auto access_lrowsize_buffer = lrowsize_buffer.template get_access<sycl::access::mode::read>(cgh);
938 auto access_block_row_offset = internal_profile->getBlockRowOffset().template get_access<sycl::access::mode::read>(cgh);
939 auto access_values_buffer = values_buffer.template get_access<sycl::access::mode::read>(cgh);
940 auto access_block_values = m_values.template get_access<sycl::access::mode::read_write>(cgh);
943 cgh.parallel_for<
class set_matrix_values5>(sycl::range<1>{total_threads},
944 [=] (sycl::item<1> item_id)
946 auto id = item_id.get_id(0);
951 for (
auto i =
id; i < nrows; i += item_id.get_range()[0])
953 auto block_id = i/ellpack_size ;
954 auto local_id = i%ellpack_size ;
956 auto begin = access_kcol_buffer[i] ;
957 auto lrow_size = access_lrowsize_buffer[i] ;
958 auto end = begin + lrow_size ;
960 int block_row_offset = access_block_row_offset[block_id]*ellpack_size*NxN ;
961 auto block_row_size = access_block_row_offset[block_id+1]-access_block_row_offset[block_id] ;
963 for(
int k=begin*NxN;k<end*NxN;++k)
965 access_block_values[block_row_offset+(k-begin*NxN)*ellpack_size+local_id] = access_values_buffer[k] ;
967 for(
int k=lrow_size*NxN;k<block_row_size*NxN;++k)
969 access_block_values[block_row_offset+k*ellpack_size+local_id] = 0 ;
974 auto kcol = m_profile->kcol() ;
975 auto local_row_size = m_profile->localRowSize() ;
977 auto interface_nrows = m_ext_profile->getNRows();
978 auto ext_nnz = m_ext_profile->getNnz();
979 auto ext_block_nnz = m_ext_profile->getBlockNnz();
981 auto ext_internal_profile = m_ext_profile->internal();
982 auto& ext_kcol = ext_internal_profile->getKCol();
983 auto& ext_block_row_offset = ext_internal_profile->getBlockRowOffset();
985 m_ext_values.reset(
new ValueBufferType(ext_block_nnz * ellpack_size * NxN)) ;
989 ValueBufferType ext_csr_values_buffer(m_h_csr_ext_values.data(), sycl::range<1>(ext_nnz * NxN));
991 std::vector<Integer> h_local_row_offset(interface_nrows+1) ;
994 for(std::size_t i=0;i<interface_nrows;++i)
996 h_local_row_offset[i] = offset ;
997 offset += local_row_size[i] ;
999 h_local_row_offset[interface_nrows] = offset ;
1001 IndexBufferType local_row_offset(h_local_row_offset.data(),sycl::range<1>(interface_nrows+1)) ;
1003 queue.submit([&](sycl::handler& cgh)
1005 auto access_kcol = internal_profile->getKCol().template get_access<sycl::access::mode::read>(cgh);
1006 auto access_interface_row_ids = m_interface_row_ids->template get_access<sycl::access::mode::read>(cgh);
1007 auto access_local_row_size = lrowsize_buffer.template get_access<sycl::access::mode::read>(cgh);
1008 auto access_local_row_offset = local_row_offset.template get_access<sycl::access::mode::read>(cgh);
1009 auto access_csr_values = values_buffer.template get_access<sycl::access::mode::read>(cgh);
1010 auto access_ext_csr_values = ext_csr_values_buffer.template get_access<sycl::access::mode::read_write>(cgh);
1011 cgh.parallel_for<
class set_matrix_values6>(sycl::range<1>{total_threads},
1012 [=] (sycl::item<1> item_id)
1014 auto id = item_id.get_id(0);
1015 for (
auto i =
id; i < interface_nrows; i += item_id.get_range()[0])
1017 Integer jcol = access_local_row_offset[i] ;
1018 for (
int k = (access_kcol[i] + access_local_row_size[i])*NxN; k < access_kcol[i + 1] * NxN; ++k)
1019 access_ext_csr_values[jcol++] = access_csr_values[k];
1024 queue.submit([&](sycl::handler& cgh)
1026 auto access_kcol_buffer = ext_kcol.template get_access<sycl::access::mode::read>(cgh);
1027 auto access_block_row_offset = ext_block_row_offset.template get_access<sycl::access::mode::read>(cgh);
1028 auto access_values_buffer = ext_csr_values_buffer.template get_access<sycl::access::mode::read>(cgh);
1030 auto access_block_values = sycl::accessor { *m_ext_values, cgh, sycl::write_only, sycl::property::no_init{}};
1032 cgh.parallel_for<
class set_matrix_values7>(sycl::range<1>{total_threads},
1033 [=] (sycl::item<1> item_id)
1035 auto id = item_id.get_id(0);
1037 for (
auto i =
id; i < interface_nrows; i += item_id.get_range()[0])
1039 auto block_id = i/ellpack_size ;
1040 auto local_id = i%ellpack_size ;
1041 auto begin = access_kcol_buffer[i] ;
1042 auto end = access_kcol_buffer[i+1] ;
1043 auto row_size = end - begin ;
1045 int block_row_offset = access_block_row_offset[block_id]*ellpack_size*NxN ;
1046 auto block_row_size = access_block_row_offset[block_id+1]-access_block_row_offset[block_id] ;
1048 for(
int k=begin*NxN;k<end*NxN;++k)
1050 access_block_values[block_row_offset+(k-begin*NxN)*ellpack_size+local_id] = access_values_buffer[k] ;
1052 for(
int k=row_size*NxN;k<block_row_size*NxN;++k)
1054 access_block_values[block_row_offset+k*ellpack_size+local_id] = 0 ;
1061 m_values_is_update =
true;
1066 template <
typename ValueT,
int EllpackSize>
1067 bool MatrixInternal<ValueT, EllpackSize>::setMatrixValues(ValueBufferType& values_buffer,
1068 ValueBufferType& ext_values_buffer)
1071 auto env = SYCLEnv::instance();
1072 auto& queue = env->internal()->queue();
1073 auto num_groups = env->internal()->maxNumGroups();
1074 auto max_work_group_size = env->internal()->maxWorkGroupSize();
1075 auto total_threads = num_groups * ellpack_size;
1077 int NxN = this->m_NxN;
1079 auto nrows = m_profile->getNRows();
1080 auto nnz = m_profile->getNnz();
1081 auto block_nnz = m_profile->getBlockNnz();
1083 auto internal_profile = m_profile->internal();
1084 auto& kcol = internal_profile->getKCol();
1085 auto& block_row_offset = internal_profile->getBlockRowOffset();
1087 auto local_row_size = m_profile->localRowSize();
1088 if (local_row_size ==
nullptr)
1093 queue.submit([&](sycl::handler& cgh)
1095 auto access_kcol_buffer = internal_profile->getKCol().template get_access<sycl::access::mode::read>(cgh);
1096 auto access_block_row_offset = internal_profile->getBlockRowOffset().template get_access<sycl::access::mode::read>(cgh);
1097 auto access_values_buffer = values_buffer.template get_access<sycl::access::mode::read>(cgh);
1098 auto access_block_values = m_values.template get_access<sycl::access::mode::read_write>(cgh);
1101 cgh.parallel_for<
class set_matrix_values4>(sycl::range<1>{total_threads},
1102 [=] (sycl::item<1> item_id)
1104 auto id = item_id.get_id(0);
1109 for (
auto i =
id; i < nrows; i += item_id.get_range()[0])
1111 auto block_id = i/ellpack_size ;
1112 auto local_id = i%ellpack_size ;
1114 auto begin = access_kcol_buffer[i] ;
1115 auto end = access_kcol_buffer[i+1] ;
1116 auto row_size = end - begin ;
1118 int block_row_offset = access_block_row_offset[block_id]*ellpack_size*NxN ;
1119 auto block_row_size = access_block_row_offset[block_id+1]-access_block_row_offset[block_id] ;
1121 for(
int k=begin*NxN;k<end*NxN;++k)
1123 access_block_values[block_row_offset+(k-begin*NxN)*ellpack_size+local_id] = access_values_buffer[k] ;
1125 for(
int k=row_size*NxN;k<block_row_size*NxN;++k)
1127 access_block_values[block_row_offset+k*ellpack_size+local_id] = 0 ;
1133 m_values_is_update =
true;
1138 IndexBufferType lrowsize_buffer(local_row_size, sycl::range<1>(nrows));
1142 queue.submit([&](sycl::handler& cgh)
1144 auto access_kcol_buffer = internal_profile->getKCol().template get_access<sycl::access::mode::read>(cgh);
1145 auto access_lrowsize_buffer = lrowsize_buffer.template get_access<sycl::access::mode::read>(cgh);
1147 auto access_block_row_offset = internal_profile->getBlockRowOffset().template get_access<sycl::access::mode::read>(cgh);
1148 auto access_values_buffer = values_buffer.template get_access<sycl::access::mode::read>(cgh);
1149 auto access_block_values = m_values.template get_access<sycl::access::mode::read_write>(cgh);
1152 cgh.parallel_for<
class set_matrix_values5>(sycl::range<1>{total_threads},
1153 [=] (sycl::item<1> item_id)
1155 auto id = item_id.get_id(0);
1160 for (
auto i =
id; i < nrows; i += item_id.get_range()[0])
1162 auto block_id = i/ellpack_size ;
1163 auto local_id = i%ellpack_size ;
1165 auto begin = access_kcol_buffer[i] ;
1166 auto lrow_size = access_lrowsize_buffer[i] ;
1167 auto end = begin + lrow_size ;
1169 int block_row_offset = access_block_row_offset[block_id]*ellpack_size*NxN ;
1170 auto block_row_size = access_block_row_offset[block_id+1]-access_block_row_offset[block_id] ;
1172 for(
int k=begin*NxN;k<end*NxN;++k)
1174 access_block_values[block_row_offset+(k-begin*NxN)*ellpack_size+local_id] = access_values_buffer[k] ;
1176 for(
int k=lrow_size*NxN;k<block_row_size*NxN;++k)
1178 access_block_values[block_row_offset+k*ellpack_size+local_id] = 0 ;
1183 auto kcol = m_profile->kcol() ;
1184 auto local_row_size = m_profile->localRowSize() ;
1186 auto interface_nrows = m_ext_profile->getNRows();
1187 auto ext_nnz = m_ext_profile->getNnz();
1188 auto ext_block_nnz = m_ext_profile->getBlockNnz();
1190 auto ext_internal_profile = m_ext_profile->internal();
1191 auto& ext_kcol = ext_internal_profile->getKCol();
1192 auto& ext_block_row_offset = ext_internal_profile->getBlockRowOffset();
1194 m_ext_values.reset(
new ValueBufferType(ext_block_nnz * ellpack_size * NxN)) ;
1198 ValueBufferType ext_csr_values_buffer(m_h_csr_ext_values.data(), sycl::range<1>(ext_nnz * NxN));
1200 std::vector<Integer> h_local_row_offset(interface_nrows+1) ;
1202 Integer offset = 0 ;
1203 for(std::size_t i=0;i<interface_nrows;++i)
1205 h_local_row_offset[i] = offset ;
1206 offset += local_row_size[i] ;
1208 h_local_row_offset[interface_nrows] = offset ;
1210 IndexBufferType local_row_offset(h_local_row_offset.data(),sycl::range<1>(interface_nrows+1)) ;
1212 queue.submit([&](sycl::handler& cgh)
1214 auto access_kcol = internal_profile->getKCol().template get_access<sycl::access::mode::read>(cgh);
1215 auto access_interface_row_ids = m_interface_row_ids->template get_access<sycl::access::mode::read>(cgh);
1216 auto access_local_row_size = lrowsize_buffer.template get_access<sycl::access::mode::read>(cgh);
1217 auto access_local_row_offset = local_row_offset.template get_access<sycl::access::mode::read>(cgh);
1218 auto access_csr_values = values_buffer.template get_access<sycl::access::mode::read>(cgh);
1219 auto access_ext_csr_values = ext_csr_values_buffer.template get_access<sycl::access::mode::read_write>(cgh);
1220 cgh.parallel_for<
class set_matrix_values6>(sycl::range<1>{total_threads},
1221 [=] (sycl::item<1> item_id)
1223 auto id = item_id.get_id(0);
1224 for (
auto i =
id; i < interface_nrows; i += item_id.get_range()[0])
1226 Integer jcol = access_local_row_offset[i] ;
1227 for (
int k = (access_kcol[i] + access_local_row_size[i])*NxN; k < access_kcol[i + 1] * NxN; ++k)
1228 access_ext_csr_values[jcol++] = access_csr_values[k];
1233 queue.submit([&](sycl::handler& cgh)
1235 auto access_kcol_buffer = ext_kcol.template get_access<sycl::access::mode::read>(cgh);
1236 auto access_block_row_offset = ext_block_row_offset.template get_access<sycl::access::mode::read>(cgh);
1237 auto access_values_buffer = ext_csr_values_buffer.template get_access<sycl::access::mode::read>(cgh);
1239 auto access_block_values = sycl::accessor { *m_ext_values, cgh, sycl::write_only, sycl::property::no_init{}};
1241 cgh.parallel_for<
class set_matrix_values7>(sycl::range<1>{total_threads},
1242 [=] (sycl::item<1> item_id)
1244 auto id = item_id.get_id(0);
1246 for (
auto i =
id; i < interface_nrows; i += item_id.get_range()[0])
1248 auto block_id = i/ellpack_size ;
1249 auto local_id = i%ellpack_size ;
1250 auto begin = access_kcol_buffer[i] ;
1251 auto end = access_kcol_buffer[i+1] ;
1252 auto row_size = end - begin ;
1254 int block_row_offset = access_block_row_offset[block_id]*ellpack_size*NxN ;
1255 auto block_row_size = access_block_row_offset[block_id+1]-access_block_row_offset[block_id] ;
1257 for(
int k=begin*NxN;k<end*NxN;++k)
1259 access_block_values[block_row_offset+(k-begin*NxN)*ellpack_size+local_id] = access_values_buffer[k] ;
1261 for(
int k=row_size*NxN;k<block_row_size*NxN;++k)
1263 access_block_values[block_row_offset+k*ellpack_size+local_id] = 0 ;
1270 m_values_is_update =
true;
1275 template <
typename ValueT,
int EllpackSize>
1276 bool MatrixInternal<ValueT, EllpackSize>::setMatrixValues(ValueT
const* values,
bool only_host)
1280 int NxN = this->m_NxN;
1282 auto nnz = m_profile->getNnz();
1283 m_h_csr_values.resize(nnz*NxN);
1284 std::copy(values, values + nnz*NxN, m_h_csr_values.begin());
1285 if (m_ext_profile) {
1287 auto kcol = m_profile->kcol() ;
1288 auto local_row_size = m_profile->localRowSize() ;
1290 auto interface_nrows = m_ext_profile->getNRows() ;
1291 auto ext_nnz = m_ext_profile->getNnz();
1294 m_h_csr_ext_values.resize(ext_nnz*NxN);
1299 for (std::size_t i = 0; i < interface_nrows; ++i) {
1300 auto id = m_h_interface_row_ids[i];
1301 for (
int k = (kcol[
id] + local_row_size[
id])*NxN; k < kcol[
id + 1]*NxN; ++k) {
1302 m_h_csr_ext_values[jcol++] = values[k];
1308 m_values_is_update =
false;
1311 setMatrixValuesFromHost();
1312 m_values_is_update =
true;
1317 template <
typename ValueT,
int EllpackSize>
1318 bool MatrixInternal<ValueT, EllpackSize>::copy(std::size_t nb_blocks,
1320 ValueBufferType& values_buffer,
1323 auto env = SYCLEnv::instance();
1324 auto& queue = env->internal()->queue();
1325 auto num_groups = env->internal()->maxNumGroups();
1326 auto max_work_group_size = env->internal()->maxWorkGroupSize();
1327 auto total_threads = num_groups * ellpack_size;
1329 int pack_size = ellpack_size;
1330 int N1 = block_size ;
1332 int N2 = rhs_block_size ;
1334 auto nrows = m_profile->getNRows();
1335 auto nnz = m_profile->getNnz();
1336 auto block_nnz = m_profile->getBlockNnz();
1338 auto internal_profile = m_profile->internal();
1339 auto& kcol = internal_profile->getKCol();
1340 auto& block_row_offset = internal_profile->getBlockRowOffset();
1342 auto local_row_size = m_profile->localRowSize();
1343 if (local_row_size ==
nullptr)
1348 queue.submit([&](sycl::handler& cgh)
1350 auto access_kcol_buffer = internal_profile->getKCol().template get_access<sycl::access::mode::read>(cgh);
1351 auto access_block_row_offset = internal_profile->getBlockRowOffset().template get_access<sycl::access::mode::read>(cgh);
1352 auto access_values_buffer = values_buffer.template get_access<sycl::access::mode::read>(cgh);
1353 auto access_block_values = m_values.template get_access<sycl::access::mode::read_write>(cgh);
1356 cgh.parallel_for<
class set_matrix_values4>(
1357 sycl::range<1>{total_threads},
1358 [=] (sycl::item<1> item_id)
1360 auto id = item_id.get_id(0);
1365 for (
auto i =
id; i < nrows; i += item_id.get_range()[0])
1367 auto block_id = i/pack_size ;
1368 auto local_id = i%pack_size ;
1370 auto begin = access_block_row_offset[block_id] ;
1371 auto end = access_block_row_offset[block_id+1] ;
1373 for(
int k=begin;k<end;++k)
1375 for(
int i=0;i<N1;++i)
1376 for(
int j=0;j<N1;++j)
1377 access_block_values[(k*N1xN1 +i*N1+j)*pack_size+local_id] = access_values_buffer[(k*N2xN2+i*N2+j)*pack_size+local_id] ;
1387 IndexBufferType lrowsize_buffer(local_row_size, sycl::range<1>(nrows));
1391 queue.submit([&](sycl::handler& cgh)
1393 auto access_kcol_buffer = internal_profile->getKCol().template get_access<sycl::access::mode::read>(cgh);
1394 auto access_lrowsize_buffer = lrowsize_buffer.template get_access<sycl::access::mode::read>(cgh);
1396 auto access_block_row_offset = internal_profile->getBlockRowOffset().template get_access<sycl::access::mode::read>(cgh);
1397 auto access_values_buffer = values_buffer.template get_access<sycl::access::mode::read>(cgh);
1398 auto access_block_values = m_values.template get_access<sycl::access::mode::read_write>(cgh);
1401 cgh.parallel_for<
class set_matrix_values5>(
1402 sycl::range<1>{total_threads},
1403 [=] (sycl::item<1> item_id)
1405 auto id = item_id.get_id(0);
1410 for (
auto i =
id; i < nrows; i += item_id.get_range()[0])
1412 auto block_id = i/pack_size ;
1413 auto local_id = i%pack_size ;
1416 int block_row_offset = access_block_row_offset[block_id] ;
1418 auto begin = access_block_row_offset[block_id] ;
1419 auto end = access_block_row_offset[block_id+1] ;
1420 auto lrow_size = access_lrowsize_buffer[i] ;
1422 for(
int k=begin;k<begin+lrow_size;++k)
1424 for(
int i=0;i<N1;++i)
1425 for(
int j=0;j<N1;++j)
1426 access_block_values[(k*N1xN1 +i*N1+j)*pack_size+local_id] = access_values_buffer[(k*N2xN2+i*N2+j)*pack_size+local_id] ;
1428 for(
int k=begin+lrow_size;k<end;++k)
1430 for(
int i=0;i<N1;++i)
1431 for(
int j=0;j<N1;++j)
1432 access_block_values[(k*N1xN1 +i*N1+j)*pack_size+local_id] = 0 ;
1439 m_values_is_update =
true;
1443 template <
typename ValueT,
int EllpackSize>
1444 bool MatrixInternal<ValueT, EllpackSize>::copy(std::size_t nb_blocks,
1446 ValueBufferType& values_buffer,
1447 ValueBufferType& ext_values_buffer,
1450 copy(nb_blocks,block_size,values_buffer,rhs_block_size) ;
1452 auto env = SYCLEnv::instance();
1453 auto& queue = env->internal()->queue();
1454 auto num_groups = env->internal()->maxNumGroups();
1455 auto max_work_group_size = env->internal()->maxWorkGroupSize();
1456 auto total_threads = num_groups * ellpack_size;
1458 int pack_size = ellpack_size;
1459 int N1 = block_size ;
1461 int N2 = rhs_block_size ;
1463 auto nrows = m_profile->getNRows();
1464 auto nnz = m_profile->getNnz();
1465 auto block_nnz = m_profile->getBlockNnz();
1467 auto internal_profile = m_profile->internal();
1468 auto& kcol = internal_profile->getKCol();
1469 auto& block_row_offset = internal_profile->getBlockRowOffset();
1471 assert(m_ext_profile) ;
1472 auto interface_nrows = m_ext_profile->getNRows();
1473 auto ext_nnz = m_ext_profile->getNnz();
1474 auto ext_block_nnz = m_ext_profile->getBlockNnz();
1475 auto ext_internal_profile = m_ext_profile->internal();
1476 auto& ext_kcol = ext_internal_profile->getKCol();
1477 auto& ext_block_row_offset = ext_internal_profile->getBlockRowOffset();
1479 m_h_ext_values.resize(ext_block_nnz*N1xN1) ;
1480 m_ext_values.reset(
new ValueBufferType(ext_block_nnz * N1xN1* ellpack_size)) ;
1482 queue.submit([&](sycl::handler& cgh)
1484 auto access_block_row_offset = ext_block_row_offset.template get_access<sycl::access::mode::read>(cgh);
1485 auto access_ext_values_buffer = ext_values_buffer.template get_access<sycl::access::mode::read>(cgh);
1486 auto access_ext_values = sycl::accessor { *m_ext_values, cgh, sycl::write_only, sycl::property::no_init{}};
1488 cgh.parallel_for<
class set_matrix_ext_values3>(
1489 sycl::range<1>{total_threads},
1490 [=] (sycl::item<1> item_id)
1492 auto id = item_id.get_id(0);
1493 for (
auto i =
id; i < interface_nrows; i += item_id.get_range()[0])
1495 auto block_id = i/pack_size ;
1496 auto local_id = i%pack_size ;
1498 auto begin = access_block_row_offset[block_id] ;
1499 auto end = access_block_row_offset[block_id+1] ;
1501 for(
int k=begin;k<begin;++k)
1503 for(
int i=0;i<N1;++i)
1504 for(
int j=0;j<N1;++j)
1505 access_ext_values[(k*N1xN1 +i*N1+j)*pack_size+local_id] = access_ext_values_buffer[(k*N2xN2+i*N2+j)*pack_size+local_id] ;
1512 m_values_is_update =
true;
1517 template <
typename ValueT,
int EllpackSize>
1518 bool MatrixInternal<ValueT, EllpackSize>::needUpdate()
1520 return m_values_is_update !=
true;
1523 template <
typename ValueT,
int EllpackSize>
1524 void MatrixInternal<ValueT, EllpackSize>::notifyChanges()
1526 m_values_is_update =
false;
1529 template <
typename ValueT,
int EllpackSize>
1530 void MatrixInternal<ValueT, EllpackSize>::endUpdate()
1532 if (not m_values_is_update) {
1533 setMatrixValuesFromHost();
1614 template <
typename ValueT,
int EllPackSize>
1615 void MatrixInternal<ValueT, EllPackSize>::mult(ValueBufferType& x, ValueBufferType& y, sycl::queue& queue)
const
1620 auto device = queue.get_device();
1622 auto num_groups = queue.get_device().get_info<sycl::info::device::max_compute_units>();
1624 auto max_work_group_size = queue.get_device().get_info<sycl::info::device::max_work_group_size>();
1630 std::size_t pack_size = ellpack_size;
1631 auto nrows = m_profile->getNRows();
1632 auto nnz = m_profile->getNnz();
1634 auto internal_profile = m_profile->internal();
1635 auto& kcol = internal_profile->getKCol();
1636 auto& block_row_offset = internal_profile->getBlockRowOffset();
1637 auto& block_cols = internal_profile->getBlockCols();
1639 auto blocks_needed = (nrows + ellpack_size - 1) / ellpack_size;
1640 auto blocks_target = std::max(blocks_needed, num_groups * 4UL);
1641 auto total_threads = blocks_target * ellpack_size;
1645 queue.submit([&](sycl::handler& cgh)
1647 auto access_block_row_offset = block_row_offset.template get_access<sycl::access::mode::read>(cgh);
1648 auto access_cols = block_cols.template get_access<sycl::access::mode::read>(cgh);
1649 auto access_values = m_values.template get_access<sycl::access::mode::read>(cgh);
1652 auto access_x = x.template get_access<sycl::access::mode::read>(cgh);
1653 auto access_y = y.template get_access<sycl::access::mode::read_write>(cgh);
1657 cgh.parallel_for<
class compute_mult>(
1658 sycl::range<1>{total_threads},
1659 [=] (sycl::item<1> item_id)
1661 auto id = item_id.get_id(0);
1666 for (
auto i =
id; i < nrows; i += item_id.get_range()[0])
1668 auto block_id = i/ellpack_size ;
1669 auto local_id = i%ellpack_size ;
1670 int block_row_offset = access_block_row_offset[block_id]*ellpack_size ;
1671 auto block_row_size = access_block_row_offset[block_id+1]-access_block_row_offset[block_id] ;
1673 ValueType value = 0. ;
1674 for(
int j=0;j<block_row_size;++j)
1676 auto k = block_row_offset+j*ellpack_size+local_id ;
1677 value += access_values[k]* access_x[access_cols[k]] ;
1679 access_y[i] = value ;
1684 sycl::local_accessor<ValueType, 1> lds_x{pack_size, cgh};
1685 sycl::nd_range<1> r{sycl::range<1>{total_threads},sycl::range<1>{pack_size}};
1686 cgh.parallel_for<
class compute_mult>(r,
1687 [=](sycl::nd_item<1> item_id)
1690 auto local_id = item_id.get_local_id(0);
1692 auto global_id = item_id.get_global_id(0);
1695 for (
auto i = global_id; i < nrows; i += item_id.get_global_range()[0])
1697 auto block_id = i/pack_size ;
1700 int begin = access_block_row_offset[block_id] ;
1701 int end = access_block_row_offset[block_id+1] ;
1702 ValueType value = 0. ;
1703 for(
int k=begin;k<end;++k)
1706 const int col = access_cols[k * pack_size + local_id];
1708 lds_x[local_id] = access_x[col];
1709 item_id.barrier(sycl::access::fence_space::local_space);
1711 value += access_values[k * pack_size + local_id] * lds_x[local_id] ;
1712 item_id.barrier(sycl::access::fence_space::local_space);
1714 access_y[i] = value ;
1722 const bool done = dispatchN<2, 20>(this->m_N, [&](
auto N) {
1723 multN<decltype(N)::value>(x, y, queue);
1727 auto device = queue.get_device();
1729 auto num_groups = queue.get_device().get_info<sycl::info::device::max_compute_units>();
1731 auto max_work_group_size = queue.get_device().get_info<sycl::info::device::max_work_group_size>();
1733 auto total_threads = num_groups * ellpack_size;
1738 std::size_t pack_size = ellpack_size;
1739 auto nrows = m_profile->getNRows();
1740 auto nnz = m_profile->getNnz();
1742 auto internal_profile = m_profile->internal();
1743 auto& kcol = internal_profile->getKCol();
1744 auto& block_row_offset = internal_profile->getBlockRowOffset();
1745 auto& block_cols = internal_profile->getBlockCols();
1748 [&](sycl::handler& cgh)
1750 auto access_block_row_offset = block_row_offset.template get_access<sycl::access::mode::read>(cgh);
1751 auto access_cols = block_cols.template get_access<sycl::access::mode::read>(cgh);
1752 auto access_values = m_values.template get_access<sycl::access::mode::read>(cgh);
1755 auto access_x = x.template get_access<sycl::access::mode::read>(cgh);
1756 auto access_y = y.template get_access<sycl::access::mode::discard_write>(cgh);
1760 sycl::range<1> range{total_threads} ;
1761 auto tile = Tile(N) ;
1763 cgh.parallel_for<
class compute_block_mult>(range,
1764 [=] (sycl::item<1> item_id )
1766 auto id = item_id.get_id(0);
1773 for (
auto i =
id; i < nrows; i += item_id.get_range()[0] )
1775 auto block_id = i/pack_size ;
1776 auto local_id = i%pack_size ;
1778 std::size_t block_row_offset = access_block_row_offset[block_id] ;
1779 auto block_row_size = access_block_row_offset[block_id+1]-access_block_row_offset[block_id] ;
1781 for(
int ieq=0;ieq<N;++ieq)
1783 ValueType value = 0. ;
1784 for(std::size_t k=block_row_offset;k<block_row_offset+block_row_size;++k)
1787 value += tile.mult(ieq,
1794 access_y[i*N+ieq] = value;
1805 multN<2>(x,y,queue) ;
1808 multN<3>(x,y,queue) ;
1811 multN<4>(x,y,queue) ;
1814 auto device = queue.get_device();
1816 auto num_groups = queue.get_device().get_info<sycl::info::device::max_compute_units>();
1818 auto max_work_group_size = queue.get_device().get_info<sycl::info::device::max_work_group_size>();
1820 auto total_threads = num_groups * ellpack_size;
1825 std::size_t pack_size = ellpack_size;
1826 auto nrows = m_profile->getNRows();
1827 auto nnz = m_profile->getNnz();
1829 auto internal_profile = m_profile->internal();
1830 auto& kcol = internal_profile->getKCol();
1831 auto& block_row_offset = internal_profile->getBlockRowOffset();
1832 auto& block_cols = internal_profile->getBlockCols();
1835 [&](sycl::handler& cgh)
1837 auto access_block_row_offset = block_row_offset.template get_access<sycl::access::mode::read>(cgh);
1838 auto access_cols = block_cols.template get_access<sycl::access::mode::read>(cgh);
1839 auto access_values = m_values.template get_access<sycl::access::mode::read>(cgh);
1842 auto access_x = x.template get_access<sycl::access::mode::read>(cgh);
1843 auto access_y = y.template get_access<sycl::access::mode::discard_write>(cgh);
1847 sycl::range<1> range{total_threads} ;
1848 auto tile = Tile(N) ;
1850 cgh.parallel_for<
class compute_block_mult>(range,
1851 [=] (sycl::item<1> item_id )
1853 auto id = item_id.get_id(0);
1860 for (
auto i =
id; i < nrows; i += item_id.get_range()[0] )
1862 auto block_id = i/pack_size ;
1863 auto local_id = i%pack_size ;
1865 std::size_t block_row_offset = access_block_row_offset[block_id] ;
1866 auto block_row_size = access_block_row_offset[block_id+1]-access_block_row_offset[block_id] ;
1868 for(
int ieq=0;ieq<N;++ieq)
1870 ValueType value = 0. ;
1871 for(std::size_t k=block_row_offset;k<block_row_offset+block_row_size;++k)
1874 value += tile.mult(ieq,
1881 access_y[i*N+ieq] = value;
1948 template <
typename ValueT,
int EllPackSize>
1949 void MatrixInternal<ValueT, EllPackSize>::mult(ValueBufferType& x, ValueBufferType& y)
const
1951 this->mult(x, y, SYCLEnv::instance()->internal()->queue());
1954 template <
typename ValueT,
int EllPackSize>
1955 void MatrixInternal<ValueT, EllPackSize>::addExtMult(ValueBufferType& x,
1957 sycl::queue& queue)
const
1959 auto device = queue.get_device();
1961 auto num_groups = queue.get_device().get_info<sycl::info::device::max_compute_units>();
1963 auto max_work_group_size = queue.get_device().get_info<sycl::info::device::max_work_group_size>();
1965 auto total_threads = num_groups * ellpack_size;
1969 std::size_t pack_size = ellpack_size;
1972 auto nrows = m_profile->getNRows();
1973 auto nnz = m_profile->getNnz();
1975 auto interface_nrow = m_ext_profile->getNRows();
1976 auto ext_profile = m_ext_profile->internal();
1977 auto& kcol = ext_profile->getKCol();
1978 auto& block_row_offset = ext_profile->getBlockRowOffset();
1979 auto& block_cols = ext_profile->getBlockCols();
1984 queue.submit([&](sycl::handler& cgh)
1986 auto access_block_row_offset = block_row_offset.template get_access<sycl::access::mode::read>(cgh);
1987 auto access_cols = block_cols.template get_access<sycl::access::mode::read>(cgh);
1988 auto access_values = m_ext_values->template get_access<sycl::access::mode::read>(cgh);
1990 auto access_row_ids = m_interface_row_ids->template get_access<sycl::access::mode::read>(cgh);
1992 auto access_x = x.template get_access<sycl::access::mode::read>(cgh);
1993 auto access_y = y.template get_access<sycl::access::mode::read_write>(cgh);
1995 cgh.parallel_for<
class compute_ext_mult>(
1996 sycl::range<1>{total_threads},
1997 [=] (sycl::item<1> item_id)
1999 auto id = item_id.get_id(0);
2001 for (
auto i =
id; i < interface_nrow; i += item_id.get_range()[0])
2003 auto block_id = i / pack_size ;
2004 auto local_id = i % pack_size ;
2006 int block_row_offset = access_block_row_offset[block_id]*ellpack_size ;
2007 auto block_row_size = access_block_row_offset[block_id+1]-access_block_row_offset[block_id] ;
2009 ValueType value = 0. ;
2010 for(
int j=0;j<block_row_size;++j)
2012 auto k = block_row_offset+j*ellpack_size+local_id ;
2013 value += access_values[k]* access_x[access_cols[k]] ;
2015 access_y[access_row_ids[i]] += value ;
2023 const bool done = dispatchN<2, 20>(
2027 addExtMultN<decltype(N)::value>(1., x, y, queue);
2034 queue.submit([&](sycl::handler& cgh)
2036 auto access_block_row_offset = block_row_offset.template get_access<sycl::access::mode::read>(cgh);
2037 auto access_cols = block_cols.template get_access<sycl::access::mode::read>(cgh);
2038 auto access_values = m_ext_values->template get_access<sycl::access::mode::read>(cgh);
2040 auto access_row_ids = m_interface_row_ids->template get_access<sycl::access::mode::read>(cgh);
2042 auto access_x = x.template get_access<sycl::access::mode::read>(cgh);
2043 auto access_y = y.template get_access<sycl::access::mode::read_write>(cgh);
2045 auto tile = Tile(N) ;
2046 cgh.parallel_for<
class compute_ext_mult>(
2047 sycl::range<1>{total_threads},
2048 [=] (sycl::item<1> item_id)
2050 auto id = item_id.get_id(0);
2052 for (
auto i =
id; i < interface_nrow; i += item_id.get_range()[0])
2054 auto block_id = i / pack_size ;
2055 auto local_id = i % pack_size ;
2057 int block_row_offset = access_block_row_offset[block_id] * pack_size ;
2058 auto block_row_size = access_block_row_offset[block_id+1]-access_block_row_offset[block_id] ;
2060 for(
int ieq=0;ieq<N;++ieq)
2062 ValueType value = 0. ;
2063 for(std::size_t k=block_row_offset;k<block_row_offset+block_row_size;++k)
2066 value += tile.mult(ieq,
2073 access_y[access_row_ids[i]*N+ieq] += value;
2083 template <
typename ValueT,
int EllPackSize>
2084 void MatrixInternal<ValueT, EllPackSize>::addExtMult(ValueBufferType& x,
2085 ValueBufferType& y)
const
2087 this->addExtMult(x, y, SYCLEnv::instance()->internal()->queue());
2090 template <
typename ValueT,
int EllPackSize>
2091 void MatrixInternal<ValueT, EllPackSize>::addLMult(ValueType alpha,
2094 sycl::queue& queue)
const
2099 auto device = queue.get_device();
2101 auto num_groups = queue.get_device().get_info<sycl::info::device::max_compute_units>();
2103 auto max_work_group_size = queue.get_device().get_info<sycl::info::device::max_work_group_size>();
2105 std::size_t pack_size = ellpack_size;
2106 auto nrows = m_profile->getNRows();
2107 auto nnz = m_profile->getNnz();
2109 auto internal_profile = m_profile->internal();
2110 auto& kcol = internal_profile->getKCol();
2111 auto& block_row_offset = internal_profile->getBlockRowOffset();
2112 auto& block_cols = internal_profile->getBlockCols();
2114 auto& mask = internal_profile->getLowerMask();
2118 [&](sycl::handler& cgh)
2120 auto access_block_row_offset = block_row_offset.template get_access<sycl::access::mode::read>(cgh);
2121 auto access_cols = block_cols.template get_access<sycl::access::mode::read>(cgh);
2122 auto access_mask = mask.template get_access<sycl::access::mode::read>(cgh);
2123 auto access_values = m_values.template get_access<sycl::access::mode::read>(cgh);
2126 auto access_x = x.template get_access<sycl::access::mode::read>(cgh);
2127 auto access_y = y.template get_access<sycl::access::mode::read_write>(cgh);
2129 auto blocks_needed = (nrows + ellpack_size - 1) / ellpack_size;
2130 auto blocks_target = std::max(blocks_needed, num_groups * 4UL);
2131 auto total_threads = blocks_target * ellpack_size;
2133 sycl::local_accessor<ValueType, 1> lds_x{pack_size, cgh};
2134 sycl::nd_range<1> r{sycl::range<1>{total_threads},sycl::range<1>{pack_size}};
2136 cgh.parallel_for<
class compute_lmult>(r,
2137 [=](sycl::nd_item<1> item_id)
2140 auto local_id = item_id.get_local_id(0);
2142 auto global_id = item_id.get_global_id(0);
2145 for (
auto i = global_id; i < nrows; i += item_id.get_global_range()[0])
2147 auto block_id = i/pack_size ;
2150 int begin = access_block_row_offset[block_id] ;
2151 int end = access_block_row_offset[block_id+1] ;
2153 ValueType value = access_y[i] ;
2154 for(
int k=begin;k<end;++k)
2157 const int col = access_cols[k * pack_size + local_id];
2159 lds_x[local_id] = access_x[col];
2160 item_id.barrier(sycl::access::fence_space::local_space);
2161 if(access_mask[k * pack_size + local_id])
2162 value += alpha * access_values[k * pack_size + local_id] * lds_x[local_id] ;
2163 item_id.barrier(sycl::access::fence_space::local_space);
2165 access_y[i] = value ;
2172 const bool done = dispatchN<2, 20>(
2176 addLMultN<decltype(N)::value>(alpha,x, y, queue);
2181 auto device = queue.get_device();
2183 auto num_groups = queue.get_device().get_info<sycl::info::device::max_compute_units>();
2185 auto max_work_group_size = queue.get_device().get_info<sycl::info::device::max_work_group_size>();
2186 auto total_threads = num_groups * ellpack_size;
2189 int NxN = this->m_NxN;
2190 std::size_t pack_size = ellpack_size;
2191 auto nrows = m_profile->getNRows();
2192 auto nnz = m_profile->getNnz();
2194 auto internal_profile = m_profile->internal();
2195 auto& kcol = internal_profile->getKCol();
2196 auto& block_row_offset = internal_profile->getBlockRowOffset();
2197 auto& block_cols = internal_profile->getBlockCols();
2199 auto& mask = internal_profile->getLowerMask();
2203 [&](sycl::handler& cgh)
2205 auto access_block_row_offset = block_row_offset.template get_access<sycl::access::mode::read>(cgh);
2206 auto access_cols = block_cols.template get_access<sycl::access::mode::read>(cgh);
2207 auto access_mask = mask.template get_access<sycl::access::mode::read>(cgh);
2208 auto access_values = m_values.template get_access<sycl::access::mode::read>(cgh);
2210 auto access_x = x.template get_access<sycl::access::mode::read>(cgh);
2211 auto access_y = y.template get_access<sycl::access::mode::read_write>(cgh);
2212 sycl::range<1> range{total_threads} ;
2213 auto tile = Tile(N) ;
2214 cgh.parallel_for<
class compute_block_lmult>(
2215 sycl::range<1>{total_threads},
2216 [=] (sycl::item<1> item_id)
2218 auto id = item_id.get_id(0);
2223 for (
auto i =
id; i < nrows; i += item_id.get_range()[0])
2225 auto block_id = i/ellpack_size ;
2226 auto local_id = i%ellpack_size ;
2228 int block_row_offset = access_block_row_offset[block_id] ;
2229 auto block_row_size = access_block_row_offset[block_id+1]-access_block_row_offset[block_id] ;
2231 for(
int ieq=0;ieq<N;++ieq)
2233 ValueType value = 0. ;
2234 for(std::size_t k=block_row_offset;k<block_row_offset+block_row_size;++k)
2237 value += tile.mult(ieq,
2245 access_y[i*N+ieq] += alpha*value;
2255 addLMultN<2>(alpha,x,y,queue);
2258 addLMultN<3>(alpha,x,y,queue);
2261 addLMultN<4>(alpha,x,y,queue);
2265 auto device = queue.get_device();
2267 auto num_groups = queue.get_device().get_info<sycl::info::device::max_compute_units>();
2269 auto max_work_group_size = queue.get_device().get_info<sycl::info::device::max_work_group_size>();
2270 auto total_threads = num_groups * ellpack_size;
2273 int NxN = this->m_NxN;
2274 std::size_t pack_size = ellpack_size;
2275 auto nrows = m_profile->getNRows();
2276 auto nnz = m_profile->getNnz();
2278 auto internal_profile = m_profile->internal();
2279 auto& kcol = internal_profile->getKCol();
2280 auto& block_row_offset = internal_profile->getBlockRowOffset();
2281 auto& block_cols = internal_profile->getBlockCols();
2283 auto& mask = internal_profile->getLowerMask();
2287 [&](sycl::handler& cgh)
2289 auto access_block_row_offset = block_row_offset.template get_access<sycl::access::mode::read>(cgh);
2290 auto access_cols = block_cols.template get_access<sycl::access::mode::read>(cgh);
2291 auto access_mask = mask.template get_access<sycl::access::mode::read>(cgh);
2292 auto access_values = m_values.template get_access<sycl::access::mode::read>(cgh);
2294 auto access_x = x.template get_access<sycl::access::mode::read>(cgh);
2295 auto access_y = y.template get_access<sycl::access::mode::read_write>(cgh);
2296 sycl::range<1> range{total_threads} ;
2297 auto tile = Tile(N) ;
2298 cgh.parallel_for<
class compute_block_lmult>(
2299 sycl::range<1>{total_threads},
2300 [=] (sycl::item<1> item_id)
2302 auto id = item_id.get_id(0);
2307 for (
auto i =
id; i < nrows; i += item_id.get_range()[0])
2309 auto block_id = i/ellpack_size ;
2310 auto local_id = i%ellpack_size ;
2312 int block_row_offset = access_block_row_offset[block_id] ;
2313 auto block_row_size = access_block_row_offset[block_id+1]-access_block_row_offset[block_id] ;
2315 for(
int ieq=0;ieq<N;++ieq)
2317 ValueType value = 0. ;
2318 for(std::size_t k=block_row_offset;k<block_row_offset+block_row_size;++k)
2321 value += tile.mult(ieq,
2329 access_y[i*N+ieq] += alpha*value;
2340#ifdef PRINT_DEBUG_INFO
2342 sycl::host_accessor<ValueT, 1, sycl::access::mode::read> h_acc(m_values);
2343 sycl::host_accessor<int, 1, sycl::access::mode::read> kcol_acc(block_row_offset);
2344 sycl::host_accessor<uint8_t, 1, sycl::access::mode::read> mask_acc(mask) ;
2345 sycl::host_accessor<ValueT, 1, sycl::access::mode::read> x_acc(x);
2346 sycl::host_accessor<ValueT, 1, sycl::access::mode::read> y_acc(y);
2347 for(
int irow=0;irow<nrows;++irow)
2349 std::cout<<
"XK["<<irow<<
"]=\n";
2350 for(
int i=0;i<N;++i)
2351 std::cout<<x_acc[irow*N+i]<<
"\n";
2353 for(
int irow=0;irow<nrows;++irow)
2355 auto ib=irow/ellpack_size ;
2356 auto il=irow%ellpack_size ;
2357 std::cout<<
"LSOLVE MAT["<<irow<<
"]:"<<std::endl;
2358 for(
int k=kcol_acc[ib];k<kcol_acc[ib+1];++k)
2360 if(mask_acc[k*ellpack_size+il])
2362 for(
int i=0;i<N;++i)
2364 for(
int j=0;j<N;++j)
2365 std::cout<<h_acc[(k*NxN+i*N+j)*ellpack_size+il]<<
" ";
2366 std::cout<<std::endl;
2370 std::cout<<
"Y ="<<std::endl;
2371 for(
int i=0;i<N;++i)
2372 std::cout<<y_acc[irow*N+i]<<
"\n";
2378 template <
typename ValueT,
int EllPackSize>
2379 void MatrixInternal<ValueT, EllPackSize>::addLMult(ValueType alpha, ValueBufferType& x, ValueBufferType& y)
const
2381 this->addLMult(alpha, x, y, SYCLEnv::instance()->internal()->queue());
2384 template <
typename ValueT,
int EllPackSize>
2385 void MatrixInternal<ValueT, EllPackSize>::addExtLMult(ValueType alpha,
2388 sycl::queue& queue)
const
2390 auto device = queue.get_device();
2392 auto num_groups = queue.get_device().get_info<sycl::info::device::max_compute_units>();
2394 auto max_work_group_size = queue.get_device().get_info<sycl::info::device::max_work_group_size>();
2396 auto total_threads = num_groups * ellpack_size;
2400 std::size_t pack_size = ellpack_size;
2403 auto nrows = m_profile->getNRows();
2404 auto nnz = m_profile->getNnz();
2406 auto interface_nrow = m_ext_profile->getNRows();
2407 auto first_upper_ghost = m_first_upper_ghost_index ;
2408 auto ext_profile = m_ext_profile->internal();
2409 auto& kcol = ext_profile->getKCol();
2410 auto& block_row_offset = ext_profile->getBlockRowOffset();
2411 auto& block_cols = ext_profile->getBlockCols();
2416 queue.submit([&](sycl::handler& cgh)
2418 auto access_block_row_offset = block_row_offset.template get_access<sycl::access::mode::read>(cgh);
2419 auto access_cols = block_cols.template get_access<sycl::access::mode::read>(cgh);
2420 auto access_values = m_ext_values->template get_access<sycl::access::mode::read>(cgh);
2422 auto access_row_ids = m_interface_row_ids->template get_access<sycl::access::mode::read>(cgh);
2424 auto access_x = x.template get_access<sycl::access::mode::read>(cgh);
2425 auto access_y = y.template get_access<sycl::access::mode::read_write>(cgh);
2427 cgh.parallel_for<
class compute_ext_lmult>(
2428 sycl::range<1>{total_threads},
2429 [=] (sycl::item<1> item_id)
2431 auto id = item_id.get_id(0);
2433 for (
auto i =
id; i < interface_nrow; i += item_id.get_range()[0])
2435 auto block_id = i / pack_size ;
2436 auto local_id = i % pack_size ;
2438 int block_row_offset = access_block_row_offset[block_id] * pack_size ;
2439 auto block_row_size = access_block_row_offset[block_id+1] - access_block_row_offset[block_id] ;
2441 ValueType value = 0. ;
2442 for(
int j=0;j<block_row_size;++j)
2444 auto k = block_row_offset+j*ellpack_size+local_id ;
2445 if(access_cols[k]<first_upper_ghost)
2446 value += access_values[k]* access_x[access_cols[k]] ;
2448 access_y[access_row_ids[i]] += alpha * value ;
2456 const bool done = dispatchN<2, 20>(
2460 addExtLMultN<decltype(N)::value>(alpha, x, y, queue);
2467 queue.submit([&](sycl::handler& cgh)
2469 auto access_block_row_offset = block_row_offset.template get_access<sycl::access::mode::read>(cgh);
2470 auto access_cols = block_cols.template get_access<sycl::access::mode::read>(cgh);
2471 auto access_values = m_ext_values->template get_access<sycl::access::mode::read>(cgh);
2473 auto access_row_ids = m_interface_row_ids->template get_access<sycl::access::mode::read>(cgh);
2475 auto access_x = x.template get_access<sycl::access::mode::read>(cgh);
2476 auto access_y = y.template get_access<sycl::access::mode::read_write>(cgh);
2478 auto tile = Tile(N) ;
2479 cgh.parallel_for<
class compute_ext_lmult>(
2480 sycl::range<1>{total_threads},
2481 [=] (sycl::item<1> item_id)
2483 auto id = item_id.get_id(0);
2485 for (
auto i =
id; i < interface_nrow; i += item_id.get_range()[0])
2487 auto block_id = i / pack_size ;
2488 auto local_id = i % pack_size ;
2490 int block_row_offset = access_block_row_offset[block_id] * pack_size ;
2491 auto block_row_size = access_block_row_offset[block_id+1]-access_block_row_offset[block_id] ;
2493 for(
int ieq=0;ieq<N;++ieq)
2495 ValueType value = 0. ;
2496 for(std::size_t k=block_row_offset;k<block_row_offset+block_row_size;++k)
2499 if(access_cols[k]<first_upper_ghost)
2500 value += tile.mult(ieq,
2507 access_y[access_row_ids[i]*N+ieq] += alpha * value;
2517 template <
typename ValueT,
int EllPackSize>
2518 void MatrixInternal<ValueT, EllPackSize>::addExtLMult(ValueType alpha,
2520 ValueBufferType& y)
const
2522 this->addExtLMult(alpha, x, y, SYCLEnv::instance()->internal()->queue());
2525 template <
typename ValueT,
int EllPackSize>
2526 void MatrixInternal<ValueT, EllPackSize>::addUMult(ValueType alpha,
2529 sycl::queue& queue)
const
2533 auto device = queue.get_device();
2535 auto num_groups = queue.get_device().get_info<sycl::info::device::max_compute_units>();
2536 auto max_work_group_size = queue.get_device().get_info<sycl::info::device::max_work_group_size>();
2540 int NxN = this->m_NxN;
2541 std::size_t pack_size = ellpack_size;
2542 auto nrows = m_profile->getNRows() ;
2543 auto nnz = m_profile->getNnz() ;
2545 auto blocks_needed = (nrows + ellpack_size - 1) / ellpack_size;
2546 auto blocks_target = std::max(blocks_needed, num_groups * 4UL);
2547 auto total_threads = blocks_target * ellpack_size;
2549 auto internal_profile = m_profile->internal() ;
2550 auto& kcol = internal_profile->getKCol() ;
2551 auto& block_row_offset = internal_profile->getBlockRowOffset() ;
2552 auto& block_cols = internal_profile->getBlockCols() ;
2553 auto& mask = internal_profile->getUpperMask() ;
2557 [&](sycl::handler& cgh)
2559 auto access_block_row_offset = block_row_offset.template get_access<sycl::access::mode::read>(cgh);
2560 auto access_cols = block_cols.template get_access<sycl::access::mode::read>(cgh);
2561 auto access_mask = mask.template get_access<sycl::access::mode::read>(cgh);
2562 auto access_values = m_values.template get_access<sycl::access::mode::read>(cgh);
2565 auto access_x = x.template get_access<sycl::access::mode::read>(cgh);
2566 auto access_y = y.template get_access<sycl::access::mode::read_write>(cgh);
2568 sycl::local_accessor<ValueType, 1> lds_x{pack_size, cgh};
2569 sycl::nd_range<1> r{sycl::range<1>{total_threads},sycl::range<1>{pack_size}};
2571 cgh.parallel_for<
class compute_umult>(r,
2572 [=](sycl::nd_item<1> item_id)
2575 auto local_id = item_id.get_local_id(0);
2577 auto global_id = item_id.get_global_id(0);
2579 for (
auto i = global_id; i < nrows; i += item_id.get_global_range()[0])
2581 auto block_id = i/pack_size ;
2584 auto begin = access_block_row_offset[block_id] ;
2585 auto end = access_block_row_offset[block_id+1] ;
2588 ValueType value = access_y[i] ;
2589 for(
int k=begin;k<end;++k)
2593 const int col = access_cols[k * pack_size + local_id];
2595 lds_x[local_id] = access_x[col];
2596 item_id.barrier(sycl::access::fence_space::local_space);
2597 if(access_mask[k * pack_size + local_id])
2598 value += alpha * access_values[k * pack_size + local_id] * lds_x[local_id] ;
2599 item_id.barrier(sycl::access::fence_space::local_space);
2601 access_y[i] = value ;
2608 const bool done = dispatchN<2, 20>(
2612 addUMultN<decltype(N)::value>(alpha, x, y, queue);
2617 auto device = queue.get_device();
2619 auto num_groups = queue.get_device().get_info<sycl::info::device::max_compute_units>();
2620 auto max_work_group_size = queue.get_device().get_info<sycl::info::device::max_work_group_size>();
2621 auto total_threads = num_groups * ellpack_size;
2625 int NxN = this->m_NxN;
2626 std::size_t pack_size = ellpack_size;
2627 auto nrows = m_profile->getNRows() ;
2628 auto nnz = m_profile->getNnz() ;
2630 auto internal_profile = m_profile->internal() ;
2631 auto& kcol = internal_profile->getKCol() ;
2632 auto& block_row_offset = internal_profile->getBlockRowOffset() ;
2633 auto& block_cols = internal_profile->getBlockCols() ;
2634 auto& mask = internal_profile->getUpperMask() ;
2638 [&](sycl::handler& cgh)
2640 auto access_block_row_offset = block_row_offset.template get_access<sycl::access::mode::read>(cgh);
2641 auto access_cols = block_cols.template get_access<sycl::access::mode::read>(cgh);
2642 auto access_mask = mask.template get_access<sycl::access::mode::read>(cgh);
2643 auto access_values = m_values.template get_access<sycl::access::mode::read>(cgh);
2646 auto access_x = x.template get_access<sycl::access::mode::read>(cgh);
2647 auto access_y = y.template get_access<sycl::access::mode::read_write>(cgh);
2649 auto tile = Tile(N) ;
2650 cgh.parallel_for<
class compute_block_umult>(
2651 sycl::range<1>{total_threads},
2652 [=] (sycl::item<1> item_id)
2654 auto id = item_id.get_id(0);
2659 for (
auto i =
id; i < nrows; i += item_id.get_range()[0])
2661 auto block_id = i/ellpack_size ;
2662 auto local_id = i%ellpack_size ;
2664 std::size_t block_row_offset = access_block_row_offset[block_id] ;
2665 std::size_t block_row_size = access_block_row_offset[block_id+1]-access_block_row_offset[block_id] ;
2666 for(
int ieq=0;ieq<N;++ieq)
2668 ValueType value = 0. ;
2669 for(std::size_t k=block_row_offset;k<block_row_offset+block_row_size;++k)
2672 value += tile.mult(ieq,
2680 access_y[i*N+ieq] += alpha*value;
2690 addUMultN<2>(alpha,x,y,queue);
2693 addUMultN<3>(alpha,x,y,queue);
2696 addUMultN<4>(alpha,x,y,queue);
2700 auto device = queue.get_device();
2702 auto num_groups = queue.get_device().get_info<sycl::info::device::max_compute_units>();
2703 auto max_work_group_size = queue.get_device().get_info<sycl::info::device::max_work_group_size>();
2704 auto total_threads = num_groups * ellpack_size;
2708 int NxN = this->m_NxN;
2709 std::size_t pack_size = ellpack_size;
2710 auto nrows = m_profile->getNRows() ;
2711 auto nnz = m_profile->getNnz() ;
2713 auto internal_profile = m_profile->internal() ;
2714 auto& kcol = internal_profile->getKCol() ;
2715 auto& block_row_offset = internal_profile->getBlockRowOffset() ;
2716 auto& block_cols = internal_profile->getBlockCols() ;
2717 auto& mask = internal_profile->getUpperMask() ;
2721 [&](sycl::handler& cgh)
2723 auto access_block_row_offset = block_row_offset.template get_access<sycl::access::mode::read>(cgh);
2724 auto access_cols = block_cols.template get_access<sycl::access::mode::read>(cgh);
2725 auto access_mask = mask.template get_access<sycl::access::mode::read>(cgh);
2726 auto access_values = m_values.template get_access<sycl::access::mode::read>(cgh);
2729 auto access_x = x.template get_access<sycl::access::mode::read>(cgh);
2730 auto access_y = y.template get_access<sycl::access::mode::read_write>(cgh);
2732 auto tile = Tile(N) ;
2733 cgh.parallel_for<
class compute_block_umult>(
2734 sycl::range<1>{total_threads},
2735 [=] (sycl::item<1> item_id)
2737 auto id = item_id.get_id(0);
2742 for (
auto i =
id; i < nrows; i += item_id.get_range()[0])
2744 auto block_id = i/ellpack_size ;
2745 auto local_id = i%ellpack_size ;
2747 int block_row_offset = access_block_row_offset[block_id] ;
2748 auto block_row_size = access_block_row_offset[block_id+1]-access_block_row_offset[block_id] ;
2749 for(
int ieq=0;ieq<N;++ieq)
2751 ValueType value = 0. ;
2752 for(std::size_t k=block_row_offset;k<block_row_offset+block_row_size;++k)
2755 value += tile.mult(ieq,
2763 access_y[i*N+ieq] += alpha*value;
2775#ifdef PRINT_DEBUG_INFO
2777 sycl::host_accessor<ValueT, 1, sycl::access::mode::read> h_acc(m_values);
2778 sycl::host_accessor<int, 1, sycl::access::mode::read> kcol_acc(block_row_offset);
2779 sycl::host_accessor<uint8_t, 1, sycl::access::mode::read> mask_acc(mask) ;
2780 sycl::host_accessor<ValueT, 1, sycl::access::mode::read> x_acc(x);
2781 sycl::host_accessor<ValueT, 1, sycl::access::mode::read> y_acc(y);
2782 for(
int irow=0;irow<nrows;++irow)
2784 std::cout<<
"XK["<<irow<<
"]=\n";
2785 for(
int i=0;i<N;++i)
2786 std::cout<<x_acc[irow*N+i]<<
"\n";
2788 for(
int irow=0;irow<nrows;++irow)
2790 auto ib=irow/ellpack_size ;
2791 auto il=irow%ellpack_size ;
2792 std::cout<<
"USOLVE MAT["<<irow<<
"]:"<<std::endl;
2793 for(
int k=kcol_acc[ib];k<kcol_acc[ib+1];++k)
2795 if(mask_acc[k*ellpack_size+il])
2797 for(
int i=0;i<N;++i)
2799 for(
int j=0;j<N;++j)
2800 std::cout<<h_acc[(k*NxN+i*N+j)*ellpack_size+il]<<
" ";
2801 std::cout<<std::endl;
2805 std::cout<<
"Y ="<<std::endl;
2806 for(
int i=0;i<N;++i)
2807 std::cout<<y_acc[irow*N+i]<<
"\n";
2813 template <
typename ValueT,
int EllPackSize>
2814 void MatrixInternal<ValueT, EllPackSize>::addUMult(ValueType alpha, ValueBufferType& x, ValueBufferType& y)
const
2816 this->addUMult(alpha, x, y, SYCLEnv::instance()->internal()->queue());
2819 template <
typename ValueT,
int EllPackSize>
2820 void MatrixInternal<ValueT, EllPackSize>::addExtUMult(ValueType alpha,
2823 sycl::queue& queue)
const
2825 auto device = queue.get_device();
2827 auto num_groups = queue.get_device().get_info<sycl::info::device::max_compute_units>();
2829 auto max_work_group_size = queue.get_device().get_info<sycl::info::device::max_work_group_size>();
2831 auto total_threads = num_groups * ellpack_size;
2835 std::size_t pack_size = ellpack_size;
2838 auto nrows = m_profile->getNRows();
2839 auto nnz = m_profile->getNnz();
2841 auto interface_nrow = m_ext_profile->getNRows();
2842 auto first_upper_ghost = m_first_upper_ghost_index ;
2843 auto ext_profile = m_ext_profile->internal();
2844 auto& kcol = ext_profile->getKCol();
2845 auto& block_row_offset = ext_profile->getBlockRowOffset();
2846 auto& block_cols = ext_profile->getBlockCols();
2851 queue.submit([&](sycl::handler& cgh)
2853 auto access_block_row_offset = block_row_offset.template get_access<sycl::access::mode::read>(cgh);
2854 auto access_cols = block_cols.template get_access<sycl::access::mode::read>(cgh);
2855 auto access_values = m_ext_values->template get_access<sycl::access::mode::read>(cgh);
2857 auto access_row_ids = m_interface_row_ids->template get_access<sycl::access::mode::read>(cgh);
2859 auto access_x = x.template get_access<sycl::access::mode::read>(cgh);
2860 auto access_y = y.template get_access<sycl::access::mode::read_write>(cgh);
2862 cgh.parallel_for<
class compute_ext_umult>(
2863 sycl::range<1>{total_threads},
2864 [=] (sycl::item<1> item_id)
2866 auto id = item_id.get_id(0);
2868 for (
auto i =
id; i < interface_nrow; i += item_id.get_range()[0])
2870 auto block_id = i / pack_size ;
2871 auto local_id = i % pack_size ;
2873 int block_row_offset = access_block_row_offset[block_id] * pack_size ;
2874 auto block_row_size = access_block_row_offset[block_id+1]-access_block_row_offset[block_id] ;
2876 ValueType value = 0. ;
2877 for(
int j=0;j<block_row_size;++j)
2879 auto k = block_row_offset+j*pack_size+local_id ;
2880 if(access_cols[k]>=first_upper_ghost)
2881 value += access_values[k]* access_x[access_cols[k]] ;
2883 access_y[access_row_ids[i]] += alpha * value ;
2891 const bool done = dispatchN<2, 20>(
2895 addExtUMultN<decltype(N)::value>(alpha, x, y, queue);
2902 queue.submit([&](sycl::handler& cgh)
2904 auto access_block_row_offset = block_row_offset.template get_access<sycl::access::mode::read>(cgh);
2905 auto access_cols = block_cols.template get_access<sycl::access::mode::read>(cgh);
2906 auto access_values = m_ext_values->template get_access<sycl::access::mode::read>(cgh);
2908 auto access_row_ids = m_interface_row_ids->template get_access<sycl::access::mode::read>(cgh);
2910 auto access_x = x.template get_access<sycl::access::mode::read>(cgh);
2911 auto access_y = y.template get_access<sycl::access::mode::read_write>(cgh);
2913 auto tile = Tile(N) ;
2914 cgh.parallel_for<
class compute_ext_umult>(
2915 sycl::range<1>{total_threads},
2916 [=] (sycl::item<1> item_id)
2918 auto id = item_id.get_id(0);
2920 for (
auto i =
id; i < interface_nrow; i += item_id.get_range()[0])
2922 auto block_id = i / pack_size ;
2923 auto local_id = i % pack_size ;
2925 int block_row_offset = access_block_row_offset[block_id] * pack_size ;
2926 auto block_row_size = access_block_row_offset[block_id+1]-access_block_row_offset[block_id] ;
2928 for(
int ieq=0;ieq<N;++ieq)
2930 ValueType value = 0. ;
2931 for(std::size_t k=block_row_offset;k<block_row_offset+block_row_size;++k)
2934 if(access_cols[k]>=first_upper_ghost)
2935 value += tile.mult(ieq,
2942 access_y[access_row_ids[i]*N+ieq] += alpha * value;
2952 template <
typename ValueT,
int EllPackSize>
2953 void MatrixInternal<ValueT, EllPackSize>::addExtUMult(ValueType alpha, ValueBufferType& x,
2954 ValueBufferType& y)
const
2956 this->addExtUMult(alpha, x, y, SYCLEnv::instance()->internal()->queue());
2959 template <
typename ValueT,
int EllPackSize>
2960 void MatrixInternal<ValueT, EllPackSize>::multDiag(ValueBufferType& x, ValueBufferType& y, sycl::queue& queue)
const
2964 template <
typename ValueT,
int EllPackSize>
2965 void MatrixInternal<ValueT, EllPackSize>::multDiag(ValueBufferType& x, ValueBufferType& y)
const
2967 this->multDiag(x, y, SYCLEnv::instance()->internal()->queue());
2970 template <
typename ValueT,
int EllPackSize>
2971 void MatrixInternal<ValueT, EllPackSize>::multDiag(ValueBufferType& y, sycl::queue& queue)
const
2973 throw NotImplementedException(
2974 A_FUNCINFO,
"MatrixInternal<ValueT, EllPackSize>::multDiag not implemented");
2977 template <
typename ValueT,
int EllPackSize>
2978 void MatrixInternal<ValueT, EllPackSize>::multDiag(ValueBufferType& y)
const
2980 this->multDiag(y, SYCLEnv::instance()->internal()->queue());
2983 template <
typename ValueT,
int EllPackSize>
2984 void MatrixInternal<ValueT, EllPackSize>::computeDiag(ValueBufferType& y, sycl::queue& queue)
const
2987 auto device = queue.get_device();
2989 auto num_groups = queue.get_device().get_info<sycl::info::device::max_compute_units>();
2991 auto max_work_group_size = queue.get_device().get_info<sycl::info::device::max_work_group_size>();
2993 auto total_threads = num_groups * ellpack_size;
2997 int NxN = this->m_NxN;
2998 int pack_size = ellpack_size ;
2999 auto nrows = m_profile->getNRows() ;
3000 auto nnz = m_profile->getNnz() ;
3002 auto internal_profile = m_profile->internal() ;
3003 auto& kcol = internal_profile->getKCol() ;
3004 auto& block_row_offset = internal_profile->getBlockRowOffset() ;
3005 auto& block_cols = internal_profile->getBlockCols() ;
3008 queue.submit([&](sycl::handler& cgh)
3010 auto access_block_row_offset = block_row_offset.template get_access<sycl::access::mode::read>(cgh);
3011 auto access_cols = block_cols.template get_access<sycl::access::mode::read>(cgh);
3012 auto access_values = m_values.template get_access<sycl::access::mode::read>(cgh);
3013 auto access_y = y.template get_access<sycl::access::mode::read_write>(cgh);
3016 cgh.parallel_for<
class compute_diag>(
3017 sycl::range<1>{total_threads},
3018 [=] (sycl::item<1> item_id)
3020 auto id = item_id.get_id(0);
3025 for (
auto i =
id; i < nrows; i += item_id.get_range()[0])
3027 auto block_id = i/pack_size ;
3028 auto local_id = i%pack_size ;
3030 auto begin = access_block_row_offset[block_id] ;
3031 auto end = access_block_row_offset[block_id+1]-access_block_row_offset[block_id] ;
3032 for(
int k=begin;k<end;++k)
3034 auto kcol = k*pack_size+local_id ;
3035 if((access_cols[kcol])==
int(i))
3036 access_y[i] = access_values[kcol] ;
3043 cgh.parallel_for<
class compute_diagN>(
3044 sycl::range<1>{total_threads},
3045 [=] (sycl::item<1> item_id)
3047 auto id = item_id.get_id(0);
3052 for (std::size_t i =
id; i < nrows; i += item_id.get_range()[0])
3054 auto block_id = i/pack_size ;
3055 auto local_id = i%pack_size ;
3057 int block_row_offset = access_block_row_offset[block_id] ;
3058 auto block_row_size = access_block_row_offset[block_id+1]-access_block_row_offset[block_id] ;
3059 for(
int k=0;k<block_row_size;++k)
3061 auto kcol = (block_row_offset+k)*pack_size+local_id ;
3062 std::size_t col = access_cols[kcol] ;
3065 for(
int ieq=0;ieq<N;++ieq)
3067 auto kval = (block_row_offset+k)*NxN + ieq*N + ieq ;
3068 access_y[i*N+ieq] = access_values[kval*pack_size+local_id] ;
3107 template <
typename ValueT,
int EllPackSize>
3108 void MatrixInternal<ValueT, EllPackSize>::computeBlockDiag(ValueBufferType& y, sycl::queue& queue)
const
3111 auto device = queue.get_device();
3113 auto num_groups = queue.get_device().get_info<sycl::info::device::max_compute_units>();
3115 auto max_work_group_size = queue.get_device().get_info<sycl::info::device::max_work_group_size>();
3117 auto total_threads = num_groups * ellpack_size;
3121 int NxN = this->m_NxN;
3122 int pack_size = ellpack_size ;
3123 auto nrows = m_profile->getNRows() ;
3124 auto nnz = m_profile->getNnz() ;
3126 assert(y.size()>=NxN*nrows) ;
3128 auto internal_profile = m_profile->internal() ;
3129 auto& kcol = internal_profile->getKCol() ;
3130 auto& block_row_offset = internal_profile->getBlockRowOffset() ;
3131 auto& block_cols = internal_profile->getBlockCols() ;
3133 ValueBufferType buffer (sycl::range<1>(nrows*NxN)) ;
3135 queue.submit([&](sycl::handler& cgh)
3137 auto access_block_row_offset = block_row_offset.template get_access<sycl::access::mode::read>(cgh);
3138 auto access_cols = block_cols.template get_access<sycl::access::mode::read>(cgh);
3139 auto matrix = m_values.template get_access<sycl::access::mode::read>(cgh);
3140 auto access_y = y.template get_access<sycl::access::mode::read_write>(cgh);
3141 auto A = buffer.template get_access<sycl::access::mode::read_write>(cgh);
3143 auto tile = Tile(N) ;
3144 cgh.parallel_for<
class compute_block_diag>(
3145 sycl::range<1>{total_threads},
3146 [=] (sycl::item<1> item_id)
3148 auto id = item_id.get_id(0);
3153 for (std::size_t global_id =
id; global_id < nrows; global_id += item_id.get_range()[0])
3155 auto block_id = global_id/pack_size ;
3156 auto local_id = global_id%pack_size ;
3158 int block_row_offset = access_block_row_offset[block_id] ;
3159 auto block_row_size = access_block_row_offset[block_id+1]-access_block_row_offset[block_id] ;
3160 for(
int k=0;k<block_row_size;++k)
3162 auto kcol = (block_row_offset+k)*ellpack_size+local_id ;
3163 std::size_t col = access_cols[kcol] ;
3167 for(
int i=0;i<N;++i)
3168 for(
int j=0;j<N;++j)
3169 A[tile._ij(local_id,i,j)] = matrix[tile._ijk(k,i,j)+local_id] ;
3179 template <
typename ValueT,
int EllPackSize>
3180 void MatrixInternal<ValueT, EllPackSize>::computeDiag(ValueBufferType& y)
const
3182 this->computeDiag(y, SYCLEnv::instance()->internal()->queue());
3185 template <
typename ValueT,
int EllPackSize>
3186 void MatrixInternal<ValueT, EllPackSize>::computeBlockDiag(ValueBufferType& y)
const
3188 this->computeBlockDiag(y, SYCLEnv::instance()->internal()->queue());
3192 template <
typename ValueT,
int EllPackSize>
3193 void MatrixInternal<ValueT, EllPackSize>::multInvDiag(ValueBufferType& y, sycl::queue& queue)
const
3195 throw NotImplementedException(
3196 A_FUNCINFO,
"MatrixInternal<ValueT, EllPackSize>::multInvDiag not implemented");
3199 template <
typename ValueT,
int EllPackSize>
3200 void MatrixInternal<ValueT, EllPackSize>::multInvDiag(ValueBufferType& y)
const
3202 this->multInvDiag(y, SYCLEnv::instance()->internal()->queue());
3205 template <
typename ValueT,
int EllPackSize>
3206 void MatrixInternal<ValueT, EllPackSize>::computeInvDiag(ValueBufferType& y, sycl::queue& queue)
const
3209 auto device = queue.get_device();
3211 auto num_groups = queue.get_device().get_info<sycl::info::device::max_compute_units>();
3213 auto max_work_group_size = queue.get_device().get_info<sycl::info::device::max_work_group_size>();
3217 int NxN = this->m_NxN;
3218 std::size_t pack_size = ellpack_size ;
3219 auto nrows = m_profile->getNRows() ;
3220 auto nnz = m_profile->getNnz() ;
3222 auto internal_profile = m_profile->internal() ;
3223 auto& kcol = internal_profile->getKCol() ;
3224 auto& block_row_offset = internal_profile->getBlockRowOffset() ;
3225 auto& block_cols = internal_profile->getBlockCols() ;
3227 auto blocks_needed = (nrows + ellpack_size - 1) / ellpack_size;
3228 auto blocks_target = std::max(blocks_needed, num_groups * 4UL);
3229 auto total_threads = blocks_target * ellpack_size;
3232 queue.submit([&](sycl::handler& cgh)
3234 auto access_block_row_offset = block_row_offset.template get_access<sycl::access::mode::read>(cgh);
3235 auto access_cols = block_cols.template get_access<sycl::access::mode::read>(cgh);
3236 auto access_values = m_values.template get_access<sycl::access::mode::read>(cgh);
3237 auto access_y = y.template get_access<sycl::access::mode::read_write>(cgh);
3241 sycl::nd_range<1> r{sycl::range<1>{total_threads},sycl::range<1>{pack_size}};
3243 cgh.parallel_for<
class compute_inv_diag>(r,
3244 [=](sycl::nd_item<1> item_id)
3246 auto local_id = item_id.get_local_id(0);
3247 auto global_id = item_id.get_global_id(0);
3248 for (
auto i = global_id; i < nrows; i += item_id.get_global_range()[0])
3250 auto block_id = i/pack_size ;
3253 int begin = access_block_row_offset[block_id];
3254 int end = access_block_row_offset[block_id+1];
3255 for(
int k=begin;k<end;++k)
3257 auto kcol = k*pack_size+local_id ;
3258 if((access_cols[kcol])==
int(i) && (access_values[kcol]!=0) )
3259 access_y[i] = 1./access_values[kcol] ;
3283 sycl::nd_range<1> r{sycl::range<1>{total_threads},sycl::range<1>{pack_size}};
3284 cgh.parallel_for<
class compute_inv_diagN>(r,
3285 [=](sycl::nd_item<1> item_id)
3287 auto local_id = item_id.get_local_id(0);
3288 auto global_id = item_id.get_global_id(0);
3289 for (
auto i = global_id; i < nrows; i += item_id.get_global_range()[0])
3291 auto block_id = i/pack_size ;
3293 int begin = access_block_row_offset[block_id];
3294 int end = access_block_row_offset[block_id+1];
3296 for(
int k=begin;k<end;++k)
3298 auto kcol = k*pack_size+local_id ;
3299 std::size_t col = access_cols[kcol] ;
3302 for(
int ieq=0;ieq<N;++ieq)
3304 auto kval = k*NxN + ieq*N + ieq ;
3305 auto diag = access_values[kval*pack_size+local_id] ;
3307 access_y[i*N+ieq] = 1./diag;
3309 access_y[i*N+ieq] = 1.;
3364 template <
typename ValueT,
int EllPackSize>
3365 void MatrixInternal<ValueT, EllPackSize>::computeInvBlockDiag(ValueBufferType& y, sycl::queue& queue)
const
3368 auto device = queue.get_device();
3370 auto num_groups = queue.get_device().get_info<sycl::info::device::max_compute_units>();
3372 auto max_work_group_size = queue.get_device().get_info<sycl::info::device::max_work_group_size>();
3374 auto total_threads = num_groups * ellpack_size;
3378 int NxN = this->m_NxN;
3379 int pack_size = ellpack_size ;
3380 auto nrows = m_profile->getNRows() ;
3381 auto nnz = m_profile->getNnz() ;
3383 assert(y.size()>=NxN*nrows) ;
3385 auto internal_profile = m_profile->internal() ;
3386 auto& kcol = internal_profile->getKCol() ;
3387 auto& block_row_offset = internal_profile->getBlockRowOffset() ;
3388 auto& block_cols = internal_profile->getBlockCols() ;
3390 ValueBufferType buffer (sycl::range<1>(internal_profile->m_block_nrows*NxN*pack_size)) ;
3392 queue.submit([&](sycl::handler& cgh)
3394 auto access_block_row_offset = block_row_offset.template get_access<sycl::access::mode::read>(cgh);
3395 auto access_cols = block_cols.template get_access<sycl::access::mode::read>(cgh);
3396 auto matrix = m_values.template get_access<sycl::access::mode::read>(cgh);
3397 auto access_y = y.template get_access<sycl::access::mode::read_write>(cgh);
3398 auto A = buffer.template get_access<sycl::access::mode::read_write>(cgh);
3400 auto lu = LU<
decltype(matrix),
decltype(access_y),
decltype(A)>{N,matrix} ;
3403 cgh.parallel_for<
class compute_inv_block_diag>(
3404 sycl::range<1>{total_threads},
3405 [=] (sycl::item<1> item_id)
3407 auto id = item_id.get_id(0);
3412 for (std::size_t global_id =
id; global_id < nrows; global_id += item_id.get_range()[0])
3414 auto block_id = global_id/pack_size ;
3415 auto local_id = global_id%pack_size ;
3417 int begin = access_block_row_offset[block_id];
3418 int end = access_block_row_offset[block_id+1];
3419 for(
int k=begin;k<end;++k)
3421 auto kcol = k*pack_size+local_id ;
3422 std::size_t col = access_cols[kcol] ;
3425 lu.factorize(global_id,
3431 lu.inverse(global_id,
3493#ifdef PRINT_DEBUG_INFO
3495 sycl::host_accessor<ValueT, 1, sycl::access::mode::read> h_acc(y);
3496 sycl::host_accessor<ValueT, 1, sycl::access::mode::read> mat_acc(m_values);
3497 sycl::host_accessor<int, 1, sycl::access::mode::read> kcol_acc(block_row_offset);
3498 sycl::host_accessor<int, 1, sycl::access::mode::read> cols_acc(block_cols);
3499 std::vector<ValueT> test_y(nrows*NxN) ;
3500 std::vector<ValueT> test_A(internal_profile->m_block_nrows*NxN*pack_size) ;
3501 auto lu = LU<
decltype(mat_acc),
decltype(test_y.data()),
decltype(test_A.data())>{N,mat_acc} ;
3502 for(
int irow=0;irow<nrows;++irow)
3504 auto ib=irow/ellpack_size ;
3505 auto il=irow%ellpack_size ;
3507 cout() <<
"MAT["<<irow<<
","<<ib<<
"]:";
3509 for(
int k=kcol_acc[ib];k<kcol_acc[ib+1];++k)
3512 cout() <<
"\tCOLS["<<k<<
"] = "<<cols_acc[k*pack_size+il];
3521 if(cols_acc[k*pack_size+il]==irow)
3525 cout() <<
"\tCOMPUTE INVERSE["<<cols_acc[k*pack_size+il]<<
"]" ;
3526 for(
int i=0;i<N;++i)
3528 for(
int j=0;j<N;++j)
3529 cout()<<mat_acc[(k*NxN+i*N+j)*pack_size+il]<<
" ";
3545 for(
int i=0;i<N;++i)
3547 for(
int j=0;j<N;++j)
3548 std::cout<<test_y[irow*NxN+i*N+j]<<
",";
3549 std::cout<<std::endl;
3555 for(
int irow=0;irow<nrows;++irow)
3557 auto ib=irow/ellpack_size ;
3558 auto il=irow%ellpack_size ;
3560 cout()<<
"INV BLOCK DIAG["<<irow<<
","<<il<<
"]:\n";
3561 for(
int i=0;i<N;++i)
3563 for(
int j=0;j<N;++j)
3564 cout()<<h_acc[irow*NxN+i*N+j]<<
",";
3574 template <
typename ValueT,
int EllPackSize>
3575 void MatrixInternal<ValueT, EllPackSize>::computeInvDiag(ValueBufferType& y)
const
3577 this->computeInvDiag(y, SYCLEnv::instance()->internal()->queue());
3580 template <
typename ValueT,
int EllPackSize>
3581 void MatrixInternal<ValueT, EllPackSize>::computeInvBlockDiag(ValueBufferType& y)
const
3583 this->computeInvBlockDiag(y, SYCLEnv::instance()->internal()->queue());
3587 template <
typename ValueT,
int EllPackSize>
3588 void MatrixInternal<ValueT, EllPackSize>::scal(ValueBufferType& y, sycl::queue& queue)
3591 auto device = queue.get_device();
3593 auto num_groups = queue.get_device().get_info<sycl::info::device::max_compute_units>();
3595 auto max_work_group_size = queue.get_device().get_info<sycl::info::device::max_work_group_size>();
3597 auto total_threads = num_groups * ellpack_size;
3600 auto nrows = m_profile->getNRows() ;
3601 auto nnz = m_profile->getNnz() ;
3603 auto internal_profile = m_profile->internal() ;
3604 auto& kcol = internal_profile->getKCol() ;
3605 auto& block_row_offset = internal_profile->getBlockRowOffset() ;
3606 auto& block_cols = internal_profile->getBlockCols() ;
3609 queue.submit([&](sycl::handler& cgh)
3611 auto access_block_row_offset = block_row_offset.template get_access<sycl::access::mode::read>(cgh);
3612 auto access_cols = block_cols.template get_access<sycl::access::mode::read>(cgh);
3613 auto access_values = m_values.template get_access<sycl::access::mode::read_write>(cgh);
3614 auto access_y = y.template get_access<sycl::access::mode::read>(cgh);
3617 cgh.parallel_for<
class scal_matrix>(sycl::range<1>{total_threads},
3618 [=] (sycl::item<1> item_id)
3620 auto id = item_id.get_id(0);
3625 for (
auto i =
id; i < nrows; i += item_id.get_range()[0])
3627 auto block_id = i/ellpack_size ;
3628 auto local_id = i%ellpack_size ;
3630 int block_row_offset = access_block_row_offset[block_id]*ellpack_size ;
3631 auto block_row_size = access_block_row_offset[block_id+1]-access_block_row_offset[block_id] ;
3632 for(
int j=0;j<block_row_size;++j)
3634 auto k = block_row_offset+j*ellpack_size+local_id ;
3635 access_values[k] *= access_y[i] ;
3645 auto interface_nrows = m_ext_profile->getNRows();
3646 auto ext_nnz = m_ext_profile->getNnz();
3647 auto ext_block_nnz = m_ext_profile->getBlockNnz();
3649 auto ext_internal_profile = m_ext_profile->internal();
3650 auto& ext_block_row_offset = ext_internal_profile->getBlockRowOffset();
3653 queue.submit([&](sycl::handler& cgh)
3655 auto access_block_row_offset = ext_block_row_offset.template get_access<sycl::access::mode::read>(cgh);
3656 auto access_block_values = m_ext_values->template get_access<sycl::access::mode::read_write>(cgh);
3657 auto access_row_ids = m_interface_row_ids->template get_access<sycl::access::mode::read>(cgh);
3658 auto access_y = y.template get_access<sycl::access::mode::read>(cgh);
3660 cgh.parallel_for<
class set_matrix_values7>(sycl::range<1>{total_threads},
3661 [=] (sycl::item<1> item_id)
3663 auto id = item_id.get_id(0);
3665 for (
auto i =
id; i < interface_nrows; i += item_id.get_range()[0])
3667 auto block_id = i/ellpack_size ;
3668 auto local_id = i%ellpack_size ;
3669 auto begin = access_block_row_offset[block_id] ;
3670 auto end = access_block_row_offset[block_id+1] ;
3672 for(
int k=begin;k<end;++k)
3674 access_block_values[k*ellpack_size+local_id] *= access_y[access_row_ids[i]] ;
3683 template <
typename ValueT,
int EllPackSize>
3684 void MatrixInternal<ValueT, EllPackSize>::scal(ValueBufferType& y)
3686 this->scal(y, SYCLEnv::instance()->internal()->queue());
3689 template <
typename ValueT,
int EllPackSize>
3690 void MatrixInternal<ValueT, EllPackSize>::
3691 copyDevicePointers(
int local_offset,
3697 ValueT* values)
const
3699#ifdef PRINT_DEBUG_INFO
3701 cout()<<
"SYCLMATRIX COPY DEVICE POINTERS : "<<nrows<<
" "<<nnz;
3705 auto env = SYCLEnv::instance() ;
3706 auto max_num_threads = env->maxNumThreads() ;
3707 auto& queue = env->internal()->queue() ;
3708 auto pack_size = ellpack_size;
3710 auto internal_profile = m_profile->internal() ;
3711 auto& kcol = internal_profile->getKCol() ;
3712 auto& block_row_offset = internal_profile->getBlockRowOffset() ;
3713 auto& block_cols = internal_profile->getBlockCols() ;
3715 auto local_row_size = m_profile->localRowSize();
3741 if(local_row_size ==
nullptr)
3744 queue.submit( [&](sycl::handler& cgh)
3746 auto acc_val = m_values.template get_access<sycl::access::mode::read>(cgh);
3747 auto acc_bkcol = block_row_offset.template get_access<sycl::access::mode::read>(cgh);
3748 auto acc_cols = block_cols.template get_access<sycl::access::mode::read>(cgh);
3749 auto acc_kcol = kcol.template get_access<sycl::access::mode::read>(cgh);
3750 cgh.parallel_for<
class copy_device_ptr>(
3751 sycl::range<1>{max_num_threads},
3752 [=] (sycl::item<1> itemId)
3754 auto id = itemId.get_id(0);
3755 for (
auto i =
id; i < nrows; i += itemId.get_range()[0])
3757 auto block_id = i/pack_size ;
3758 auto local_id = i%pack_size ;
3760 int begin = acc_bkcol[block_id] ;
3761 int end = acc_bkcol[block_id+1] ;
3762 int row_size = acc_kcol[i+1] - acc_kcol[i];
3764 rows[i] = (int) (local_offset + i) ;
3765 ncols[i] = row_size ;
3767 auto offset = acc_kcol[i];
3769 for(
int k=begin;k<end;++k)
3774 values[offset+j] = acc_val[k*pack_size+local_id] ;
3775 cols[offset+j] = acc_cols[k*pack_size+local_id] ;
3781#ifdef PRINT_DEBUG_INFO
3783 std::vector<ValueT> h_data(nnz) ;
3784 queue.memcpy(h_data.data(), values, nnz *
sizeof(ValueT)).wait();
3785 std::vector<int> h_cols(nnz) ;
3786 queue.memcpy(h_cols.data(), cols, nnz *
sizeof(
int)).wait();
3787 sycl::host_accessor<int, 1, sycl::access::mode::read> h_kcol(kcol);
3789 cout()<<
"SYCL DEVICE COPY : "<<nrows<<
" "<<nnz;
3790 for(
int irow=0;irow<nrows;++irow)
3792 cout()<<
"COPY MAT["<<irow<<
"]:"<<h_kcol[irow+1]-h_kcol[irow];
3793 for(
int k=h_kcol[irow];k<h_kcol[irow+1];++k)
3795 std::cout<<h_cols[k]<<
" "<<h_data[k]<<
" ";
3797 std::cout<<std::endl ;
3806 IndexBufferType lrowsize(local_row_size, sycl::range<1>(nrows));
3807 queue.submit( [&](sycl::handler& cgh)
3809 auto acc_val = m_values.template get_access<sycl::access::mode::read>(cgh);
3810 auto acc_bkcol = block_row_offset.template get_access<sycl::access::mode::read>(cgh);
3811 auto acc_cols = block_cols.template get_access<sycl::access::mode::read>(cgh);
3812 auto acc_kcol = kcol.template get_access<sycl::access::mode::read>(cgh);
3813 auto acc_lrowsize = lrowsize.template get_access<sycl::access::mode::read>(cgh);
3814 cgh.parallel_for<
class copy_device_ptr>(
3815 sycl::range<1>{max_num_threads},
3816 [=] (sycl::item<1> itemId)
3818 auto id = itemId.get_id(0);
3819 for (
auto i =
id; i < nrows; i += itemId.get_range()[0])
3821 auto block_id = i/pack_size ;
3822 auto local_id = i%pack_size ;
3824 int begin = acc_bkcol[block_id] ;
3825 int end = acc_bkcol[block_id+1] ;
3826 int row_size = acc_kcol[i+1] - acc_kcol[i];
3827 int lrow_size = acc_lrowsize[i] ;
3828 rows[i] = (int) (local_offset + i) ;
3829 ncols[i] = row_size ;
3831 auto offset = acc_kcol[i];
3833 for(
int k=begin;k<end;++k)
3838 values[offset+j] = acc_val[k*pack_size+local_id];
3839 cols[offset+j] = local_offset + acc_cols[k*pack_size+local_id];
3846 assert(m_ext_profile) ;
3848 auto interface_nrows = m_ext_profile->getNRows();
3849 auto ext_nnz = m_ext_profile->getNnz();
3850 auto ext_block_nnz = m_ext_profile->getBlockNnz();
3852 auto ext_internal_profile = m_ext_profile->internal();
3853 auto& ext_block_row_offset = ext_internal_profile->getBlockRowOffset();
3854 auto& ext_block_cols = ext_internal_profile->getBlockCols() ;
3856 queue.submit([&](sycl::handler& cgh)
3858 auto acc_kcol = kcol.template get_access<sycl::access::mode::read>(cgh);
3859 auto acc_ext_bkcol = ext_block_row_offset.template get_access<sycl::access::mode::read>(cgh);
3860 auto acc_ext_cols = ext_block_cols.template get_access<sycl::access::mode::read>(cgh);
3861 auto acc_ext_values = m_ext_values->template get_access<sycl::access::mode::read_write>(cgh);
3862 auto acc_row_ids = m_interface_row_ids->template get_access<sycl::access::mode::read>(cgh);
3863 auto acc_lrowsize = lrowsize.template get_access<sycl::access::mode::read>(cgh);
3864 auto acc_recv_uids = m_recv_uids->template get_access<sycl::access::mode::read>(cgh);
3866 cgh.parallel_for<
class ext_copy_device_ptr>(
3867 sycl::range<1>{max_num_threads},
3868 [=] (sycl::item<1> item_id)
3870 auto id = item_id.get_id(0);
3872 for (
auto i =
id; i < interface_nrows; i += item_id.get_range()[0])
3874 auto block_id = i/pack_size ;
3875 auto local_id = i%pack_size ;
3876 auto begin = acc_ext_bkcol[block_id] ;
3877 auto end = acc_ext_bkcol[block_id+1] ;
3879 auto row_id = acc_row_ids[i];
3880 int row_size = acc_kcol[row_id+1] - acc_kcol[row_id];
3881 int lrow_size = acc_lrowsize[row_id] ;
3882 auto offset = acc_kcol[row_id] + lrow_size;
3884 for(
int k=begin;k<end;++k)
3887 if(j<row_size-lrow_size)
3889 values[offset+j] = acc_ext_values[k*pack_size+local_id] ;
3890 cols[offset+j] = acc_recv_uids[acc_ext_cols[k*pack_size+local_id]] ;
3896#ifdef PRINT_DEBUG_INFO
3898 std::vector<ValueT> h_data(nnz) ;
3899 queue.memcpy(h_data.data(), values, nnz *
sizeof(ValueT)).wait();
3900 std::vector<int> h_cols(nnz) ;
3901 queue.memcpy(h_cols.data(), cols, nnz *
sizeof(
int)).wait();
3902 sycl::host_accessor<int, 1, sycl::access::mode::read> h_kcol(kcol);
3904 cout()<<
"SYCL DEVICE COPY : "<<nrows<<
" "<<nnz<<
" "<<ext_nnz<<
" "<<interface_nrows;
3905 for(
int irow=0;irow<nrows;++irow)
3907 std::cout<<
"COPY MAT["<<irow<<
"]:"<<local_row_size[irow]<<
" "<<h_kcol[irow+1]-h_kcol[irow];
3908 for(
int k=h_kcol[irow];k<h_kcol[irow+1];++k)
3910 std::cout<<h_cols[k]<<
" "<<h_data[k]<<
" ";
3912 std::cout<<std::endl ;
3924template <
typename ValueT>
3927, m_send_policy(SimpleCSRInternal::CommProperty::ASynch)
3928, m_recv_policy(SimpleCSRInternal::CommProperty::ASynch)
3931template <
typename ValueT>
3934, m_send_policy(SimpleCSRInternal::CommProperty::ASynch)
3935, m_recv_policy(SimpleCSRInternal::CommProperty::ASynch)
3938template <
typename ValueT>
3941#ifdef ALIEN_USE_PERF_TIMER
3942 m_timer.printInfo(
"SYCLBELLPACK-MATRIX");
3946template <
typename ValueT>
3948initMatrix(Arccore::MessagePassing::IMessagePassingMng* parallel_mng,
3949 Integer local_offset,
3950 Integer global_size,
3957#ifdef PRINT_DEBUG_INFO
3959 cout()<<
"SYCLBellPackMatrix::initMatrix : "<<local_offset<<
" "<<nrows<<
" "<<global_size;
3960 cout()<<
"ParalleMng : "<<parallel_mng;
3966 m_parallel_mng = parallel_mng;
3968 m_nproc = m_parallel_mng->commSize();
3969 m_myrank = m_parallel_mng->commRank();
3971 m_is_parallel = (m_nproc > 1);
3974 m_matrix_dist_info.copy(matrix_dist_info);
3976 m_ellpack_size = PKSIZE;
3979 m_local_size = nrows;
3980 m_local_offset = local_offset;
3981 m_global_size = global_size;
3983 m_ghost_size = m_matrix_dist_info.m_ghost_nrow;
3985 auto& local_row_size = m_matrix_dist_info.m_local_row_size;
3986 auto sorted_cols = m_matrix_dist_info.m_cols.data();
3988 std::size_t block_nrows = ProfileInternalType::nbBlocks(nrows);
3990 ProfileInternalType::computeBlockRowOffset(m_block_row_offset, nrows, kcol);
3994 cout() <<
"OFFSET = "<<m_local_offset ;
3995 cout() <<
"NROWS = "<<nrows;
3996 cout() <<
"NNZ = "<<kcol[nrows];
3997 cout() <<
"BNROWS = "<<block_nrows;
3998 cout() <<
"BNNZ = "<<m_block_row_offset[block_nrows];
4002 m_profilePKSIZE.reset(
new ProfileInternalType{ nrows,
4005 m_block_row_offset.data(),
4006 local_row_size.data() });
4008 m_matrixPKSIZE.reset(
new MatrixInternalType{ m_profilePKSIZE.get(), block_size });
4011 std::size_t interface_nrows = m_matrix_dist_info.m_interface_nrow;
4012 std::vector<int> ext_kcol(interface_nrows + 1);
4015 for (std::size_t i = 0; i < interface_nrows; ++i) {
4016 auto id = m_matrix_dist_info.m_interface_rows[i];
4017 ext_kcol[i] = ext_nnz;
4018 ext_nnz += kcol[
id + 1] - kcol[id] - local_row_size[id];
4020 ext_kcol[interface_nrows] = ext_nnz;
4022 std::vector<int> ext_cols(ext_nnz);
4025 for (std::size_t i = 0; i < interface_nrows; ++i) {
4026 auto id = m_matrix_dist_info.m_interface_rows[i];
4027 for (
int k = kcol[
id] + local_row_size[
id]; k < kcol[
id + 1]; ++k) {
4028 ext_cols[jcol++] = (int)(sorted_cols[k] - nrows);
4033 std::size_t ext_block_nrows = ProfileInternalType::nbBlocks(interface_nrows);
4034 ProfileInternalType::computeBlockRowOffset(m_ext_block_row_offset, interface_nrows, ext_kcol.data());
4037 cout() <<
"EXT NROWS = "<<interface_nrows;
4038 cout() <<
"EXT NNZ = "<<ext_kcol[interface_nrows];
4039 cout() <<
"EXT BNROWS = "<<ext_block_nrows;
4040 cout() <<
"EXT BNNZ = "<<m_block_row_offset[ext_block_nrows];
4044 m_ext_profilePKSIZE.reset(
new ProfileInternalType{ interface_nrows,
4047 m_ext_block_row_offset.data(),
4050 m_matrixPKSIZE->m_ext_profile = m_ext_profilePKSIZE.get();
4051 typedef typename MatrixInternalType::IndexBufferType IndexBufferType;
4052 m_matrixPKSIZE->m_h_interface_row_ids = m_matrix_dist_info.m_interface_rows.data();
4053 m_matrixPKSIZE->m_interface_row_ids.reset(
new IndexBufferType{ m_matrix_dist_info.m_interface_rows.data(),
4054 m_matrix_dist_info.m_interface_rows.size() });
4056 m_matrixPKSIZE->m_send_ids.reset(
new IndexBufferType{ m_matrix_dist_info.m_send_info.m_ids.data(),
4057 m_matrix_dist_info.m_send_info.m_ids.size() });
4058 m_matrixPKSIZE->m_recv_ids.reset(
new IndexBufferType{ m_matrix_dist_info.m_recv_info.m_ids.data(),
4059 m_matrix_dist_info.m_recv_info.m_ids.size() });
4060 m_matrixPKSIZE->m_recv_uids.reset(
new IndexBufferType{ m_matrix_dist_info.m_recv_info.m_uids.data(),
4061 m_matrix_dist_info.m_recv_info.m_uids.size() });
4067 m_local_size = nrows;
4068 m_global_size = m_local_size;
4072 std::size_t block_nrows = ProfileInternalType::nbBlocks(nrows);
4074 ProfileInternalType::computeBlockRowOffset(m_block_row_offset, nrows, kcol);
4078 cout() <<
"NROWS = "<<nrows;
4079 cout() <<
"NNZ = "<<kcol[nrows];
4080 cout() <<
"BNROWS = "<<block_nrows;
4081 cout() <<
"BNNZ = "<<m_block_row_offset[block_nrows];
4085 m_profilePKSIZE.reset(
new ProfileInternalType{ nrows,
4088 m_block_row_offset.data(),
4091 m_matrixPKSIZE.reset(
new MatrixInternalType{ m_profilePKSIZE.get(), block_size });
4092 m_matrixPKSIZE->m_first_upper_ghost_index = m_matrix_dist_info.m_first_upper_ghost_index - m_local_size;
4098template <
typename ValueT>
4100SYCLBEllPackMatrix<ValueT>::cloneTo(
const MultiMatrixImpl* multi)
const
4102 auto block_size = blockSize() ;
4104 matrix->setBlockSize(block_size);
4105 matrix->initMatrix(m_parallel_mng,
4108 m_profilePKSIZE->getNRows(),
4109 m_profilePKSIZE->kcol(),
4110 m_profilePKSIZE->cols(),
4113 matrix->setMatrixValues(getAddressData(),
true);
4117template <
typename ValueT>
4118bool SYCLBEllPackMatrix<ValueT>::setMatrixValues(Arccore::Real
const* values,
bool only_host)
4120 return m_matrixPKSIZE->setMatrixValues(values, only_host);
4123template <
typename ValueT>
4124void SYCLBEllPackMatrix<ValueT>::notifyChanges()
4126 if (m_matrixPKSIZE.get())
4127 m_matrixPKSIZE->notifyChanges();
4130template <
typename ValueT>
4131void SYCLBEllPackMatrix<ValueT>::endUpdate()
4133 if (m_matrixPKSIZE.get() && m_matrixPKSIZE->needUpdate()) {
4134 m_matrixPKSIZE->endUpdate();
4135 this->updateTimestamp();
4139template <
typename ValueT>
4140ValueT
const* SYCLBEllPackMatrix<ValueT>::getAddressData()
const
4142 return m_matrixPKSIZE->getHCsrData();
4145template <
typename ValueT>
4146ValueT
const* SYCLBEllPackMatrix<ValueT>::data()
const
4148 return m_matrixPKSIZE->getHCsrData();
4151template <
typename ValueT>
4152ValueT* SYCLBEllPackMatrix<ValueT>::getAddressData()
4154 return m_matrixPKSIZE->getHCsrData();
4157template <
typename ValueT>
4158ValueT* SYCLBEllPackMatrix<ValueT>::data()
4160 return m_matrixPKSIZE->getHCsrData();
4163template <
typename ValueT>
4166 return m_matrixPKSIZE->mult(x.internal()->values(), y.internal()->values());
4169template <
typename ValueT>
4172 m_matrixPKSIZE->addExtMult(x.internal()->ghostValues(getGhostSize()*blockSize()), y.internal()->values());
4175template <
typename ValueT>
4178 m_profilePKSIZE->dcol();
4179 return m_matrixPKSIZE->addLMult(alpha, x.internal()->values(), y.internal()->values());
4182template <
typename ValueT>
4185 m_matrixPKSIZE->addExtLMult(alpha, x.internal()->ghostValues(getGhostSize()*blockSize()), y.internal()->values());
4188template <
typename ValueT>
4191 m_profilePKSIZE->dcol();
4192 return m_matrixPKSIZE->addUMult(alpha, x.internal()->values(), y.internal()->values());
4195template <
typename ValueT>
4198 m_matrixPKSIZE->addExtUMult(alpha, x.internal()->ghostValues(getGhostSize()*blockSize()), y.internal()->values());
4201template <
typename ValueT>
4204 return m_matrixPKSIZE->multDiag(x.internal()->values(), y.internal()->values());
4207template <
typename ValueT>
4210 return m_matrixPKSIZE->multDiag(y.internal()->values());
4213template <
typename ValueT>
4216 auto block_size = blockSize() ;
4217 if((y.blockSize()==1)||(y.blockSize()==block_size))
4218 return m_matrixPKSIZE->computeDiag(y.internal()->values());
4219 else if(y.blockSize()==block_size*block_size)
4220 return m_matrixPKSIZE->computeBlockDiag(y.internal()->values());
4222 throw Arccore::FatalErrorException(A_FUNCINFO,
"Matrix and Vector Block Size are not compatibility");
4225template <
typename ValueT>
4228 return m_matrixPKSIZE->multInvDiag(y.internal()->values());
4231template <
typename ValueT>
4234 auto block_size = blockSize() ;
4235 if((y.blockSize()==1)||(y.blockSize()==block_size))
4236 return m_matrixPKSIZE->computeInvDiag(y.internal()->values());
4237 else if(y.blockSize()==block_size*block_size)
4238 return m_matrixPKSIZE->computeInvBlockDiag(y.internal()->values());
4240 throw Arccore::FatalErrorException(A_FUNCINFO,
"Matrix and Vector Block Size are not compatibility");
4243template <
typename ValueT>
4246 return m_matrixPKSIZE->scal(diag.internal()->values());
4250template <
typename ValueT>
4253 auto block_size = blockSize() ;
4254 initMatrix(matrix.m_parallel_mng,
4255 matrix.m_local_offset,
4256 matrix.m_global_size,
4257 matrix.m_profilePKSIZE->getNRows(),
4258 matrix.m_profilePKSIZE->kcol(),
4259 matrix.m_profilePKSIZE->cols(),
4260 matrix.m_matrix_dist_info,
4262 if(block_size==matrix.blockSize())
4265 m_matrixPKSIZE->setMatrixValues(matrix.m_matrixPKSIZE->m_values,
4266 (*matrix.m_matrixPKSIZE->m_ext_values));
4268 m_matrixPKSIZE->setMatrixValues(matrix.m_matrixPKSIZE->m_values);
4272 assert(m_profilePKSIZE.get());
4273 assert(m_matrixPKSIZE.get());
4274 auto nb_blocks = m_profilePKSIZE->getBlockNnz();
4276 m_matrixPKSIZE->copy(nb_blocks,
4278 matrix.m_matrixPKSIZE->m_values,
4279 (*matrix.m_matrixPKSIZE->m_ext_values),
4280 matrix.blockSize()) ;
4282 m_matrixPKSIZE->copy(nb_blocks,
4284 matrix.m_matrixPKSIZE->m_values,
4285 matrix.blockSize()) ;
4289template <
typename ValueT>
4296 ValueT** values)
const
4298 auto env = SYCLEnv::instance() ;
4299 auto max_num_treads = env->maxNumThreads() ;
4300 auto& queue = env->internal()->queue() ;
4301 auto rows_ptr = malloc_device<IndexType>(nrows, queue);
4302 auto ncols_ptr = malloc_device<IndexType>(nrows, queue);
4303 auto cols_ptr = malloc_device<IndexType>(nnz, queue);
4304 auto values_ptr = malloc_device<ValueT>(nnz, queue);
4307 *ncols = ncols_ptr ;
4309 *values = values_ptr ;
4312template <
typename ValueT>
4316 auto env = SYCLEnv::instance() ;
4317 auto& queue = env->internal()->queue() ;
4318 sycl::free(rows,queue) ;
4319 sycl::free(ncols,queue) ;
4320 sycl::free(cols,queue) ;
4321 sycl::free(values,queue) ;
4325template <
typename ValueT>
4332 ValueT* values)
const
4334 m_matrixPKSIZE->copyDevicePointers(m_local_offset,nrows,nnz,rows,ncols,cols,values) ;
4338template <
typename ValueT>
4339SYCLBEllPackMatrix<ValueT>::HCSRView
4340SYCLBEllPackMatrix<ValueT>::hcsrView(BackEnd::Memory::eType memory,
int nrows,
int nnz)
const
4342 return HCSRView(
this,memory, nrows, nnz) ;
4353void force_int_instance()
4356 SYCLBEllPackMatrix<double>::MatrixInternalType::ValueBufferType buffer{sycl::range<1>(10)} ;
4357 matrix.internal()->setMatrixValues(buffer) ;
4358 std::size_t pack_size =SYCLBEllPackMatrix<double>::MatrixInternalType::ellpack_size ;
IMatrixImpl(const MultiMatrixImpl *multi_impl, BackEndId backend="")
Constructor.
Multi matrices representation container.
virtual ~SYCLBEllPackMatrix()
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --