Skip to content

Commit

Permalink
err on under-allocations and not on over-allocations (#1277)
Browse files Browse the repository at this point in the history
* err on under-allocations and not on over-allications

* test code for over-allocated tape

* test allocated tape error too

* 8 byte tape on all -O levels

---------

Co-authored-by: William Moses <gh@wsmoses.com>
  • Loading branch information
tthsqe12 and wsmoses authored Jun 26, 2023
1 parent 50b44bf commit d12e149
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 4 deletions.
4 changes: 2 additions & 2 deletions enzyme/Enzyme/Enzyme.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1421,7 +1421,7 @@ class EnzymeBase {
return true;
}
if (tapeType &&
DL.getTypeSizeInBits(tapeType) < 8 * (size_t)allocatedTapeSize) {
DL.getTypeSizeInBits(tapeType) > 8 * (size_t)allocatedTapeSize) {
auto bytes = DL.getTypeSizeInBits(tapeType) / 8;
EmitFailure("Insufficient tape allocation size", CI->getDebugLoc(),
CI, "need ", bytes, " bytes have ", allocatedTapeSize,
Expand Down Expand Up @@ -1491,7 +1491,7 @@ class EnzymeBase {
return true;
}
if (tapeType &&
DL.getTypeSizeInBits(tapeType) < 8 * (size_t)allocatedTapeSize) {
DL.getTypeSizeInBits(tapeType) > 8 * (size_t)allocatedTapeSize) {
auto bytes = DL.getTypeSizeInBits(tapeType) / 8;
EmitFailure("Insufficient tape allocation size", CI->getDebugLoc(),
CI, "need ", bytes, " bytes have ", allocatedTapeSize,
Expand Down
59 changes: 59 additions & 0 deletions enzyme/test/Integration/ReverseMode/allocatedtape.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// This should work on LLVM 7, 8, 9, however in CI the version of clang installed on Ubuntu 18.04 cannot load
// a clang plugin properly without segfaulting on exit. This is fine on Ubuntu 20.04 or later LLVM versions...
// RUN: if [ %llvmver -ge 10 ]; then %clang -std=c11 -O0 %s -S -emit-llvm -o - %loadClangEnzyme | %lli - ; fi
// RUN: if [ %llvmver -ge 10 ]; then %clang -std=c11 -O1 %s -S -emit-llvm -o - %loadClangEnzyme | %lli - ; fi
// RUN: if [ %llvmver -ge 10 ]; then %clang -std=c11 -O2 %s -S -emit-llvm -o - %loadClangEnzyme | %lli - ; fi
// RUN: if [ %llvmver -ge 10 ]; then %clang -std=c11 -O3 %s -S -emit-llvm -o - %loadClangEnzyme | %lli - ; fi
// RUN: if [ %llvmver -ge 10 ]; then %clang -std=c11 -O0 %s -S -emit-llvm -o - %loadClangEnzyme -mllvm -enzyme-inline=1 -S | %lli - ; fi
// RUN: if [ %llvmver -ge 10 ]; then %clang -std=c11 -O1 %s -S -emit-llvm -o - %loadClangEnzyme -mllvm -enzyme-inline=1 -S | %lli - ; fi
// RUN: if [ %llvmver -ge 10 ]; then %clang -std=c11 -O2 %s -S -emit-llvm -o - %loadClangEnzyme -mllvm -enzyme-inline=1 -S | %lli - ; fi
// RUN: if [ %llvmver -ge 10 ]; then %clang -std=c11 -O3 %s -S -emit-llvm -o - %loadClangEnzyme -mllvm -enzyme-inline=1 -S | %lli - ; fi
// RUN: if [ %llvmver -ge 12 ]; then %clang -std=c11 -O0 %s -S -emit-llvm -o - %newLoadClangEnzyme | %lli - ; fi
// RUN: if [ %llvmver -ge 12 ]; then %clang -std=c11 -O1 %s -S -emit-llvm -o - %newLoadClangEnzyme | %lli - ; fi
// RUN: if [ %llvmver -ge 12 ]; then %clang -std=c11 -O2 %s -S -emit-llvm -o - %newLoadClangEnzyme | %lli - ; fi
// RUN: if [ %llvmver -ge 12 ]; then %clang -std=c11 -O3 %s -S -emit-llvm -o - %newLoadClangEnzyme | %lli - ; fi
// RUN: if [ %llvmver -ge 12 ]; then %clang -std=c11 -O0 %s -S -emit-llvm -o - %newLoadClangEnzyme -mllvm -enzyme-inline=1 -S | %lli - ; fi
// RUN: if [ %llvmver -ge 12 ]; then %clang -std=c11 -O1 %s -S -emit-llvm -o - %newLoadClangEnzyme -mllvm -enzyme-inline=1 -S | %lli - ; fi
// RUN: if [ %llvmver -ge 12 ]; then %clang -std=c11 -O2 %s -S -emit-llvm -o - %newLoadClangEnzyme -mllvm -enzyme-inline=1 -S | %lli - ; fi
// RUN: if [ %llvmver -ge 12 ]; then %clang -std=c11 -O3 %s -S -emit-llvm -o - %newLoadClangEnzyme -mllvm -enzyme-inline=1 -S | %lli - ; fi

#include "test_utils.h"

extern int enzyme_dup, enzyme_allocated, enzyme_tape;
void __enzyme_autodiff(void*, ...);
void* __enzyme_augmentfwd(void*, ...);
void __enzyme_reverse(void*, ...);

#define TAPE_SIZE 100 // v0.69 wants 24 bytes, so 100 should be more than enough

// jac(f)(x) is [1 2*x1; 0 -1] as a function of the original inputs
void f(double* x) {
x[0] += x[1]*x[1];
x[1] = -x[1];
}

void f_aug(double* x, double* x_b, void* tape) {
__enzyme_augmentfwd(f, enzyme_dup, x, x_b,
enzyme_allocated, TAPE_SIZE, enzyme_tape, tape);
}

void f_rev(double* x, double* x_b, void* tape) {
__enzyme_reverse(f, enzyme_dup, x, x_b,
enzyme_allocated, TAPE_SIZE, enzyme_tape, tape);
}

int main() {
double x0 = 1.2, x1 = 3.4;
double x0_b = 5.6, x1_b = 7.8;
double x[2] = {x0, x1};
double x_b[2] = {x0_b, x1_b};
char tape[TAPE_SIZE];

f_aug(x, x_b, tape);
f_rev(x, x_b, tape);

APPROX_EQ(x[0], x0 + x1*x1, 1e-10);
APPROX_EQ(x[1], -x1, 1e-10);
APPROX_EQ(x_b[0], x0_b*(1) + x1_b*(0), 1e-10);
APPROX_EQ(x_b[1], x0_b*(2*x1) + x1_b*(-1), 1e-10);
}
22 changes: 22 additions & 0 deletions enzyme/test/Integration/ReverseMode/allocatedtape_err.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// RUN: if [ %llvmver -ge 10 ]; then %clang -std=c11 -g -O0 %s -S -emit-llvm -o - %loadClangEnzyme -Xclang -verify; fi
// RUN: if [ %llvmver -ge 10 ]; then %clang -std=c11 -g -O1 %s -S -emit-llvm -o - %loadClangEnzyme -Xclang -verify; fi
// RUN: if [ %llvmver -ge 10 ]; then %clang -std=c11 -g -O2 %s -S -emit-llvm -o - %loadClangEnzyme -Xclang -verify; fi
// RUN: if [ %llvmver -ge 10 ]; then %clang -std=c11 -g -O3 %s -S -emit-llvm -o - %loadClangEnzyme -Xclang -verify; fi
// RUN: if [ %llvmver -ge 12 ]; then %clang -std=c11 -g -O0 %s -S -emit-llvm -o - %newLoadClangEnzyme -Xclang -verify; fi
// RUN: if [ %llvmver -ge 12 ]; then %clang -std=c11 -g -O1 %s -S -emit-llvm -o - %newLoadClangEnzyme -Xclang -verify; fi
// RUN: if [ %llvmver -ge 12 ]; then %clang -std=c11 -g -O2 %s -S -emit-llvm -o - %newLoadClangEnzyme -Xclang -verify; fi
// RUN: if [ %llvmver -ge 12 ]; then %clang -std=c11 -g -O3 %s -S -emit-llvm -o - %newLoadClangEnzyme -Xclang -verify; fi

#include <math.h>

extern int enzyme_allocated, enzyme_tape;
void __enzyme_reverse(void*, ...);

void f(double* x) {
x[0] = sin(x[0]);
}

void f_rev(double* x, double* x_b, void* tape) {
__enzyme_reverse(f, x, x_b, enzyme_allocated, 1, enzyme_tape, tape); // expected-error {{Enzyme: need 8 bytes have 1 bytes}}
}

5 changes: 3 additions & 2 deletions enzyme/test/Integration/ReverseMode/test_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ static inline bool approx_fp_equality_double(double f1, double f2, double thresh

#define APPROX_EQ(LHS, RHS, THRES) \
{ \
if (__builtin_fabs(LHS - RHS) > THRES) { \
fprintf(stderr, "Assertion Failed: fabs( [%s = %g] - [%s = %g] ) > %g at %s:%d (%s)\n", #LHS, LHS, #RHS, RHS, THRES, \
if (__builtin_fabs((LHS) - (RHS)) > THRES) { \
fprintf(stderr, "Assertion Failed: fabs( [%s = %g] - [%s = %g] ) > %g at %s:%d (%s)\n", \
#LHS, (double)(LHS), #RHS, (double)(RHS), THRES, \
__FILE__, __LINE__, __PRETTY_FUNCTION__); \
abort(); \
} \
Expand Down

0 comments on commit d12e149

Please sign in to comment.