Skip to content

Commit bb65d67

Browse files
committed
Fixed some bugs and failed assertions that only appeared in debug mode
1 parent 12c5b39 commit bb65d67

20 files changed

Lines changed: 287 additions & 213 deletions

src/backend/computational_graph/elementwise_mul_node.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ using namespace std;
1515
using namespace graph;
1616

1717
vector<shared_ptr<Tensor>> ElementwiseMulNode::backward(const Tensor& upstreamGrad) {
18+
assert(!upstreamGrad.getRequiresGrad());
1819
return {
1920
make_shared<Tensor>(upstreamGrad * (*parents[1])),
2021
make_shared<Tensor>(upstreamGrad * (*parents[0]))

src/backend/computational_graph/graph_creation.cpp

Lines changed: 57 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,35 +21,35 @@ using namespace std;
2121
shared_ptr<Tensor> graph::mul(const shared_ptr<Tensor> left, const shared_ptr<Tensor> right) {
2222
auto res = make_shared<Tensor>((*left) * (*right));
2323
if(left->getRequiresGrad() || right->getRequiresGrad()){
24-
assert(res->getRequiresGrad());
2524
res->setCgNode(make_shared<graph::ElementwiseMulNode>(left, right));
25+
assert(res->getRequiresGrad());
2626
}
2727
return res;
2828
}
2929

3030
shared_ptr<Tensor> graph::add(const shared_ptr<Tensor> left, const shared_ptr<Tensor> right) {
3131
auto res = make_shared<Tensor>(*left + *right);
3232
if(left->getRequiresGrad() || right->getRequiresGrad()){
33-
assert(res->getRequiresGrad());
3433
res->setCgNode(make_shared<graph::AddNode>(left, right));
34+
assert(res->getRequiresGrad());
3535
}
3636
return res;
3737
}
3838

3939
shared_ptr<Tensor> graph::matmul(const shared_ptr<Tensor> left, const shared_ptr<Tensor> right) {
4040
auto res = make_shared<Tensor>(left->matmul(*right));
4141
if(left->getRequiresGrad() || right->getRequiresGrad()){
42-
assert(res->getRequiresGrad());
4342
res->setCgNode(make_shared<graph::MatMulNode>(left, right));
43+
assert(res->getRequiresGrad());
4444
}
4545
return res;
4646
}
4747

4848
shared_ptr<Tensor> graph::mul(const shared_ptr<Tensor> t, ftype scalar) {
4949
auto res = make_shared<Tensor>((*t) * scalar);
5050
if(t->getRequiresGrad()){
51-
assert(res->getRequiresGrad());
5251
res->setCgNode(std::make_shared<graph::ScalarMulNode>(t, scalar));
52+
assert(res->getRequiresGrad());
5353
}
5454
return res;
5555
}
@@ -61,8 +61,8 @@ shared_ptr<Tensor> graph::mul(ftype scalar, const shared_ptr<Tensor> t) {
6161
shared_ptr<Tensor> graph::add(const shared_ptr<Tensor> t, ftype scalar) {
6262
auto res = make_shared<Tensor>((*t) + scalar);
6363
if(t->getRequiresGrad()){
64-
assert(res->getRequiresGrad());
6564
res->setCgNode(std::make_shared<graph::ScalarAddNode>(t));
65+
assert(res->getRequiresGrad());
6666
}
6767
return res;
6868
}
@@ -74,17 +74,67 @@ shared_ptr<Tensor> graph::add(ftype scalar, const shared_ptr<Tensor> t) {
7474
shared_ptr<Tensor> graph::sub(const shared_ptr<Tensor> t, ftype scalar) {
7575
auto res = make_shared<Tensor>((*t) - scalar);
7676
if(t->getRequiresGrad()){
77-
assert(res->getRequiresGrad());
7877
res->setCgNode(std::make_shared<graph::ScalarAddNode>(t));
78+
assert(res->getRequiresGrad());
7979
}
8080
return res;
8181
}
8282

8383
shared_ptr<Tensor> graph::div(const shared_ptr<Tensor> t, ftype scalar) {
8484
auto res = make_shared<Tensor>((*t) / scalar);
8585
if(t->getRequiresGrad()){
86-
assert(res->getRequiresGrad());
8786
res->setCgNode(std::make_shared<graph::ScalarMulNode>(t, 1 / scalar));
87+
assert(res->getRequiresGrad());
8888
}
8989
return res;
90+
}
91+
92+
/**
93+
* @brief Special linear indexing, see getItem() overloads in tensor.
94+
* Used to keep the computational graph intact.
95+
* E.g. if we have something like
96+
*
97+
* loss = loss + other.get(i), we need to make sure get(i) can map to computational graph.
98+
*/
99+
shared_ptr<Tensor> graph::getAsShared(const shared_ptr<Tensor>& t, tensorSize_t idx) {
100+
ftype val = t->getItem(idx);
101+
return make_shared<Tensor>(std::vector<tensorDim_t>{1}, std::vector<ftype>{val},
102+
t->getDevice(), t->getRequiresGrad());
103+
}
104+
105+
/**
106+
* @brief Special linear indexing, see getItem() overloads in tensor.
107+
* Used to keep the computational graph intact.
108+
* E.g. if we have something like
109+
*
110+
* loss = loss + other.get(i), we need to make sure get(i) can map to computational graph.
111+
*/
112+
std::shared_ptr<Tensor> graph::getAsShared(const Tensor& t, tensorSize_t idx) {
113+
ftype val = t.getItem(idx);
114+
return make_shared<Tensor>(std::vector<tensorDim_t>{1}, std::vector<ftype>{val},
115+
t.getDevice(), t.getRequiresGrad());
116+
}
117+
118+
/**
119+
* @brief Used to keep the computational graph intact.
120+
* E.g. if we have something like
121+
*
122+
* loss = loss + other.get(i), we need to make sure get(i) can map to computational graph.
123+
*/
124+
shared_ptr<Tensor> graph::getAsShared(const shared_ptr<Tensor>& t, vector<tensorDim_t>&& idx) {
125+
ftype val = t->getItem(std::move(idx));
126+
return make_shared<Tensor>(std::vector<tensorDim_t>{1}, std::vector<ftype>{val},
127+
t->getDevice(), t->getRequiresGrad());
128+
}
129+
130+
/**
131+
* @brief Used to keep the computational graph intact.
132+
* E.g. if we have something like
133+
*
134+
* loss = loss + other.get(i), we need to make sure get(i) can map to computational graph.
135+
*/
136+
std::shared_ptr<Tensor> graph::getAsShared(const Tensor& t, std::vector<tensorDim_t>&& idx) {
137+
ftype val = t.getItem(std::move(idx));
138+
return make_shared<Tensor>(std::vector<tensorDim_t>{1}, std::vector<ftype>{val},
139+
t.getDevice(), t.getRequiresGrad());
90140
}

src/backend/computational_graph/graph_creation.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,12 @@ namespace graph {
2929
std::shared_ptr<Tensor> add(ftype scalar, const std::shared_ptr<Tensor> left);
3030

3131
std::shared_ptr<Tensor> sub(const std::shared_ptr<Tensor> left, ftype scalar);
32-
std::shared_ptr<Tensor> div(const std::shared_ptr<Tensor> left, ftype scalar);
32+
std::shared_ptr<Tensor> div(const std::shared_ptr<Tensor> left, ftype scalar);
33+
34+
std::shared_ptr<Tensor> getAsShared(const std::shared_ptr<Tensor>& t, tensorSize_t idx);
35+
std::shared_ptr<Tensor> getAsShared(const Tensor& t, tensorSize_t idx);
36+
37+
std::shared_ptr<Tensor> getAsShared(const std::shared_ptr<Tensor>& t, std::vector<tensorDim_t>&& idx);
38+
std::shared_ptr<Tensor> getAsShared(const Tensor& t, std::vector<tensorDim_t>&& idx);
3339
}
3440

src/backend/computational_graph/matmul_node.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ using namespace std;
1515
using namespace graph;
1616

1717
vector<shared_ptr<Tensor>> MatMulNode::backward(const Tensor& upstreamGrad) {
18+
assert(!upstreamGrad.getRequiresGrad());
1819
return {
1920
make_shared<Tensor>(upstreamGrad.matmul(parents[1]->transpose(-2, -1))),
2021
make_shared<Tensor>(parents[0]->transpose(-2, -1).matmul(upstreamGrad))

src/backend/computational_graph/relu_node.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,14 @@ using namespace std;
1717
using namespace graph;
1818

1919
vector<shared_ptr<Tensor>> ReLuNode::backward(const Tensor& upstreamGrad) {
20+
assert(!upstreamGrad.getRequiresGrad());
21+
2022
constexpr ftype zero = 0.0;
2123

2224
auto res = make_shared<Tensor>(upstreamGrad.getDims().toVector(), upstreamGrad.getDevice(), false);
2325
for(tensorSize_t i=0; i<upstreamGrad.getSize(); i++){
24-
auto v = upstreamGrad.get(i);
25-
res->set(v > zero ? v : zero, i);
26+
auto v = upstreamGrad.getItem(i);
27+
res->setItem(v > zero ? v : zero, i);
2628
}
2729
return {std::move(res)};
2830
}

src/backend/computational_graph/scalar_op_nodes.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,16 @@ using namespace std;
1717
using namespace graph;
1818

1919
vector<shared_ptr<Tensor>> graph::ScalarAddNode::backward(const Tensor& upstreamGrad) {
20+
assert(!upstreamGrad.getRequiresGrad());
2021
return {make_shared<Tensor>(upstreamGrad.createDeepCopy())};
2122
}
2223

2324
vector<shared_ptr<Tensor>> graph::ScalarMulNode::backward(const Tensor& upstreamGrad) {
25+
assert(!upstreamGrad.getRequiresGrad());
26+
2427
auto res = make_shared<Tensor>(upstreamGrad.createDeepCopy());
2528
for(tensorSize_t i=0; i<res->getSize(); i++){
26-
res->set(res->get(i) * factor, i);
29+
res->setItem(res->getItem(i) * factor, i);
2730
}
2831
return {std::move(res)};
2932
}

src/backend/data_modeling/dim_type.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ tensorDim_t Dimension::multVector(const std::vector<tensorDim_t>& dims) const no
2222
#ifndef NDEBUG
2323
utility::SafeArithmetics_t<tensorSize_t> mult(1);
2424
for(auto dim: dims){
25-
mult * dim;
25+
mult = mult * dim;
2626
}
2727

2828
res = mult.value;
@@ -85,7 +85,7 @@ Dimension& Dimension::operator=(Dimension&& other) noexcept {
8585
ostream& operator<<(ostream& os, const Dimension& d) noexcept {
8686
os << "(";
8787
for(int i=0; i<d.nDims(); i++){
88-
os << d.get(i);
88+
os << d.getItem(i);
8989

9090
if(i+1<d.nDims()){
9191
os << ",";

src/backend/data_modeling/dim_type.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ class Dimension final {
5454
return size;
5555
}
5656

57-
tensorDim_t get(int idx) const {
57+
tensorDim_t getItem(int idx) const {
5858
assert(size!=0);
5959
if(idx<0){
6060
idx = dims.size() + idx; // -1 is last idx, -2 second last and so forth

0 commit comments

Comments
 (0)