Replies: 2 comments 2 replies
-
PS: I am trying to port my library from enzyme to clad (mostly owing to ease of distribution, and possibility of using advanced C++ functions), what would be best way forward to design my functions? Currently in enzyme I have workflow where I inherit a parent class and create virtualreverse objects for differentiations, example (from https://github.com/ipcamit/colabfit-descriptor-library/blob/master/Descriptors.cpp): void Descriptor::gradient(int n_atoms /* contributing */,
//... params
double *desc,
double *d_desc, /* vector for vjp or jvp */
DescriptorKind *desc_kind) {
switch (desc_kind->descriptor_kind) {
case KindSymmetryFunctions: {
auto d_desc_kind = new SymmetryFunctions();
*((void **) d_desc_kind) = __enzyme_virtualreverse(*((void **) d_desc_kind));
d_desc_kind->clone_empty(desc_kind); // empty object with parameters to be differentiated against
__enzyme_autodiff(compute, /* fn to be differentiated */
enzyme_const, n_atoms, /* Do not diff. against integer params */
//params ...
enzyme_dup, desc, d_desc,
enzyme_dup, desc_kind, d_desc_kind);
delete d_desc_kind;
return;
}
case //... so on What can be the most painless way to achieve the equivalent in clad? |
Beta Was this translation helpful? Give feedback.
-
Hi @ipcamit, Thank you very creating this discussion. The reason the code is crashing is that Clad has limited support for pointers in the reverse mode. The below code works fine: #include <iostream>
#include <cmath>
#include "clad/Differentiator/Differentiator.h"
//class ContainerParent {
//public:
// int power;
// double * params;
// virtual void f(double * x, double * y) = 0;
//};
class ContainerChild {
public:
int size;
int power;
ContainerChild(int size_ = 0) {
power = 2;
size = size_;
}
void f(double * x, double * y) {
for (int i = 0; i < size; i++) {
y[i] = std::pow(x[i], power);
}
}
};
void wrapper(double * x, double * y, ContainerChild &container) {
container.f(x, y);
}
int main() {
ContainerChild * container = new ContainerChild(5);
ContainerChild * d_container = new ContainerChild(5);
auto wrapper_f = clad::gradient(wrapper);
double x[5] = {1, 2, 3, 4, 5};
double y[5] = {0, 0, 0, 0, 0};
double dx[5] = {0, 0, 0, 0, 0};
double dy[5] = {1, 1, 1, 1, 1};
wrapper(x, y, *container);
wrapper_f.execute(x, y, *container, dx, dy, d_container);
wrapper_f.dump();
} Please note that There are differences in the interface of Clad and Enzyme. Unlike enzyme, double fn(double x0, long double x1, ...) {
// ...
// ...
return y;
} Differentiating That being said, the function which returns I will get back to the question which you asked in the comment later today. |
Beta Was this translation helpful? Give feedback.
-
I want to pass the class which contains all parameters and functions to a wrapper function, and differentiate against it. I is possible?
Please see the example below:
When I compile it as
I get following error:
Beta Was this translation helpful? Give feedback.
All reactions