spla
cl_format_dense_vec.hpp
Go to the documentation of this file.
1 /**********************************************************************************/
2 /* This file is part of spla project */
3 /* https://github.com/SparseLinearAlgebra/spla */
4 /**********************************************************************************/
5 /* MIT License */
6 /* */
7 /* Copyright (c) 2023 SparseLinearAlgebra */
8 /* */
9 /* Permission is hereby granted, free of charge, to any person obtaining a copy */
10 /* of this software and associated documentation files (the "Software"), to deal */
11 /* in the Software without restriction, including without limitation the rights */
12 /* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell */
13 /* copies of the Software, and to permit persons to whom the Software is */
14 /* furnished to do so, subject to the following conditions: */
15 /* */
16 /* The above copyright notice and this permission notice shall be included in all */
17 /* copies or substantial portions of the Software. */
18 /* */
19 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR */
20 /* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, */
21 /* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE */
22 /* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER */
23 /* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, */
24 /* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE */
25 /* SOFTWARE. */
26 /**********************************************************************************/
27 
28 #ifndef SPLA_CL_FORMAT_DENSE_VEC_HPP
29 #define SPLA_CL_FORMAT_DENSE_VEC_HPP
30 
31 #include <opencl/cl_counter.hpp>
32 #include <opencl/cl_debug.hpp>
33 #include <opencl/cl_formats.hpp>
37 
38 namespace spla {
39 
45  template<typename T>
46  void cl_dense_vec_resize(const std::size_t n_rows,
47  CLDenseVec<T>& storage) {
48  const std::size_t buffer_size = n_rows * sizeof(T);
49  const auto flags = CL_MEM_READ_WRITE | CL_MEM_HOST_NO_ACCESS;
50 
51  cl::Buffer buffer(get_acc_cl()->get_context(), flags, buffer_size);
52  storage.Ax = std::move(buffer);
53  }
54 
55  template<typename T>
56  void cl_dense_vec_fill_value(const std::size_t n_rows,
57  const T value,
58  CLDenseVec<T>& storage) {
59  cl_fill_value<T>(get_acc_cl()->get_queue_default(), storage.Ax, n_rows, value);
60  }
61 
62  template<typename T>
63  void cl_dense_vec_init(const std::size_t n_rows,
64  const T* values,
65  CLDenseVec<T>& storage) {
66  assert(values);
67 
68  const std::size_t buffer_size = n_rows * sizeof(T);
69  const auto flags = CL_MEM_READ_WRITE | CL_MEM_HOST_NO_ACCESS | CL_MEM_COPY_HOST_PTR;
70 
71  cl::Buffer buffer(get_acc_cl()->get_context(), flags, buffer_size, (void*) values);
72  storage.Ax = std::move(buffer);
73  }
74 
75  template<typename T>
76  void cl_dense_vec_read(const std::size_t n_rows,
77  T* values,
78  CLDenseVec<T>& storage,
79  cl::CommandQueue& queue,
80  cl_mem_flags staging_flags = CL_MEM_READ_ONLY | CL_MEM_HOST_READ_ONLY | CL_MEM_ALLOC_HOST_PTR,
81  bool blocking = true) {
82  const std::size_t buffer_size = n_rows * sizeof(T);
83  cl::Buffer staging(get_acc_cl()->get_context(), staging_flags, buffer_size);
84 
85  queue.enqueueCopyBuffer(storage.Ax, staging, 0, 0, buffer_size);
86  queue.enqueueReadBuffer(staging, blocking, 0, buffer_size, values);
87  }
88 
89  template<typename T>
90  void cl_dense_vec_to_coo(const std::size_t n_rows,
91  const T fill_value,
92  const CLDenseVec<T>& in,
93  CLCooVec<T>& out,
94  cl::CommandQueue& queue) {
95 
96  CLProgramBuilder builder;
97  builder.set_name("vector_format")
98  .add_type("TYPE", get_ttype<T>().template as<Type>())
99  .set_source(source_vector_formats)
100  .acquire();
101 
102  auto* acc = get_acc_cl();
103 
104  CLCounterWrapper cl_count;
105  cl::Buffer temp_Ri(acc->get_context(), CL_MEM_WRITE_ONLY | CL_MEM_HOST_NO_ACCESS, n_rows * sizeof(uint));
106  cl::Buffer temp_Rx(acc->get_context(), CL_MEM_WRITE_ONLY | CL_MEM_HOST_NO_ACCESS, n_rows * sizeof(T));
107 
108  cl_count.set(queue, 0);
109 
110  uint block_size = acc->get_default_wgs();
111  uint n_groups_to_dispatch = std::max(std::min(uint(n_rows) / block_size, uint(1024)), uint(1));
112 
113  cl::NDRange global(block_size * n_groups_to_dispatch);
114  cl::NDRange local(block_size);
115 
116  auto kernel = builder.make_kernel("dense_to_sparse");
117  kernel.setArg(0, in.Ax);
118  kernel.setArg(1, temp_Ri);
119  kernel.setArg(2, temp_Rx);
120  kernel.setArg(3, cl_count.buffer());
121  kernel.setArg(4, uint(n_rows));
122  kernel.setArg(5, fill_value);
123 
124  queue.enqueueNDRangeKernel(kernel, cl::NDRange(), global, local);
125  uint count = cl_count.get(queue);
126 
127  if (count == 0) {
128  LOG_MSG(Status::Ok, "nothing to do");
129 
130  out.values = 0;
131  out.Ai = cl::Buffer();
132  out.Ax = cl::Buffer();
133  return;
134  }
135 
136  out.values = count;
137  out.Ai = cl::Buffer(acc->get_context(), CL_MEM_READ_WRITE | CL_MEM_HOST_NO_ACCESS, count * sizeof(uint));
138  out.Ax = cl::Buffer(acc->get_context(), CL_MEM_READ_WRITE | CL_MEM_HOST_NO_ACCESS, count * sizeof(T));
139 
140  queue.enqueueCopyBuffer(temp_Ri, out.Ai, 0, 0, count * sizeof(uint));
141  queue.enqueueCopyBuffer(temp_Rx, out.Ax, 0, 0, count * sizeof(T));
142  CL_FINISH(queue);
143  }
144 
149 }// namespace spla
150 
151 #endif//SPLA_CL_FORMAT_DENSE_VEC_HPP
#define CL_FINISH(queue)
Definition: cl_debug.hpp:34
OpenCL list-of-coordinates sparse vector representation.
Definition: cl_formats.hpp:77
cl::Buffer Ax
Definition: cl_formats.hpp:84
cl::Buffer Ai
Definition: cl_formats.hpp:83
Definition: cl_counter.hpp:58
uint get(cl::CommandQueue &queue, cl::Event *event=nullptr)
Definition: cl_counter.cpp:53
cl::Buffer & buffer()
Definition: cl_counter.cpp:59
void set(cl::CommandQueue &queue, uint value, cl::Event *event=nullptr)
Definition: cl_counter.cpp:56
OpenCL one-dim array for dense vector representation.
Definition: cl_formats.hpp:61
cl::Buffer Ax
Definition: cl_formats.hpp:67
Runtime opencl program builder.
Definition: cl_program_builder.hpp:55
CLProgramBuilder & set_name(const char *name)
Definition: cl_program_builder.cpp:37
CLProgramBuilder & add_type(const char *alias, const ref_ptr< Type > &type)
Definition: cl_program_builder.cpp:45
cl::Kernel make_kernel(const char *name)
Definition: cl_program_builder.hpp:67
CLProgramBuilder & set_source(const char *source)
Definition: cl_program_builder.cpp:61
void acquire()
Definition: cl_program_builder.cpp:65
uint values
Definition: tdecoration.hpp:58
void cl_dense_vec_to_coo(const std::size_t n_rows, const T fill_value, const CLDenseVec< T > &in, CLCooVec< T > &out, cl::CommandQueue &queue)
Definition: cl_format_dense_vec.hpp:90
void cl_dense_vec_read(const std::size_t n_rows, T *values, CLDenseVec< T > &storage, cl::CommandQueue &queue, cl_mem_flags staging_flags=CL_MEM_READ_ONLY|CL_MEM_HOST_READ_ONLY|CL_MEM_ALLOC_HOST_PTR, bool blocking=true)
Definition: cl_format_dense_vec.hpp:76
void cl_dense_vec_init(const std::size_t n_rows, const T *values, CLDenseVec< T > &storage)
Definition: cl_format_dense_vec.hpp:63
void cl_dense_vec_fill_value(const std::size_t n_rows, const T value, CLDenseVec< T > &storage)
Definition: cl_format_dense_vec.hpp:56
void cl_dense_vec_resize(const std::size_t n_rows, CLDenseVec< T > &storage)
Definition: cl_format_dense_vec.hpp:46
std::uint32_t uint
Library index and size type.
Definition: config.hpp:56
#define LOG_MSG(status, msg)
Definition: logger.hpp:66
Definition: algorithm.hpp:37
T min(T a, T b)
Definition: op.cpp:152
T max(T a, T b)
Definition: op.cpp:155