-
-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
linalg sum method #3278
linalg sum method #3278
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -37,6 +37,7 @@ | |
#ifdef HAVE_VIENNACL | ||
#include <viennacl/vector.hpp> | ||
#include <viennacl/linalg/inner_prod.hpp> | ||
#include <viennacl/linalg/sum.hpp> | ||
#endif | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why close here the
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agreed! The creation of the class itself should fail if viennacl is not found. |
||
|
||
#ifdef HAVE_CXX11 | ||
|
@@ -60,9 +61,23 @@ T GPUBackend::dot(const GPUVector<T> &a, const GPUVector<T> &b) const | |
#endif | ||
} | ||
|
||
template <typename T> | ||
T GPUBackend::sum(const GPUVector<T> &vec) const | ||
{ | ||
#ifdef HAVE_VIENNACL | ||
return viennacl::linalg::sum(vec.gpuarray->GPUvec()); | ||
#else | ||
SG_SERROR("User did not register GPU backend. \n"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't like it if we would have to put this error message in every implementation. Minor: No space after period. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why do we generate at all you should implement a |
||
return T(0); | ||
#endif | ||
} | ||
|
||
template int32_t GPUBackend::dot<int32_t>(const GPUVector<int32_t> &a, const GPUVector<int32_t> &b) const; | ||
template float32_t GPUBackend::dot<float32_t>(const GPUVector<float32_t> &a, const GPUVector<float32_t> &b) const; | ||
|
||
template int32_t GPUBackend::sum<int32_t>(const GPUVector<int32_t> &vec) const; | ||
template float32_t GPUBackend::sum<float32_t>(const GPUVector<float32_t> &vec) const; | ||
|
||
} | ||
|
||
#endif //HAVE_CXX11 |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -66,6 +66,15 @@ class GPUBackend | |
*/ | ||
template <typename T> | ||
T dot(const GPUVector<T> &a, const GPUVector<T> &b) const; | ||
|
||
/** | ||
* Method that computes the sum of SGVectors using Eigen3 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. not Eigen3. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agreed! |
||
* | ||
* @param a vector whose sum has to be computed | ||
* @return the vector sum \f$\sum_i a_i\f$ | ||
*/ | ||
template <typename T> | ||
T sum(const GPUVector<T> &vec) const; | ||
}; | ||
|
||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -113,13 +113,37 @@ T SGLinalg::dot(BaseVector<T> *a, BaseVector<T> *b) const | |
} | ||
} | ||
|
||
template <class T> | ||
T SGLinalg::sum(BaseVector<T> *vec) const | ||
{ | ||
if (vec->onGPU()) | ||
{ | ||
if (this->hasGPUBackend()) | ||
{ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we dont use {} for single line statements |
||
return m_gpubackend->sum<T>(static_cast<GPUVector<T>&>(*vec)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. don't need to pass |
||
} | ||
else | ||
{ | ||
SG_SERROR("User did not register GPU backend. \n"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why was there an error message in the sum implementation if there is already one here? Also, can we just call some method that throws the error? We dont want to re-write this all the time. |
||
return -1; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. -1 ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
} | ||
} | ||
else | ||
{ | ||
return m_cpubackend->sum<T>(static_cast<CPUVector<T>&>(*vec)); | ||
} | ||
} | ||
|
||
bool SGLinalg::hasGPUBackend() const | ||
{ | ||
return m_gpubackend != nullptr; | ||
} | ||
|
||
template int32_t SGLinalg::dot<int32_t>(BaseVector<int32_t> *a, BaseVector<int32_t> *b) const; | ||
template float32_t SGLinalg::dot<float32_t>(BaseVector<float32_t> *a, BaseVector<float32_t> *b) const; | ||
|
||
template int32_t SGLinalg::sum<int32_t>(BaseVector<int32_t> *vec) const; | ||
template float32_t SGLinalg::sum<float32_t>(BaseVector<float32_t> *vec) const; | ||
} | ||
|
||
#endif //HAVE_CXX11 |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -60,6 +60,19 @@ TEST(SGLinalg, CPUBackend_dot) | |
EXPECT_NEAR(result, 20.0, 1E-15); | ||
} | ||
|
||
TEST(SGLinalg, CPUBackend_sum) | ||
{ | ||
const index_t size=10; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not an optimal unit test. |
||
SGVector<int32_t> a(size); | ||
a.set_const(2); | ||
|
||
CPUVector<int32_t> a_CPU(a); | ||
|
||
auto result = sg_linalg->sum(&a_CPU); | ||
|
||
EXPECT_NEAR(result, 20.0, 1E-15); | ||
} | ||
|
||
#ifdef HAVE_VIENNACL | ||
|
||
TEST(SGLinalg, GPU_Vector_convert) | ||
|
@@ -106,6 +119,23 @@ TEST(SGLinalg, GPUBackend_dot) | |
EXPECT_NEAR(result, 20.0, 1E-15); | ||
} | ||
|
||
TEST(SGLinalg, GPUBackend_sum) | ||
{ | ||
const index_t size=10; | ||
SGVector<int32_t> a(size); | ||
a.set_const(2); | ||
|
||
GPUVector<int32_t> a_GPU(a); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this guy now lives on CPU memory if no GPU is available? |
||
|
||
std::shared_ptr<GPUBackend> ViennaCLBackend; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this needs to be guarded, no? UPDATE: I just saw it is, sorry |
||
ViennaCLBackend = std::shared_ptr<GPUBackend>(new GPUBackend); | ||
|
||
sg_linalg->set_gpu_backend(ViennaCLBackend); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I suggest you keep the GPU backend test in a different file, or at least move registering the backend to a method. To avoid having to register it for every test |
||
auto result = sg_linalg->sum(&a_GPU); | ||
|
||
EXPECT_NEAR(result, 20.0, 1E-15); | ||
} | ||
|
||
#endif //HAVE_VIENNACL | ||
|
||
#endif //HAVE_CXX11 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would remove "with Eigen3" here