Skip to content

Commit c1c49e9

Browse files
committed
[Code] Add vector eWiseAdd op && support setElement (in sq backend)
1 parent f37ee08 commit c1c49e9

File tree

16 files changed

+569
-6
lines changed

16 files changed

+569
-6
lines changed

cubool/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,9 @@ set(CUBOOL_C_API_SOURCES
8585
sources/cuBool_Vector_Duplicate.cpp
8686
sources/cuBool_Vector_Nvals.cpp
8787
sources/cuBool_Vector_Nrows.cpp
88-
sources/cuBool_Vector_Reduce.cpp
8988
sources/cuBool_Vector_Free.cpp
89+
sources/cuBool_Vector_Reduce.cpp
90+
sources/cuBool_Vector_EWiseAdd.cpp
9091
sources/cuBool_MxM.cpp
9192
sources/cuBool_Kronecker.cpp)
9293

cubool/include/cubool/cubool.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -555,6 +555,13 @@ CUBOOL_EXPORT CUBOOL_API cuBool_Status cuBool_Vector_Reduce(
555555
cuBool_Hints hints
556556
);
557557

558+
CUBOOL_EXPORT CUBOOL_API cuBool_Status cuBool_Vector_EWiseAdd(
559+
cuBool_Vector result,
560+
cuBool_Vector left,
561+
cuBool_Vector right,
562+
cuBool_Hints hints
563+
);
564+
558565
/**
559566
* Performs result (accum)= left x right evaluation, where source '+' and 'x' are boolean semiring operations.
560567
* If accum hint passed, the the result of the multiplication is added to the result matrix.

cubool/sources/backend/vector_base.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ namespace cubool {
4545
virtual void reduce(index &result, bool checkTime) = 0;
4646
virtual void reduceMatrix(const class MatrixBase& matrix, bool transpose, bool checkTime) = 0;
4747

48+
virtual void eWiseAdd(const VectorBase &aBase, const VectorBase &bBase, bool checkTime) = 0;
49+
4850
virtual index getNrows() const = 0;
4951
virtual index getNvals() const = 0;
5052

cubool/sources/core/vector.cpp

Lines changed: 69 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,15 @@
2525
#include <core/vector.hpp>
2626
#include <core/error.hpp>
2727
#include <core/library.hpp>
28+
#include <utils/timer.hpp>
2829
#include <io/logger.hpp>
2930

31+
#define TIMER_ACTION(timer, action) \
32+
Timer timer; \
33+
timer.start(); \
34+
action; \
35+
timer.end()
36+
3037
namespace cubool {
3138

3239
Vector::Vector(size_t nrows, BackendBase &backend) {
@@ -48,7 +55,10 @@ namespace cubool {
4855
}
4956

5057
void Vector::setElement(index i) {
51-
RAISE_ERROR(NotImplemented, "This function is not implemented");
58+
CHECK_RAISE_ERROR(i < getNrows(), InvalidArgument, "Value out of vector bounds");
59+
60+
// This values will be committed later
61+
mCachedI.push_back(i);
5262
}
5363

5464
void Vector::build(const index *rows, size_t nvals, bool isSorted, bool noDuplicates) {
@@ -103,6 +113,39 @@ namespace cubool {
103113
RAISE_ERROR(NotImplemented, "This function is not implemented");
104114
}
105115

116+
void Vector::eWiseAdd(const VectorBase &aBase, const VectorBase &bBase, bool checkTime) {
117+
const auto* a = dynamic_cast<const Vector*>(&aBase);
118+
const auto* b = dynamic_cast<const Vector*>(&bBase);
119+
120+
CHECK_RAISE_ERROR(a != nullptr, InvalidArgument, "Passed vector does not belong to core vector class");
121+
CHECK_RAISE_ERROR(b != nullptr, InvalidArgument, "Passed vector does not belong to core vector class");
122+
123+
index M = a->getNrows();
124+
125+
CHECK_RAISE_ERROR(M == b->getNrows(), InvalidArgument, "Passed vectors have incompatible size");
126+
CHECK_RAISE_ERROR(M == this->getNrows(), InvalidArgument, "Vector has incompatible size for operation result");
127+
128+
a->commitCache();
129+
b->commitCache();
130+
this->releaseCache();
131+
132+
if (checkTime) {
133+
TIMER_ACTION(timer, mHnd->eWiseAdd(*a->mHnd, *b->mHnd, false));
134+
135+
LogStream stream(*Library::getLogger());
136+
stream << Logger::Level::Info
137+
<< "Time: " << timer.getElapsedTimeMs() << " ms "
138+
<< "Vector::eWiseAdd: "
139+
<< this->getDebugMarker() << " = "
140+
<< a->getDebugMarker() << " + "
141+
<< b->getDebugMarker() << LogStream::cmt;
142+
143+
return;
144+
}
145+
146+
mHnd->eWiseAdd(*a->mHnd, *b->mHnd, false);
147+
}
148+
106149
index Vector::getNrows() const {
107150
return mHnd->getNrows();
108151
}
@@ -117,7 +160,31 @@ namespace cubool {
117160
}
118161

119162
void Vector::commitCache() const {
120-
// todo
163+
size_t cachedNvals = mCachedI.size();
164+
165+
// Nothing to do if no value was cached on CPU side
166+
if (cachedNvals == 0)
167+
return;
168+
169+
bool isSorted = false;
170+
bool noDuplicates = false;
171+
172+
if (mHnd->getNvals() > 0) {
173+
// We will have to join old and new values
174+
// Create tmp vector and merge values
175+
176+
VectorBase* tmp = mProvider->createVector(getNrows());
177+
tmp->build(mCachedI.data(), cachedNvals, isSorted, noDuplicates);
178+
mHnd->eWiseAdd(*mHnd, *tmp, false);
179+
mProvider->releaseVector(tmp);
180+
}
181+
else {
182+
// Otherwise, new values are used to build vector content
183+
mHnd->build(mCachedI.data(), cachedNvals, isSorted, noDuplicates);
184+
}
185+
186+
// Clear arrays
187+
releaseCache();
121188
}
122189

123190
}

cubool/sources/core/vector.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ namespace cubool {
4848
void reduce(index &result, bool checkTime) override;
4949
void reduceMatrix(const MatrixBase &matrix, bool transpose, bool checkTime) override;
5050

51+
void eWiseAdd(const VectorBase &aBase, const VectorBase &bBase, bool checkTime) override;
52+
5153
index getNrows() const override;
5254
index getNvals() const override;
5355

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
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 <cuBool_Common.hpp>
26+
27+
cuBool_Status cuBool_Vector_EWiseAdd(
28+
cuBool_Vector result,
29+
cuBool_Vector left,
30+
cuBool_Vector right,
31+
cuBool_Hints hints
32+
) {
33+
CUBOOL_BEGIN_BODY
34+
CUBOOL_VALIDATE_LIBRARY
35+
CUBOOL_ARG_NOT_NULL(result)
36+
CUBOOL_ARG_NOT_NULL(left)
37+
CUBOOL_ARG_NOT_NULL(right)
38+
auto resultM = (cubool::Vector *) result;
39+
auto leftM = (cubool::Vector *) left;
40+
auto rightM = (cubool::Vector *) right;
41+
resultM->eWiseAdd(*leftM, *rightM, hints & CUBOOL_HINT_TIME_CHECK);
42+
CUBOOL_END_BODY
43+
}

cubool/sources/sequential/sq_ewiseadd.cpp

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,4 +117,75 @@ namespace cubool {
117117
}
118118
}
119119

120+
void sq_ewiseadd(const VecData& a, const VecData& b, VecData& out) {
121+
size_t nnz = 0;
122+
123+
const index* ar = a.indices.data();
124+
const index* br = b.indices.data();
125+
126+
const index* arend = a.indices.data() + a.nvals;
127+
const index* brend = b.indices.data() + b.nvals;
128+
129+
// Count nnz
130+
while (ar != arend && br != brend) {
131+
if (*ar == *br) {
132+
ar++;
133+
br++;
134+
}
135+
else if (*ar < *br) {
136+
ar++;
137+
}
138+
else {
139+
br++;
140+
}
141+
142+
nnz++;
143+
}
144+
145+
while (ar != arend) {
146+
nnz++;
147+
ar++;
148+
}
149+
150+
while (br != brend) {
151+
nnz++;
152+
br++;
153+
}
154+
155+
// Allocate data
156+
out.indices.clear();
157+
out.indices.reserve(nnz);
158+
out.nvals = nnz;
159+
160+
// Fill data
161+
ar = a.indices.data();
162+
br = b.indices.data();
163+
164+
while (ar != arend && br != brend) {
165+
if (*ar == *br) {
166+
out.indices.push_back(*ar);
167+
ar++;
168+
br++;
169+
}
170+
else if (*ar < *br) {
171+
out.indices.push_back(*ar);
172+
ar++;
173+
}
174+
else {
175+
out.indices.push_back(*br);
176+
br++;
177+
}
178+
}
179+
180+
while (ar != arend) {
181+
out.indices.push_back(*ar);
182+
ar++;
183+
}
184+
185+
while (br != brend) {
186+
out.indices.push_back(*br);
187+
br++;
188+
}
189+
}
190+
120191
}

cubool/sources/sequential/sq_ewiseadd.hpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,15 @@ namespace cubool {
3838
*/
3939
void sq_ewiseadd(const CsrData& a, const CsrData& b, CsrData& out);
4040

41+
/**
42+
* Element-wise addition of the vectors `a` and `b`.
43+
*
44+
* @param a Input vector
45+
* @param b Input vector
46+
* @param[out] out Where to store the result
47+
*/
48+
void sq_ewiseadd(const VecData& a, const VecData& b, VecData& out);
49+
4150
}
4251

4352
#endif //CUBOOL_SQ_EWISEADD_HPP

cubool/sources/sequential/sq_vector.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include <sequential/sq_vector.hpp>
2626
#include <sequential/sq_matrix.hpp>
2727
#include <sequential/sq_reduce.hpp>
28+
#include <sequential/sq_ewiseadd.hpp>
2829
#include <sequential/sq_subvector.hpp>
2930
#include <utils/data_utils.hpp>
3031
#include <core/error.hpp>
@@ -106,6 +107,24 @@ namespace cubool {
106107
this->mData = std::move(out);
107108
}
108109

110+
void SqVector::eWiseAdd(const VectorBase &aBase, const VectorBase &bBase, bool checkTime) {
111+
auto a = dynamic_cast<const SqVector*>(&aBase);
112+
auto b = dynamic_cast<const SqVector*>(&bBase);
113+
114+
CHECK_RAISE_ERROR(a != nullptr, InvalidArgument, "Provided vector does not belongs to sequential vector class");
115+
CHECK_RAISE_ERROR(b != nullptr, InvalidArgument, "Provided vector does not belongs to sequential vector class");
116+
117+
assert(a->getNrows() == this->getNrows());
118+
assert(a->getNrows() == b->getNrows());
119+
120+
VecData out;
121+
out.nrows = this->getNrows();
122+
123+
sq_ewiseadd(a->mData, b->mData, out);
124+
125+
this->mData = std::move(out);
126+
}
127+
109128
index SqVector::getNrows() const {
110129
return mData.nrows;
111130
}

cubool/sources/sequential/sq_vector.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ namespace cubool {
3232

3333
class SqVector final: public VectorBase {
3434
public:
35-
SqVector(size_t nrows);
35+
explicit SqVector(size_t nrows);
3636
~SqVector() override = default;
3737

3838
void setElement(index i) override;
@@ -44,6 +44,8 @@ namespace cubool {
4444
void reduce(index &result, bool checkTime) override;
4545
void reduceMatrix(const class MatrixBase &matrix, bool transpose, bool checkTime) override;
4646

47+
void eWiseAdd(const VectorBase &aBase, const VectorBase &bBase, bool checkTime) override;
48+
4749
index getNrows() const override;
4850
index getNvals() const override;
4951

0 commit comments

Comments
 (0)