Skip to content

Add torch backend - #1922

Open
fogsong233 wants to merge 4 commits into
vgvassilev:masterfrom
fogsong233:add-torch-backedn
Open

Add torch backend#1922
fogsong233 wants to merge 4 commits into
vgvassilev:masterfrom
fogsong233:add-torch-backedn

Conversation

@fogsong233

@fogsong233 fogsong233 commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

Status

Still in progress. The initial LibTorch integration is functional, but several TODO items remain.

TODO

  • Accept native torch::Tensor / at::Tensor inputs without exposing raw storage pointers.
  • Support composition across user-defined Tensor -> Tensor helper functions.
  • Support scalar loss functions through Tensor::item<float>().
  • Add custom derivatives for add, sub, mul, div, relu, and dot.
  • Support Tensor-Tensor operators +, -, *, and /.
  • Support .add(), .sub(), .mul(), .div(), .relu(), and .dot().
  • Recognize torch::, at::, and namespace-alias API spellings.
  • Handle Tensor copy/move construction and independent adjoint storage.
  • Fix direct memory-return differentiation through ReturnStmt.
  • Compare generated gradients against torch::autograd::grad.
  • Add a Clad-versus-LibTorch autograd benchmark.
  • Fix the Clad AST cloning crash for chained rvalue calls such as return output.dot(lhs).item<float>();.
  • Add Tensor-scalar and scalar-Tensor overloads for +, -, *, and /.
  • Add scalar overloads for .add(), .sub(), .mul(), and .div().
  • Define and implement scalar-adjoint reduction semantics.
  • Add in-place operators +=, -=, *=, and /=.
  • Add .add_(), .sub_(), .mul_(), and .div_() with correct mutation and tape semantics.
  • Strengthen adjoint alias handling for distinct Tensor views sharing storage.
  • Add broadcasting support with reduction back to each input shape.
  • Add support for additional dtypes, devices, layouts, and non-contiguous tensors.
  • Make the Clad and autograd benchmark workloads fully symmetric, including scalar extraction.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clang-tidy made some suggestions

There were too many comments to post at once. Showing the first 10 out of 20. Check the log or trigger a new build to see more.

@@ -0,0 +1,89 @@
#include "clad/Differentiator/Differentiator.h"
#include "clad/Differentiator/TorchBuiltins.h"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: included header TorchBuiltins.h is not used directly [misc-include-cleaner]

Suggested change

return loss.item<float>();
}

struct Inputs {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: constructor does not initialize these fields: prediction, target [cppcoreguidelines-pro-type-member-init]

benchmark/LibTorch/TorchOpsBenchmark.cpp:19:

-   torch::Tensor prediction;
-   torch::Tensor target;
+   torch::Tensor prediction{};
+   torch::Tensor target{};


void BM_CladGradient(benchmark::State& state) {
const auto size = state.range(0);
const auto inputs = make_inputs(size, false);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: argument comment missing for literal argument 'requires_grad' [bugprone-argument-comment]

Suggested change
const auto inputs = make_inputs(size, false);
const auto inputs = make_inputs(size, /*requires_grad=*/false);


void BM_LibTorchAutograd(benchmark::State& state) {
const auto size = state.range(0);
const auto inputs = make_inputs(size, true);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: argument comment missing for literal argument 'requires_grad' [bugprone-argument-comment]

Suggested change
const auto inputs = make_inputs(size, true);
const auto inputs = make_inputs(size, /*requires_grad=*/true);

@@ -0,0 +1,271 @@
#include "clad/Differentiator/Differentiator.h"
#include "clad/Differentiator/TorchBuiltins.h"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: included header TorchBuiltins.h is not used directly [misc-include-cleaner]

Suggested change

#include <iostream>
#include <stdexcept>
#include <type_traits>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: included header type_traits is not used directly [misc-include-cleaner]

Suggested change

Comment thread benchmark/LibTorch/TorchOpsTest.cpp Outdated
}

template <typename Callback>
void require_c10_error(Callback&& callback, const char* message) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: forwarding reference parameter 'callback' is never forwarded inside the function body [cppcoreguidelines-missing-std-forward]

void require_c10_error(Callback&& callback, const char* message) {
                                  ^


// Public umbrella header for Clad's ATen custom derivatives.
#include "clad/Differentiator/TorchBuiltins/BasicOps.h"
#include "clad/Differentiator/TorchBuiltins/TensorLifecycle.h"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: included header BasicOps.h is not used directly [misc-include-cleaner]

Suggested change
#include "clad/Differentiator/TorchBuiltins/TensorLifecycle.h"
#include "clad/Differentiator/TorchBuiltins/TensorLifecycle.h"

// Public umbrella header for Clad's ATen custom derivatives.
#include "clad/Differentiator/TorchBuiltins/BasicOps.h"
#include "clad/Differentiator/TorchBuiltins/TensorLifecycle.h"
#include "clad/Differentiator/TorchBuiltins/TensorSyntax.h"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: included header TensorLifecycle.h is not used directly [misc-include-cleaner]

Suggested change
#include "clad/Differentiator/TorchBuiltins/TensorSyntax.h"
#include "clad/Differentiator/TorchBuiltins/TensorSyntax.h"

#include "clad/Differentiator/TorchBuiltins/BasicOps.h"
#include "clad/Differentiator/TorchBuiltins/TensorLifecycle.h"
#include "clad/Differentiator/TorchBuiltins/TensorSyntax.h"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: included header TensorSyntax.h is not used directly [misc-include-cleaner]

Suggested change

@codecov

codecov Bot commented Jul 25, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clang-tidy made some suggestions


namespace clad::custom_derivatives::class_functions {

inline ::clad::ValueAndAdjoint<float, float>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: no header providing "clad::ValueAndAdjoint" is directly included [misc-include-cleaner]

include/clad/Differentiator/TorchBuiltins/BasicOps.h:4:

+ #include <clad/Differentiator/BuiltinDerivatives.h>


inline ::clad::ValueAndAdjoint<::at::Tensor, ::at::Tensor>
constructor_reverse_forw(ConstructorPushforwardTag<::at::Tensor>,
::at::Tensor&& input, ::at::Tensor&& /*d_input*/) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: rvalue reference parameter '' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]

                         ::at::Tensor&& input, ::at::Tensor&& /*d_input*/) {
                                                                         ^


inline ::clad::ValueAndAdjoint<::at::Tensor, ::at::Tensor>
constructor_reverse_forw(ConstructorPushforwardTag<::at::Tensor>,
::at::Tensor&& input, ::at::Tensor&& /*d_input*/) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: rvalue reference parameter 'input' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]

                         ::at::Tensor&& input, ::at::Tensor&& /*d_input*/) {
                                        ^

::clad::torch::detail::propagate_adjoint(d_this, d_input);
}

inline void constructor_pullback(::at::Tensor&& /*input*/, ::at::Tensor* d_this,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: rvalue reference parameter '' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]

inline void constructor_pullback(::at::Tensor&& /*input*/, ::at::Tensor* d_this,
                                                         ^

#define CLAD_DIFFERENTIATOR_TORCHBUILTINS_TENSORSUPPORT_H

#include "clad/Differentiator/BuiltinDerivatives.h"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: included header BuiltinDerivatives.h is not used directly [misc-include-cleaner]

Suggested change


#include "clad/Differentiator/BuiltinDerivatives.h"

#include <ATen/ATen.h>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: 'ATen/ATen.h' file not found [clang-diagnostic-error]

#include <ATen/ATen.h>
         ^

return {::std::move(value), ::std::move(adjoint)};
}

inline void accumulate(::at::Tensor* destination,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: pointer parameter 'destination' can be pointer to const [readability-non-const-parameter]

Suggested change
inline void accumulate(::at::Tensor* destination,
inline void accumulate(const ::at::Tensor* destination,

destination->add_(contribution);
}

inline void propagate_adjoint(::at::Tensor* source, ::at::Tensor* destination) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: pointer parameter 'destination' can be pointer to const [readability-non-const-parameter]

Suggested change
inline void propagate_adjoint(::at::Tensor* source, ::at::Tensor* destination) {
inline void propagate_adjoint(::at::Tensor* source, const ::at::Tensor* destination) {

destination->add_(contribution);
}

inline void propagate_adjoint(::at::Tensor* source, ::at::Tensor* destination) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: pointer parameter 'source' can be pointer to const [readability-non-const-parameter]

Suggested change
inline void propagate_adjoint(::at::Tensor* source, ::at::Tensor* destination) {
inline void propagate_adjoint(const ::at::Tensor* source, ::at::Tensor* destination) {

return false;
// A call returned directly is still consumed by the enclosing
// function, including its value and adjoint in reverse_forw mode.
if (isa<ReturnStmt>(S))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: no header providing "clang::ReturnStmt" is directly included [misc-include-cleaner]

        if (isa<ReturnStmt>(S))
                ^

@github-actions

Copy link
Copy Markdown
Contributor

clang-tidy review says "All clean, LGTM! 👍"

@github-actions

Copy link
Copy Markdown
Contributor

clang-tidy review says "All clean, LGTM! 👍"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant