Skip to content

Commit d30d95f

Browse files
committed
autograd engine working
1 parent a071e38 commit d30d95f

9 files changed

Lines changed: 493 additions & 78 deletions

File tree

CMakeLists.txt

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
cmake_minimum_required(VERSION 3.14)
1+
cmake_minimum_required(VERSION 3.17)
22

33
# Project declaration
44
project(TorchScratch
@@ -29,7 +29,19 @@ include_directories(
2929
)
3030

3131
# Create library target
32-
add_library(torchscratch src/core/tensor/tensor.cpp src/core/tensor/ops.cpp)
32+
add_library(torchscratch
33+
src/core/tensor/tensor.cpp
34+
src/core/tensor/ops.cpp
35+
src/core/tensor/tensor_impl.cpp
36+
src/core/autograd/engine.cpp
37+
)
38+
39+
set(HEADER
40+
include/core/tensor/tensor.h
41+
include/core/tensor/ops.h
42+
include/core/tensor/tensor_impl.h
43+
include/core/autograd/function.h
44+
include/core/autograd/variable.h)
3345

3446
# Set include directories for the target
3547
target_include_directories(torchscratch PUBLIC

include/core/autograd/function.h

Lines changed: 51 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,58 +11,101 @@
1111
namespace torchscratch {
1212
namespace core {
1313
namespace autograd {
14+
15+
// Forward declaration
1416
class Variable;
1517

18+
/**
19+
* Base class for all autograd functions.
20+
* Each subclass implements a particular operation (like Add, MatMul, etc.)
21+
* with its forward and backward pass logic.
22+
*/
1623
class Function {
1724
public:
1825
virtual ~Function() = default;
26+
27+
// Rule of 5: Allow proper inheritance
1928
Function() = default;
2029
Function(const Function&) = default;
2130
Function& operator=(const Function&) = default;
2231
Function(Function&&) noexcept = default;
2332
Function& operator=(Function&&) noexcept = default;
2433

34+
/**
35+
* Apply the forward pass of this function to the inputs.
36+
* @param inputs Vector of input tensors
37+
* @return Vector of output tensors
38+
*/
2539
virtual std::vector<tensor::Tensor> forward(const std::vector<tensor::Tensor>& inputs) = 0;
2640

27-
virtual std::vector<tensor::Tensor> backward(const std::vector<tensor::Tensor>& grad_outputs) = 0;
41+
/**
42+
* Apply the backward pass of this function.
43+
* @param grad_output Gradient of the loss with respect to the output
44+
* @return Vector of gradients with respect to the inputs
45+
*/
46+
virtual std::vector<tensor::Tensor> backward(const std::vector<tensor::Tensor>& grad_output) = 0;
2847

48+
/**
49+
* Get a string representation of this function for debugging.
50+
*/
2951
virtual std::string name() const = 0;
3052

31-
void save_for_backward(const std::vector<tensor::Tensor>& inputs);
53+
/**
54+
* Save pointers to the input variables for backward pass.
55+
* @param inputs Vector of input variables
56+
*/
57+
void save_for_backward(const std::vector<Variable*>& inputs);
3258

59+
/**
60+
* Get the saved input variables.
61+
* @return Vector of saved input variables
62+
*/
3363
const std::vector<Variable*>& get_saved_variables() const;
3464

3565
private:
3666
std::vector<Variable*> saved_variables_;
3767
};
68+
69+
/**
70+
* AddFunction implements element-wise addition with broadcasting.
71+
*/
3872
class AddFunction : public Function {
3973
public:
4074
std::vector<tensor::Tensor> forward(const std::vector<tensor::Tensor>& inputs) override;
41-
std::vector<tensor::Tensor> backward(const std::vector<tensor::Tensor>& grad_outputs) override;
75+
std::vector<tensor::Tensor> backward(const std::vector<tensor::Tensor>& grad_output) override;
4276
std::string name() const override { return "AddFunction"; }
4377
};
78+
79+
/**
80+
* MulFunction implements element-wise multiplication.
81+
*/
4482
class MulFunction : public Function {
4583
public:
4684
std::vector<tensor::Tensor> forward(const std::vector<tensor::Tensor>& inputs) override;
47-
std::vector<tensor::Tensor> backward(const std::vector<tensor::Tensor>& grad_outputs) override;
85+
std::vector<tensor::Tensor> backward(const std::vector<tensor::Tensor>& grad_output) override;
4886
std::string name() const override { return "MulFunction"; }
4987

5088
private:
51-
tensor::Tensor input1_;
89+
tensor::Tensor input1_; // Save inputs for backward pass
5290
tensor::Tensor input2_;
5391
};
92+
93+
/**
94+
* MatMulFunction implements matrix multiplication.
95+
*/
5496
class MatMulFunction : public Function {
5597
public:
5698
std::vector<tensor::Tensor> forward(const std::vector<tensor::Tensor>& inputs) override;
57-
std::vector<tensor::Tensor> backward(const std::vector<tensor::Tensor>& grad_outputs) override;
99+
std::vector<tensor::Tensor> backward(const std::vector<tensor::Tensor>& grad_output) override;
58100
std::string name() const override { return "MatMulFunction"; }
59101

60102
private:
61-
tensor::Tensor input1_;
103+
tensor::Tensor input1_; // Save inputs for backward pass
62104
tensor::Tensor input2_;
63105
};
64106

65107
} // namespace autograd
66108
} // namespace core
67109
} // namespace torchscratch
68-
#endif
110+
111+
#endif // AUTOGRAD_FUNCTION_H

include/core/tensor/tensor.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
#include <stdexcept>
88
#include <vector>
99

10+
#include "core/tensor/tensor_impl.h"
11+
1012
namespace torchscratch {
1113
namespace core {
1214
namespace tensor {

include/core/tensor/tensor_impl.h

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
#pragma once
2+
#ifndef TENSOR_IMPL_H
3+
#define TENSOR_IMPL_H
4+
5+
#include <cstddef> // For std::size_t
6+
#include <cstdint>
7+
#include <vector>
8+
9+
namespace torchscratch {
10+
namespace core {
11+
namespace tensor {
12+
13+
class DType;
14+
15+
/**
16+
* Internal implementation for Tensor class.
17+
*/
18+
struct TensorImpl {
19+
void* data_ = nullptr; // Raw data pointer
20+
std::vector<int64_t> shape_; // Tensor shape
21+
std::vector<int64_t> strides_; // Strides (bytes between elements)
22+
DType* dtype_ = nullptr; // Placeholder for data type
23+
bool is_contiguous_ = true; // Contiguity flag
24+
bool owns_data_ = true; // Ownership of data
25+
26+
TensorImpl() = default;
27+
28+
TensorImpl(const std::vector<int64_t>& shape, DType* dtype);
29+
30+
// Copy constructor - Create a shallow copy (share data pointer)
31+
TensorImpl(const TensorImpl& other);
32+
33+
// Move constructor
34+
TensorImpl(TensorImpl&& other) noexcept;
35+
36+
// Assignment operators
37+
TensorImpl& operator=(const TensorImpl& other);
38+
TensorImpl& operator=(TensorImpl&& other) noexcept;
39+
40+
~TensorImpl();
41+
42+
static std::vector<int64_t> compute_strides(const std::vector<int64_t>& shape);
43+
44+
// Helper method to get element at specified indices
45+
template <typename T>
46+
T& get(const std::vector<int64_t>& indices) {
47+
std::size_t offset = 0;
48+
for (std::size_t i = 0; i < indices.size(); ++i) {
49+
offset += indices[i] * strides_[i];
50+
}
51+
return static_cast<T*>(data_)[offset];
52+
}
53+
54+
template <typename T>
55+
const T& get(const std::vector<int64_t>& indices) const {
56+
std::size_t offset = 0;
57+
for (std::size_t i = 0; i < indices.size(); ++i) {
58+
offset += indices[i] * strides_[i];
59+
}
60+
return static_cast<const T*>(data_)[offset];
61+
}
62+
};
63+
64+
} // namespace tensor
65+
} // namespace core
66+
} // namespace torchscratch
67+
68+
#endif // TENSOR_IMPL_H

reports/cppcheck_report.txt

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
1+
Checking /home/vansh5632/sudo/nn/src/core/autograd/engine.cpp ...
2+
1/4 files checked 44% done
13
Checking /home/vansh5632/sudo/nn/src/core/tensor/ops.cpp ...
2-
1/2 files checked 35% done
4+
2/4 files checked 63% done
35
Checking /home/vansh5632/sudo/nn/src/core/tensor/tensor.cpp ...
4-
/home/vansh5632/sudo/nn/src/core/tensor/tensor.cpp:95:3: performance: Variable 'impl_' is assigned in constructor body. Consider performing initialization in initialization list. [useInitializationList]
6+
/home/vansh5632/sudo/nn/src/core/tensor/tensor.cpp:33:3: performance: Variable 'impl_' is assigned in constructor body. Consider performing initialization in initialization list. [useInitializationList]
57
impl_ = std::make_unique<TensorImpl>(shape, dtype);
68
^
7-
/home/vansh5632/sudo/nn/src/core/tensor/tensor.cpp:99:3: performance: Variable 'impl_' is assigned in constructor body. Consider performing initialization in initialization list. [useInitializationList]
9+
/home/vansh5632/sudo/nn/src/core/tensor/tensor.cpp:37:3: performance: Variable 'impl_' is assigned in constructor body. Consider performing initialization in initialization list. [useInitializationList]
810
impl_ = std::make_unique<TensorImpl>(shape, dtype);
911
^
10-
2/2 files checked 100% done
12+
3/4 files checked 87% done
13+
Checking /home/vansh5632/sudo/nn/src/core/tensor/tensor_impl.cpp ...
14+
4/4 files checked 100% done

0 commit comments

Comments
 (0)