🌐 AI搜索 & 代理 主页
Skip to content

Commit 536c711

Browse files
committed
First commit.
1 parent d290d69 commit 536c711

File tree

4 files changed

+173
-0
lines changed

4 files changed

+173
-0
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,6 @@
3030
*.exe
3131
*.out
3232
*.app
33+
34+
# CMake
35+
build/

CMakeLists.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
cmake_minimum_required(VERSION 3.10)
2+
3+
# Set the project name
4+
project(Micrograd)
5+
6+
# Specify the C++ standard
7+
set(CMAKE_CXX_STANDARD 23)
8+
set(CMAKE_CXX_STANDARD_REQUIRED True)
9+
10+
# Add the executable
11+
add_executable(Micrograd engine.cpp)

build.sh

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#!/bin/bash
2+
3+
# Create build directory if it doesn't exist
4+
[ ! -d "build" ] && mkdir build
5+
6+
# Navigate to the build directory
7+
cd build
8+
9+
# Run CMake and build
10+
cmake .. && cmake --build .

engine.cpp

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
#include <iostream>
2+
#include <memory>
3+
#include <set>
4+
#include <functional>
5+
#include <cassert>
6+
#include <cmath>
7+
8+
class Value : public std::enable_shared_from_this<Value> {
9+
public:
10+
double data;
11+
double grad;
12+
std::function<void()> _backward;
13+
std::set<std::shared_ptr<Value>> _prev;
14+
std::string _op;
15+
16+
Value(double data, std::set<std::shared_ptr<Value>> _children = {}, std::string _op = "")
17+
: data(data), grad(0), _backward([]{}), _prev(_children), _op(_op) {}
18+
19+
std::shared_ptr<Value> operator+(const std::shared_ptr<Value>& other) {
20+
auto out = std::make_shared<Value>(data + other->data, std::set<std::shared_ptr<Value>>{shared_from_this(), other}, "+");
21+
out->_backward = [this, other, out] {
22+
this->grad += out->grad;
23+
other->grad += out->grad;
24+
};
25+
return out;
26+
}
27+
28+
std::shared_ptr<Value> operator*(const std::shared_ptr<Value>& other) {
29+
auto out = std::make_shared<Value>(data * other->data, std::set<std::shared_ptr<Value>>{shared_from_this(), other}, "*");
30+
out->_backward = [this, other, out] {
31+
this->grad += other->data * out->grad;
32+
other->grad += this->data * out->grad;
33+
};
34+
return out;
35+
}
36+
37+
std::shared_ptr<Value> operator^(double other) {
38+
assert(other == static_cast<int>(other) || other == static_cast<float>(other) || other == static_cast<double>(other));
39+
auto out = std::make_shared<Value>(std::pow(data, other), std::set<std::shared_ptr<Value>>{shared_from_this()}, "**" + std::to_string(other));
40+
out->_backward = [this, other, out] {
41+
this->grad += (other * std::pow(data, other - 1)) * out->grad;
42+
};
43+
return out;
44+
}
45+
46+
std::shared_ptr<Value> relu() {
47+
auto out = std::make_shared<Value>(data < 0 ? 0 : data, std::set<std::shared_ptr<Value>>{shared_from_this()}, "ReLU");
48+
out->_backward = [this, out] {
49+
this->grad += (out->data > 0) * out->grad;
50+
};
51+
return out;
52+
}
53+
54+
void backward() {
55+
std::vector<std::shared_ptr<Value>> topo;
56+
std::set<std::shared_ptr<Value>> visited;
57+
auto build_topo = [&](auto&& self, const std::shared_ptr<Value>& v) -> void {
58+
if (visited.find(v) == visited.end()) {
59+
visited.insert(v);
60+
for (const auto& child : v->_prev) {
61+
self(self, child);
62+
}
63+
topo.push_back(v);
64+
}
65+
};
66+
build_topo(build_topo, shared_from_this());
67+
grad = 1;
68+
for (auto it = topo.rbegin(); it != topo.rend(); ++it) {
69+
(*it)->_backward();
70+
}
71+
}
72+
73+
std::shared_ptr<Value> operator-() {
74+
return (*this) * std::make_shared<Value>(-1);
75+
}
76+
77+
std::shared_ptr<Value> operator+(double other) {
78+
return (*this) + std::make_shared<Value>(other);
79+
}
80+
81+
std::shared_ptr<Value> operator-(const std::shared_ptr<Value>& other) {
82+
return (*this) + (-*other);
83+
}
84+
85+
std::shared_ptr<Value> operator-(double other) {
86+
return (*this) + std::make_shared<Value>(-other);
87+
}
88+
89+
std::shared_ptr<Value> operator*(double other) {
90+
return (*this) * std::make_shared<Value>(other);
91+
}
92+
93+
std::shared_ptr<Value> operator/(const std::shared_ptr<Value>& other) {
94+
return (*this) * ((*other) ^ -1);
95+
}
96+
97+
std::shared_ptr<Value> operator/(double other) {
98+
return (*this) * std::make_shared<Value>(1.0 / other);
99+
}
100+
101+
// Overload the operators for shared_ptr<Value>
102+
friend std::shared_ptr<Value> operator+(const std::shared_ptr<Value>& lhs, const std::shared_ptr<Value>& rhs) {
103+
return lhs->operator+(rhs);
104+
}
105+
106+
friend std::shared_ptr<Value> operator-(const std::shared_ptr<Value>& lhs, const std::shared_ptr<Value>& rhs) {
107+
return lhs->operator-(rhs);
108+
}
109+
110+
friend std::shared_ptr<Value> operator*(const std::shared_ptr<Value>& lhs, const std::shared_ptr<Value>& rhs) {
111+
return lhs->operator*(rhs);
112+
}
113+
114+
friend std::shared_ptr<Value> operator/(const std::shared_ptr<Value>& lhs, const std::shared_ptr<Value>& rhs) {
115+
return lhs->operator/(rhs);
116+
}
117+
118+
friend std::shared_ptr<Value> operator+(double lhs, const std::shared_ptr<Value>& rhs) {
119+
return std::make_shared<Value>(lhs) + rhs;
120+
}
121+
122+
friend std::shared_ptr<Value> operator-(double lhs, const std::shared_ptr<Value>& rhs) {
123+
return std::make_shared<Value>(lhs) - rhs;
124+
}
125+
126+
friend std::shared_ptr<Value> operator*(double lhs, const std::shared_ptr<Value>& rhs) {
127+
return std::make_shared<Value>(lhs) * rhs;
128+
}
129+
130+
friend std::shared_ptr<Value> operator/(double lhs, const std::shared_ptr<Value>& rhs) {
131+
return std::make_shared<Value>(lhs) / rhs;
132+
}
133+
134+
friend std::ostream& operator<<(std::ostream& os, const Value& v) {
135+
os << "Value(data=" << v.data << ", grad=" << v.grad << ")";
136+
return os;
137+
}
138+
};
139+
140+
141+
142+
int main() {
143+
auto a = std::make_shared<Value>(2.0);
144+
auto b = std::make_shared<Value>(3.0);
145+
auto c = a + b; // Now this works
146+
std::cout << *c << std::endl;
147+
c->backward();
148+
std::cout << *a << " " << *b << std::endl;
149+
}

0 commit comments

Comments
 (0)