Giter Club home page Giter Club logo

clad's People

Contributors

alexander-penev avatar arora-vidushi avatar axmat avatar bedupako12mas avatar blide avatar deadspheroid avatar dependabot[bot] avatar efremale avatar grimmmyshini avatar hahnjo avatar ioanaif avatar kchristin22 avatar krishna-13-cyber avatar maximusron avatar mcbarton avatar mfoco avatar mihailmihov avatar mvassilev avatar nirhar avatar oshadura avatar parth-07 avatar pcanal avatar petrozarytskyi avatar phrygiangates avatar reikdas avatar ris-bali avatar sauravuppoor avatar sudo-panda avatar vaithak avatar vgvassilev avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

clad's Issues

Testsuite fails when clad is built against Debug clang

Failing Tests (3):
    clad :: FirstDerivative/TemplateFunction.C
    clad :: Gradient/Gradients.C
    clad :: Gradient/TestAgainstDiff.C

  Expected Passes    : 18
  Expected Failures  : 3
  Unexpected Failures: 3
lldb -- /Users/vvassilev/workspace/builds/llvm-root-debug/obc/bin/clang-5.0 -cc1 -triple x86_64-apple-macosx10.12.0 -Wdeprecated-objc-isa-usage -Werror=deprecated-objc-isa-usage -emit-obj -mrelax-all -disable-free -main-file-name Gradients.C -mrelocation-model pic -pic-level 2 -mthread-model posix -mdisable-fp-elim -masm-verbose -munwind-tables -faligned-alloc-unavailable -target-cpu penryn -target-linker-version 305 -dwarf-column-info -debugger-tuning=lldb -resource-dir /Users/vvassilev/workspace/builds/llvm-root-debug/obc/bin/../../../../../llvm-root-debug/lib/clang/5.0.0/ -I /Users/vvassilev/workspace/sources/root-llvm/tools/clad/test/Gradient/../../include -stdlib=libc++ -std=c++11 -fdeprecated-macro -fdebug-compilation-dir /Users/vvassilev/workspace/builds/llvm-root-debug/obc -ferror-limit 19 -fmessage-length 117 -stack-protector 1 -fblocks -fobjc-runtime=macosx-10.12.0 -fencode-extended-block-signature -fcxx-exceptions -fexceptions -fmax-type-align=16 -fdiagnostics-show-option -fcolor-diagnostics -add-plugin clad -plugin-arg-clad -fdump-derived-fn -load /Users/vvassilev/workspace/builds/llvm-root-debug/obc/./lib/clad.dylib -o /var/folders/cp/g4fhftbd5c3fsp08mc8nr1pr0000gn/T/Gradients-848bce.o -x c++ /Users/vvassilev/workspace/sources/root-llvm/tools/clad/test/Gradient/Gradients.C

* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGABRT
    ❲ 0❳ __pthread_kill ❮libsystem_kernel.dylib❯
    ❲ 1❳ pthread_kill ❮libsystem_pthread.dylib❯
    ❲ 2❳ abort ❮libsystem_c.dylib❯
    ❲ 3❳ __assert_rtn ❮libsystem_c.dylib❯
    ❲ 4❳ void clang::CodeGen::CodeGenFunction::EmitCallArgs<clang::FunctionProtoType>(this=0x00007fff5fbf6738, Args=0x00007fff5fbf5588, CallArgTypeInfo=0x000000010d04dc10, ArgRange=iterator_range<clang::Stmt::ConstExprIterator> @ 0x00007fff5fbf4dd0, AC=AbstractCallee @ 0x00007fff5fbf4dc8, ParamsToSkip=0, Order=Default) at CodeGenFunction.h:3770 ❮clang-5.0❯
    ❲ 5❳ clang::CodeGen::CodeGenFunction::EmitCall(this=0x00007fff5fbf6738, CalleeType=QualType @ 0x00007fff5fbf5490, OrigCallee=0x00007fff5fbf5950, E=0x000000010d04df90, ReturnValue=ReturnValueSlot @ 0x00007fff5fbf5480, Chain=0x0000000000000000) at CGExpr.cpp:4468 ❮clang-5.0❯
  * ❲ 6❳ clang::CodeGen::CodeGenFunction::EmitCallExpr(this=0x00007fff5fbf6738, E=0x000000010d04df90, ReturnValue=ReturnValueSlot @ 0x00007fff5fbf59e0) at CGExpr.cpp:4089 ❮clang-5.0❯
    ❲ 7❳ (anonymous namespace)::AggExprEmitter::VisitCallExpr(this=0x00007fff5fbf5ba8, E=0x000000010d04df90) at CGExprAgg.cpp:782 ❮clang-5.0❯
    ❲ 8❳ clang::StmtVisitorBase<clang::make_ptr, (anonymous namespace)::AggExprEmitter, void>::Visit(this=0x00007fff5fbf5ba8, S=0x000000010d04df90) at StmtNodes.inc:329 ❮clang-5.0❯
    ❲ 9❳ (anonymous namespace)::AggExprEmitter::Visit(this=0x00007fff5fbf5ba8, E=0x000000010d04df90) at CGExprAgg.cpp:104 ❮clang-5.0❯
    ❲10❳ clang::CodeGen::CodeGenFunction::EmitAggExpr(this=0x00007fff5fbf6738, E=0x000000010d04df90, Slot=AggValueSlot @ 0x00007fff5fbf5c10) at CGExprAgg.cpp:1548 ❮clang-5.0❯
    ❲11❳ clang::CodeGen::CodeGenFunction::EmitAnyExpr(this=0x00007fff5fbf6738, E=0x000000010d04df90, aggSlot=AggValueSlot @ 0x00007fff5fbf5cf0, ignoreResult=true) at CGExpr.cpp:180 ❮clang-5.0❯
    ❲12❳ clang::CodeGen::CodeGenFunction::EmitIgnoredExpr(this=0x00007fff5fbf6738, E=0x000000010d04df90) at CGExpr.cpp:159 ❮clang-5.0❯
    ❲13❳ clang::CodeGen::CodeGenFunction::EmitStmt(this=0x00007fff5fbf6738, S=0x000000010d04df90) at CGStmt.cpp:107 ❮clang-5.0❯
    ❲14❳ clang::CodeGen::CodeGenFunction::EmitCompoundStmtWithoutScope(this=0x00007fff5fbf6738, S=0x000000010d0512d8, GetLast=false, AggSlot=AggValueSlot @ 0x00007fff5fbf5fa0) at CGStmt.cpp:381 ❮clang-5.0❯
    ❲15❳ clang::CodeGen::CodeGenFunction::EmitCompoundStmt(this=0x00007fff5fbf6738, S=0x000000010d0512d8, GetLast=false, AggSlot=AggValueSlot @ 0x00007fff5fbf60f0) at CGStmt.cpp:371 ❮clang-5.0❯
    ❲16❳ clang::CodeGen::CodeGenFunction::EmitSimpleStmt(this=0x00007fff5fbf6738, S=0x000000010d0512d8) at CGStmt.cpp:344 ❮clang-5.0❯
    ❲17❳ clang::CodeGen::CodeGenFunction::EmitStmt(this=0x00007fff5fbf6738, S=0x000000010d0512d8) at CGStmt.cpp:53 ❮clang-5.0❯
    ❲18❳ clang::CodeGen::CodeGenFunction::EmitCompoundStmtWithoutScope(this=0x00007fff5fbf6738, S=0x000000010d05eb78, GetLast=false, AggSlot=AggValueSlot @ 0x00007fff5fbf6370) at CGStmt.cpp:381 ❮clang-5.0❯
    ❲19❳ clang::CodeGen::CodeGenFunction::EmitFunctionBody(this=0x00007fff5fbf6738, Args=0x00007fff5fbf6600, Body=0x000000010d05eb78) at CodeGenFunction.cpp:1035 ❮clang-5.0❯
    ❲20❳ clang::CodeGen::CodeGenFunction::GenerateCode(this=0x00007fff5fbf6738, GD=GlobalDecl @ 0x00007fff5fbf6588, Fn=0x000000010c81c718, FnInfo=0x000000010c81d5e0) at CodeGenFunction.cpp:1205 ❮clang-5.0❯
    ❲21❳ clang::CodeGen::CodeGenModule::EmitGlobalFunctionDefinition(this=0x000000010d819c00, GD=GlobalDecl @ 0x00007fff5fbf6730, GV=0x000000010c81c718) at CodeGenModule.cpp:3207 ❮clang-5.0❯
    ❲22❳ clang::CodeGen::CodeGenModule::EmitGlobalDefinition(this=0x000000010d819c00, GD=GlobalDecl @ 0x00007fff5fbf7b88, GV=0x0000000000000000) at CodeGenModule.cpp:2037 ❮clang-5.0❯
    ❲23❳ clang::CodeGen::CodeGenModule::EmitGlobal(this=0x000000010d819c00, GD=GlobalDecl @ 0x00007fff5fbf7d70) at CodeGenModule.cpp:1812 ❮clang-5.0❯
    ❲24❳ clang::CodeGen::CodeGenModule::EmitTopLevelDecl(this=0x000000010d819c00, D=0x000000010d04cc50) at CodeGenModule.cpp:3937 ❮clang-5.0❯
    ❲25❳ clang::CodeGeneratorImpl::HandleTopLevelDecl(this=0x000000010ce095b0, DG=DeclGroupRef @ 0x00007fff5fbf97d8) at ModuleBuilder.cpp:322 ❮clang-5.0❯
    ❲26❳ clang::BackendConsumer::HandleTopLevelDecl(this=0x000000010ce093d0, D=DeclGroupRef @ 0x00007fff5fbf9870) at CodeGenAction.cpp:136 ❮clang-5.0❯

(lldb) f 4
❲ 4❳ void clang::CodeGen::CodeGenFunction::EmitCallArgs<clang::FunctionProtoType>(this=0x00007fff5fbf6738, Args=0x00007fff5fbf5588, CallArgTypeInfo=0x000000010d04dc10, ArgRange=iterator_range<clang::Stmt::ConstExprIterator> @ 0x00007fff5fbf4dd0, AC=AbstractCallee @ 0x00007fff5fbf4dc8, ParamsToSkip=0, Order=Default) at CodeGenFunction.h:3770 ❮clang-5.0❯
   3767	                E = CallArgTypeInfo->param_type_end();
   3768	           I != E; ++I, ++Arg) {
   3769	        assert(Arg != ArgRange.end() && "Running over edge of argument list!");
-> 3770	        assert((isGenericMethod ||
   3771	                ((*I)->isVariablyModifiedType() ||
   3772	                 (*I).getNonReferenceType()->isObjCRetainableType() ||
   3773	                 getContext()
(lldb) p isGenericMethod
(bool) $1 = false
(lldb) up
❲ 5❳ clang::CodeGen::CodeGenFunction::EmitCall(this=0x00007fff5fbf6738, CalleeType=QualType @ 0x00007fff5fbf5490, OrigCallee=0x00007fff5fbf5950, E=0x000000010d04df90, ReturnValue=ReturnValueSlot @ 0x00007fff5fbf5480, Chain=0x0000000000000000) at CGExpr.cpp:4468 ❮clang-5.0❯
   4465	    }
   4466	  }
   4467	
-> 4468	  EmitCallArgs(Args, dyn_cast<FunctionProtoType>(FnType), E->arguments(),
   4469	               E->getDirectCallee(), /*ParamsToSkip*/ 0, Order);
   4470	
   4471	  const CGFunctionInfo &FnInfo = CGM.getTypes().arrangeFreeFunctionCall(
(lldb) p E->dump()
CallExpr 0x10d04df90 'CladFunction<false, void, double, double, double *>':'class clad::CladFunction<false, void, double, double, double *>'
|-ImplicitCastExpr 0x10d04df78 'CladFunction<false, void, double, double, double *> (*)(double (*)(double, double), const char *)' <FunctionToPointerDecay>
| `-DeclRefExpr 0x10d04dee0 'CladFunction<false, void, double, double, double *> (double (*)(double, double), const char *)' lvalue Function 0x10d04dd40 'gradient' 'CladFunction<false, void, double, double, double *> (double (*)(double, double), const char *)' (FunctionTemplate 0x10d03cf80 'gradient')
|-ImplicitCastExpr 0x10d066070 'void (*)(double, double, double *)' <FunctionToPointerDecay>
| `-DeclRefExpr 0x10d066048 'void (double, double, double *)' lvalue Function 0x10d065cc0 'f_add1_grad' 'void (double, double, double *)'
`-ImplicitCastExpr 0x10d0661a0 'const char *' <ArrayToPointerDecay>
  `-StringLiteral 0x10d066108 'const char [107]' lvalue "void f_add1_grad(double x, double y, double *_result) {\n    _result[0UL] += 1.;\n    _result[1UL] += 1.;\n}\n"

It looks like some of our newly generated expressions do not set some relevant properties.

@efremale, could you take a look?

Add clearer indication for results of differentiation of functions for which no derivative in custom_derivatives exist

Currently, if differentiation process meets a function which has no defined derivative in custom_derivatives namespace, its derivative is set to be 0.

Example:

double f(double x) {
  printf("%d", x);
  return x;
}

->

double f_darg0(double x) {
  0;
  printf("%d", x);
  return 1;
}

Since there exist no custom_derivatives::printf_darg0, we set the derivative of printf to be zero.
In principle, we could detect it and return null instead, but this would break cases when printf is used in expressions, e.g. int i = x + printf(...); -> int _d_i = _d_x + 0;. This is an obscure case, but it makes sense to use 0 in such expressions (say, if it is not printf, but some non-differentiable math function, we cannot determine that).

Should we indicate more clearly where does this 0 come from? E.g.

double f_darg0(double x) {
  int printf_darg0_non_differentiable = 0;
  printf_darg0_non_differentiable;
  printf("%d", x);
  return 1;
}

Clad generate "Must be the same types" assert when one of params is struct

struct Vec {
  float x, y, z;
}

float sphere_implicit_func(float x, float y, float z, Vec &p, float r) {
  return (x-p.x)*(x-p.x) + (y-p.y)*(y-p.y) + (z-p.z)*(z-p.z) - r*r;
}

Fires "Assertion failed: (lhs_derived->getType() == rhs_derived->getType() && "Must be the same types."), function VisitBinaryOperator" during compilation,

but

float sphere_implicit_func(float x, float y, float z, float px, float py, float pz, float r) {
  return (x-px)*(x-px) + (y-py)*(y-py) + (z-pz)*(z-pz) - r*r;
}

is OK.

Assert message and error must be more descriptive

Assertion failed: (lhs_derived->getType() == rhs_derived->getType() && "Must be the same types."), function VisitBinaryOperator, file /Users/alexanderpenev/clad/src/tools/clad/lib/Differentiator/DerivativeBuilder.cpp, line 453.
This message does not help the user. Better text should contains information on function, which can not differentiate, if possible row and column of the user program. Best messages or warnings in style clang.

Repeated expressions in the derived function result in repeated statements in the derivative.

Example:

double f(double x, double y) {
  double t = (x - y) * (x - y);
  return t;
}

->

double f_darg0(double x, double y) {
  double _t0 = (x - y);
  double _t1 = (x - y);
  double _d_t = (1. - 0.) * _t1 + _t0 * (1. - 0.);
  double t = _t0 * _t1;
  return _d_t;
}

Variables _t0 and _t1 are redundant. Since the original function uses (x - y) on several places, we get several temporaries for it.

We do not check the original function for repeated expressions, it would add quite a huge computational overhead. Moreover, since it was acceptable for the original function to use the same expression repeatedly, it is presumably acceptable to do so in the derivative.

Implement simple constant folder

The chained rule of differentiation produces a lot of trivial constants to fold. For example:
return 1 + (0) + (1) + (0) + (1).

x/=r; does not differentiate properly

double hyperbolic_octahedron_func(double x, double y, double z, const Vec &p, double r) {
  x/=r; y/=r; z/=r;                        
  return pow(x, 2/3) + pow(y, 2/3) + pow(z, 2/3) - 1;
}

generate:

double hyperbolic_octahedron_func_dx(double x, double y, double z, const Vec &p, double r) {
    1. /= 0.;
    0. /= 0.;
    0. /= 0.;
    return pow_dx(x, 2 / 3);
}

but

double hyperbolic_octahedron_func(double x, double y, double z, const Vec &p, double r) {
  x=x/r; y=y/r; z=z/r;                        
  return pow(x, 2/3) + pow(y, 2/3) + pow(z, 2/3) - 1;
}

is OK, generating:

double hyperbolic_octahedron_func_dx(double x, double y, double z, const Vec &p, double r) {
    x = r / (r * r);
    y = 0.;
    z = 0.;
    return pow_dx(x, 2 / 3);
}

Allow to turn on/off clad derivative scanning

Such mechanism would help clients to selectively enable the derivative computation. Eg:

#pragma clad on
// synthesized code which we know will have a call to clad::*
#pragma clad off

Built-in derivatives do not work

There are problem with internal function like sqrt. For example

float func(float x, float y) {
  return sqrt(x * x + y * y) - y;
}

after clad::differentiate(func, 1) is

float func_derived_x(float x, float y) {
    return sqrt(x * x + y * y) - (0.F);
}

but it must something like that:

float func_derived_x(float x, float y) {
    return ((1.F * x + x * 1.F) + ((0.F * y + y * 0.F))) * (1.F / (2.F * sqrt(x * x + y * y)) - (0.F));
}

"Must be the same types" strange case

This function is differentiate without problems:

float sphere_implicit_func(float x, float y, float z, float px, float py, float pz, float r) {
  return (x-px)*(x-px) + (y-py)*(y-py) + (z-pz)*(z-pz) - r*r;
}

but this

float sphere_distance_func(float x, float y, float z, float px, float py, float pz, float r) {
  return (x-px)*(x-px) + (y-py)*(y-py) + (z-pz)*(z-pz) - r;
}

generate compile time assertion:

Assertion failed: (lhs_derived->getType() == rhs_derived->getType() && "Must be the same types."), function VisitBinaryOperator, file /Users/alexanderpenev/clad/src/tools/clad/lib/Differentiator/DerivativeBuilder.cpp, line 453.

This workaround

float sphere_distance_func(float x, float y, float z, float px, float py, float pz, float r) {
  return (x-px)*(x-px) + (y-py)*(y-py) + (z-pz)*(z-pz) - r*1.0f;
}

also is OK.

Would it be possible to implement forward mode by simply replacing all numerical types with dual-number types?

The idea is to replace each type RealT with the type dual<RealT, RealT>, where dual has overloaded operators such that the first element is the same as the original value and the second element is the value of its derivative. This is easy to achieve by employing basic differentiation rules for operators.

On the first sight, it appears to be a much easier way of supporting more general C++ constructs as they need not be treated separately anymore.

Similar idea is in "Automatic Differentiation in 10 minutes with Julia": https://www.youtube.com/watch?v=vAp6nUMrKYg&t=683s

Structure fields do not differentiated correctly

Differentiate

struct Vec { float x,y,z; };
float f_const_args_func_4(float x, float y, const Vec v) {
  return x * x + y * y - v.x;
}

return

float f_const_args_func_4_dx(const float x, const float y, const Vec v) {
  return (1.F * x + x * 1.F) + ((0.F * y + y * 0.F)) - (v.x);
}

but we expect

float f_const_args_func_4_dx(const float x, const float y, const Vec v) {
  return (1.F * x + x * 1.F) + ((0.F * y + y * 0.F)) - (0.F);
}

Reduce cloning complexity in forward mode

Each call to Clone() has complexity of O(n), where n is the size of the Stmt's subtree, since it recursively calls Clone() on every substatement until leaves are reached.

When differentiating a function via Forward/ReverseModeVisitor, we potentially call Clone() on every node of the AST tree (which recursively clones all subnodes, we are cloning same nodes multiple times) and have the total complexity of O(n^2).

Wouldn't it be more efficient to Clone() the whole tree just once before calling Visit() on it? The complexity should be just 2xO(n).

Position of output parameter in gradient calls

Now we pass the output _result array to gradient functions as a last parameter.
This causes some problems, e.g.,
default parameter values cannot be used as the _result parameter is last and has no default value.
This leads to generation of functions like

void f_grad(double x, double y = default_y, double* _result);

where there is no way to actually call it with default_y value.

Some problems may also arise when f or f_grad is declared as variadic template function.

Are there better solutions?
Does it make sense to pass _result as a first parameter?

Recursive functions are not differentiated correctly

A call to itself inside a function body is not treated correctly.

For example, if we differentiate

double r(double x) {
  if (x > 0)
    return r(x-1);
  else
    return x;

the call r(x-1) is treated as a call to some other function and we get the warning: function 'r' was not differentiated because it is not declared in namespace 'custom_derivatives' attempted differention of function 'r', which does not have a definition.

The following derivative is generated:

double r_darg0(double x) {
  if (x > 0)
    return r(x-1);
  else
    return 1.0;

but the correct derivative would be

double r_darg0(double x) {
  if (x > 0)
    return r_darg0(x-1) * 1.0;
  else
    return 1.0;

Emit hard error when differentiation visits unsupported statement

Currently, if we Visit unsupported statement (e.g. try-catch, range for loop), it is simply cloned without changes and a warning is emitted.

Should we instead emit a hard error and not produce the derivative?

This is somewhat harder to achieve now.
How should the error be promoted in the visitor?
If we return null StmtDiff whenever we meet an unsupported statement, we would have to add a lot of checks for null.
We cannot throw an exception sice clang disables them.
We can set some bool flag and keep visiting function and check for the error flag in the end, but it is inefficient and error-prone.

Wrong virtual method override called.

class A {
public:
  virtual float vm(float x, float y) {
    return x + y;
  }
};
class B : public A {
public:
  float vm(float x, float y) override {
    return x*x + y*y;
  }
};
int main() {
  auto vm_darg0_A = clad::differentiate(&A::vm, 0);
  printf("Result is = %f\n", vm_darg0_A.execute(a, 2, 3)); // CHECK-EXEC: Result is = 1.0000
  auto vm_darg0_B = clad::differentiate(&B::vm, 0);
  printf("Result is = %f\n", vm_darg0_B.execute(b, 2, 3)); // CHECK-EXEC: Result is = 4.0000
}

For some reason vm_darg0_A.execute(a, 2, 3) calls the B::vm. If the execute()-s get swapped it works as expected.

Clad picks up wrong clang version

When embedded in ROOT we want to build clad with external LLVM but internal clang. Currently there is not way of detecting this and we pick up the wrong header files which manifest into a very hard-to-find bug.

Clad picks up system LLVM

Even if -DCLAD_PATH_TO_LLVM_BUILD is passed, the system llvm is discovered first.

 /cvmfs/sft.cern.ch/lcg/releases/CMake/3.11.1-773ff/x86_64-centos7-gcc62-opt/bin/cmake  -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=/cvmfs/projects.cern.ch/intelsw/psxe/linux/x86_64/2018/compilers_and_libraries_2018.2.199/linux/bin/intel64/icc -DCMAKE_C_FLAGS= -restrict -wd1572 -m64 -wd279 -wd873 -wd2536 -wd597 -wd1098 -wd1292 -wd1478 -wd3373 -pthread -fPIC -Werror=date-time -w -ffunction-sections -fdata-sections -DCMAKE_CXX_COMPILER=/cvmfs/projects.cern.ch/intelsw/psxe/linux/x86_64/2018/compilers_and_libraries_2018.2.199/linux/bin/intel64/icc -DCMAKE_CXX_FLAGS= -wd1476 -wd1572 -m64 -wd279 -wd873 -wd2536 -wd597 -wd1098 -wd1292 -wd1478 -wd3373 -pthread -std=c++11  -fPIC -fvisibility-inlines-hidden -Werror=date-time -std=c++11 -w -ffunction-sections -fdata-sections -fno-common -Woverloaded-virtual -fno-strict-aliasing -Wno-nested-anon-types -Wno-covered-switch-default -Wno-unused-local-typedef -fno-rtti -DCMAKE_INSTALL_PREFIX=/data/sftnight/workspace/root-benchmark/BUILDTYPE/Release/COMPILER/icc18/LABEL/performance-sandy-cc7/build/etc/cling/plugins/ -DCLAD_PATH_TO_LLVM_BUILD=/data/sftnight/workspace/root-benchmark/BUILDTYPE/Release/COMPILER/icc18/LABEL/performance-sandy-cc7/build/interpreter/llvm/src -G"Unix Makefiles" /data/sftnight/workspace/root-benchmark/BUILDTYPE/Release/COMPILER/icc18/LABEL/performance-sandy-cc7/build/interpreter/llvm/src/tools/cling/tools/plugins/clad/clad-prefix/src/clad
-- Could NOT find Subversion (missing: Subversion_SVN_EXECUTABLE) 
CMake Error at /opt/llvm-5.0.1/lib64/cmake/llvm/LLVMExports.cmake:960 (message):
  The imported target "LLVMDemangle" references the file

     "/opt/llvm-5.0.1/lib64/libLLVMDemangle.a"

  but this file does not exist.  Possible reasons include:

  * The file was deleted, renamed, or moved to another location.

  * An install or uninstall procedure did not complete successfully.

  * The installation package was faulty and contained

     "/opt/llvm-5.0.1/lib64/cmake/llvm/LLVMExports.cmake"

  but not all the files it references.

Call Stack (most recent call first):
  /opt/llvm-5.0.1/lib64/cmake/llvm/LLVMConfig.cmake:188 (include)
  CMakeLists.txt:8 (find_package)


-- Configuring incomplete, errors occurred!

Add an option to specify independent variables for gradients

Now we can only compute gradients w.r.t. to every argument of a function.

For efficiency reasons, it seems to be a good idea to be able to specify indices required of independent variables, e.g.:

clad::gradient(f, 0, 2, 4)

or

clad::gradient(f, {0, 2, 4})

or even

clad::gradient(f, std::index_sequence<0, 2, 4>{})

Derivative name convention

Hi,
The suffix of the derivatives should be darg0, darg1, ... dargN, because we can have scenarios where the users rely on using builtin derivatives. For example:
Builtins.h

float builtin_f(float x, double y); // in builtin derivatives becomes
float builtin_fdx(float x, double y) {}

And the user file:

float builtin_f(float a, double b);
float f(float t, float u) {
  // Here clad won't be able to find builtin_fdx, because there is not enough info in the call
  return t * u * builtin_f(t, u); 
}

Vassil

Add support for vector of points

Support double f(double*, unsigned numElements); The user should be able to specify the independent variable from a given array of variables.

Simple constant folder do not work in some cases

For example:

double sphere_implicit_func(double x, double y, double z, const Vec &p, double r) {
  return (x-p.x)*(x-p.x) + (y-p.y)*(y-p.y) + (z-p.z)*(z-p.z) - r*r;
}

generate:

double sphere_implicit_func_dx(double x, double y, double z, const Vec &p, double r) {
    return ((x - p.x) + (x - p.x));
}
double sphere_implicit_func_dy(double x, double y, double z, const Vec &p, double r) {
    return 0. + ((y - p.y) + (y - p.y));
}
double sphere_implicit_func_dz(double x, double y, double z, const Vec &p, double r) {
    return 0. + ((z - p.z) + (z - p.z));
}

Methods and Virtual methods do not differentiated

If we have

class A {
public:
  int f(int x) {
    return x;
  }
  virtual float vm(float x, float y) {
    return x + y;
  }
}

class B : public A {
public:
  float vm(float x, float y) override {
    return x*x + y*y;
  }
}

int main() {
  A a;
  B b;
  clad::differentiate(&A::f, 0);
  clad::differentiate(&A::vm, 0);
  printf("Result is = %f\n", a.vm_dx(2,3)); // Result is = 2.F
  clad::differentiate(&B::vm, 0);
  printf("Result is = %f\n", a.vm_dx(2,3)); // Result is = 4.F
  return 0;
}

clad throw error and assert message

error: no member named 'vm_dx' in 'A'
  printf("Result is = %f\n", a.vm_dx(2,3));
                             ~ ^

...

Assertion failed: (Access != AS_none && "Access specifier is AS_none inside a record decl"), function AccessDeclContextSanity, file /Users/alexanderpenev/clad/src/tools/clang/lib/AST/DeclBase.cpp, line 701.

Avoid storing simple expressions like -x in temporaries

Example:

double f(double x) {
  double t = 2 * (-x);
  return t;
}

->

double f_darg0(double x) {
    double _t0 = -x;
    double _d_t = 0 * _t0 + 2 * -1.;
    double t = 2 * _t0;
    return _d_t;
}

In this case, double _t0 = -x seems useless so it makes sense to add such simple unary operators to a list of cases for which temporaries are not generated (now it is literals and references). On the other hand, results of unary operators like ++x must be stored to avoid repeated increment.

Clad work right only when include "Differentiator.h" is first include in program

This work:

// Necessary for clad to work include
#include "clad/Differentiator/Differentiator.h"
#include <math.h>
#include <stdlib.h>
#include <stdio.h>

This generate compile time assert ("Cannot find builtin derivatives!"):

#include <math.h>
#include <stdlib.h>
#include <stdio.h>
// Necessary for clad to work include
#include "clad/Differentiator/Differentiator.h"

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.