Skip to content

Commit 12bd69a

Browse files
committed
[Code] Add SpGEMV first impl for cuda backend
1 parent 7458787 commit 12bd69a

File tree

9 files changed

+353
-52
lines changed

9 files changed

+353
-52
lines changed

cubool/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ if (CUBOOL_WITH_CUDA)
128128
sources/cuda/cuda_matrix_extract_sub_matrix.cu
129129
sources/cuda/cuda_vector.hpp
130130
sources/cuda/cuda_vector.cu
131+
sources/cuda/cuda_vector_mxv.cu
131132
sources/cuda/cuda_vector_ewiseadd.cu
132133
sources/cuda/cuda_vector_reduce.cu
133134
sources/cuda/details/meta.hpp
@@ -136,6 +137,7 @@ if (CUBOOL_WITH_CUDA)
136137
sources/cuda/details/device_allocator.cuh
137138
sources/cuda/kernels/slow_sort.cuh
138139
sources/cuda/kernels/bin_search.cuh
140+
sources/cuda/kernels/spgemv.cuh
139141
sources/cuda/kernels/spewiseadd.cuh
140142
sources/cuda/kernels/sptranspose.cuh
141143
sources/cuda/kernels/sptranspose2.cuh

cubool/sources/core/library.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,10 @@ namespace cubool {
240240

241241
void Library::handleError(const std::exception& error) {
242242
mLogger->log(Logger::Level::Error, error.what());
243+
244+
#ifdef CUBOOL_DEBUG
245+
std::cerr << error.what() << std::endl;
246+
#endif
243247
}
244248

245249
void Library::queryCapabilities(cuBool_DeviceCaps &caps) {

cubool/sources/cuda/cuda_vector.cu

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -93,11 +93,6 @@ namespace cubool {
9393

9494
}
9595

96-
void CudaVector::multiplyMxV(const struct MatrixBase &mBase, const VectorBase &vBase, bool checkTime) {
97-
RAISE_ERROR(NotImplemented, "This function is not implemented");
98-
99-
}
100-
10196
index CudaVector::getNrows() const {
10297
return mVectorImpl.m_rows;
10398
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/**********************************************************************************/
2+
/* MIT License */
3+
/* */
4+
/* Copyright (c) 2020, 2021 JetBrains-Research */
5+
/* */
6+
/* Permission is hereby granted, free of charge, to any person obtaining a copy */
7+
/* of this software and associated documentation files (the "Software"), to deal */
8+
/* in the Software without restriction, including without limitation the rights */
9+
/* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell */
10+
/* copies of the Software, and to permit persons to whom the Software is */
11+
/* furnished to do so, subject to the following conditions: */
12+
/* */
13+
/* The above copyright notice and this permission notice shall be included in all */
14+
/* copies or substantial portions of the Software. */
15+
/* */
16+
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR */
17+
/* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, */
18+
/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE */
19+
/* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER */
20+
/* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, */
21+
/* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE */
22+
/* SOFTWARE. */
23+
/**********************************************************************************/
24+
25+
#include <cuda/cuda_vector.hpp>
26+
#include <cuda/cuda_matrix.hpp>
27+
#include <cuda/kernels/spgemv.cuh>
28+
#include <core/error.hpp>
29+
#include <cassert>
30+
31+
namespace cubool {
32+
33+
void CudaVector::multiplyMxV(const struct MatrixBase &mBase, const VectorBase &vBase, bool checkTime) {
34+
const auto* m = dynamic_cast<const CudaMatrix*>(&mBase);
35+
const auto* v = dynamic_cast<const CudaVector*>(&vBase);
36+
37+
CHECK_RAISE_ERROR(m != nullptr, InvalidArgument, "Provided matrix does not belong to cuda matrix class");
38+
CHECK_RAISE_ERROR(v != nullptr, InvalidArgument, "Provided vector does not belong to cuda vector class");
39+
40+
assert(m->getNcols() == v->getNrows());
41+
assert(m->getNrows() == this->getNrows());
42+
43+
m->resizeStorageToDim();
44+
45+
kernels::SpGEMV<index, DeviceAlloc<index>> functor;
46+
auto result = functor(m->mMatrixImpl, v->mVectorImpl);
47+
48+
mVectorImpl = std::move(result);
49+
}
50+
51+
}

cubool/sources/cuda/details/meta.hpp

Lines changed: 43 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -25,59 +25,64 @@
2525
#ifndef CUBOOL_META_HPP
2626
#define CUBOOL_META_HPP
2727

28+
#include <thrust/device_vector.h>
29+
#include <thrust/host_vector.h>
2830
#include <cstddef>
2931

3032
namespace cubool {
3133

32-
template <size_t workersCount, size_t blockSize>
33-
struct BinConfig {
34-
static const size_t mWorkersCount = workersCount;
35-
static const size_t mBlockSize = blockSize;
36-
};
34+
template <typename Config>
35+
struct StreamsWrapper {
36+
StreamsWrapper() {
37+
for (auto& s: streams)
38+
cudaStreamCreate(&s);
39+
}
3740

38-
template <size_t minBorder, size_t maxBorder>
39-
struct BorderConfig {
40-
static const size_t mMinBorder = minBorder;
41-
static const size_t mMaxBorder = maxBorder;
42-
};
41+
~StreamsWrapper() {
42+
for (auto& s: streams)
43+
cudaStreamDestroy(s);
44+
}
4345

44-
template <typename ... BinsConfig>
45-
class ComputeConfig {
46-
public:
46+
cudaStream_t streams[Config::binsCount()] = {};
47+
};
4748

48-
template<typename T, typename C>
49-
void exec(C& context) {
50-
ExecImpl<void, T, BinsConfig...>::exec(0, context);
51-
}
49+
template<size_t BlocksSize, size_t Max, size_t Min, size_t Id>
50+
struct Bin {
51+
static constexpr size_t blockSize = BlocksSize;
52+
static constexpr size_t min = Max;
53+
static constexpr size_t max = Min;
54+
static constexpr size_t id = Id;
55+
};
5256

53-
private:
5457

55-
template<typename D, typename T, typename C, typename ... Bins>
56-
struct ExecImpl {
57-
static void exec(size_t index, C& context) { }
58-
};
58+
template <typename ... Bins>
59+
struct Config {
60+
public:
5961

60-
template<typename D, typename T, typename C, typename Bin>
61-
struct ExecImpl<D, T, C, Bin> {
62-
static void exec(size_t index, C& context) {
63-
using Timpl = typename T::template function<Bin>;
62+
static __host__ __device__ size_t selectBin(size_t rowSize) {
63+
static constexpr size_t mins[] = { Bins::min... };
64+
static constexpr size_t maxs[] = { Bins::max... };
6465

65-
Timpl timpl;
66-
timpl(index, context);
66+
for (size_t i = 0; i < binsCount(); i++) {
67+
if (mins[i] <= rowSize && rowSize <= maxs[i])
68+
return i;
6769
}
68-
};
6970

70-
template<typename D, typename T, typename C, typename Bin, typename ... Bins>
71-
struct ExecImpl<D, T, C, Bin, Bins...> {
72-
static void exec(size_t index, C& context) {
73-
using Timpl = typename T::template function<Bin>;
71+
return unusedBinId();
72+
}
7473

75-
Timpl timpl;
76-
timpl(index, context);
74+
static __host__ __device__ constexpr size_t binBlockSize(size_t id) {
75+
constexpr size_t blockSizes[] = { Bins::blockSize... };
76+
return blockSizes[id];
77+
}
7778

78-
ExecImpl<D, T, Bins...>::exec(index + 1, context);
79-
}
80-
};
79+
static __host__ __device__ constexpr size_t binsCount() {
80+
return sizeof...(Bins);
81+
}
82+
83+
static __host__ __device__ constexpr size_t unusedBinId() {
84+
return binsCount() + 1;
85+
}
8186

8287
};
8388

0 commit comments

Comments
 (0)