Skip to content

Commit

Permalink
More fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
MihailMihov committed Oct 10, 2024
1 parent ec76713 commit afcc1d6
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 76 deletions.
4 changes: 2 additions & 2 deletions demos/ComputerGraphics/cpp-smallpt-d/build.sh
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
#!/bin/bash
clang-18 -Ofast -Xclang -add-plugin -Xclang clad -Xclang -load -Xclang ../../../inst/lib/clad.so -I../../../include/ -x c++ -std=c++14 -lstdc++ -lm cpp-smallpt.cpp -fopenmp=libiomp5 -o cpp-smallpt "$@"
clang-18 -Ofast -Xclang -add-plugin -Xclang clad -Xclang -load -Xclang ../../../inst/lib/clad.so -I../../../include/ -x c++ -std=c++14 -lstdc++ -lm diff-tracer-1.cpp -fopenmp=libiomp5 -o diff-tracer-1 "$@"
clang-18 -Ofast -Xclang -add-plugin -Xclang clad -Xclang -load -Xclang ../../../build/lib/clad.so -I../../../include/ -x c++ -std=c++14 -lstdc++ -lm cpp-smallpt.cpp -fopenmp=libomp -o cpp-smallpt "$@"
clang-18 -Ofast -Xclang -add-plugin -Xclang clad -Xclang -load -Xclang ../../../build/lib/clad.so -I../../../include/ -x c++ -std=c++14 -lstdc++ -lm diff-tracer-1.cpp -fopenmp=libomp -o diff-tracer-1 "$@"
47 changes: 10 additions & 37 deletions demos/ComputerGraphics/cpp-smallpt-d/cpp-smallpt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,21 +61,6 @@
// Declarations and Definitions
//-----------------------------------------------------------------------------
namespace smallpt {

/*constexpr*/ Sphere* scene[] = {
new Sphere(1e5, Vector3(1e5 + 1, 40.8, 81.6), Vector3(), Vector3(0.75, 0.25, 0.25), Reflection_t::Diffuse), // Left
new Sphere(1e5, Vector3(-1e5 + 99, 40.8, 81.6), Vector3(), Vector3(0.25, 0.25, 0.75), Reflection_t::Diffuse), // Right
new Sphere(1e5, Vector3(50, 40.8, 1e5), Vector3(), Vector3(0.75), Reflection_t::Diffuse), // Back
new Sphere(1e5, Vector3(50, 40.8, -1e5 + 170), Vector3(), Vector3(), Reflection_t::Diffuse), // Front
new Sphere(1e5, Vector3(50, 1e5, 81.6), Vector3(), Vector3(0.75), Reflection_t::Diffuse), // Bottom
new Sphere(1e5, Vector3(50, -1e5 + 81.6, 81.6), Vector3(), Vector3(0.75), Reflection_t::Diffuse), // Top
new Sphere(16.5, Vector3(27, 16.5, 47), Vector3(), Vector3(0.999), Reflection_t::Refractive), // Glass
// new Sphere(16.5, Vector3(55, 30, 57), Vector3(), Vector3(0.999), Reflection_t::Refractive), // Glassr
// new Sphere(16.5, Vector3(80, 60, 67), Vector3(), Vector3(0.999), Reflection_t::Refractive), // Glass
new Sphere(16.5, Vector3(73, 16.5, 78), Vector3(), Vector3(0.999), Reflection_t::Specular),// Mirror
new Sphere(600, Vector3(50, 681.6 - .27, 81.6), Vector3(12), Vector3(), Reflection_t::Diffuse) // Light
};

[[nodiscard]]
/*constexpr*/ size_t Intersect(Sphere* g_scene[], const size_t n_scene, const Ray& ray) noexcept {
size_t hit = SIZE_MAX;
Expand Down Expand Up @@ -172,9 +157,11 @@ namespace smallpt {
const Vector3 cy = Normalize(cx.Cross(gaze)) * fov;

// Change unfixed geometry center
g_scene[6]->m_p = Vector3(Vx, Vy, Vz);
Vector3 newV = Vector3(Vx, Vy, Vz);
Sphere* geometryCenter = g_scene[6];
geometryCenter->m_p = newV;

#pragma omp parallel for schedule(static)
//#pragma omp parallel for schedule(static)
for (int y = 0; y < static_cast<int>(h); ++y) { // pixel row
for (std::size_t x = 0u; x < w; ++x) { // pixel column
for (std::size_t sy = 0u, i = (h - 1u - y) * w + x; sy < 2u; ++sy) { // 2 subpixel row
Expand All @@ -186,8 +173,12 @@ namespace smallpt {
const double u2 = 2.0 * rng.Uniform();
const double dx = u1 < 1.0 ? sqrt(u1) - 1.0 : 1.0 - sqrt(2.0 - u1);
const double dy = u2 < 1.0 ? sqrt(u2) - 1.0 : 1.0 - sqrt(2.0 - u2);
const Vector3 d = cx * (((sx + 0.5 + dx) * 0.5 + x) / w - 0.5) +
cy * (((sy + 0.5 + dy) * 0.5 + y) / h - 0.5) +
const double cx_mult = (((sx + 0.5 + dx) * 0.5 + x) / w - 0.5);
const double cy_mult = (((sy + 0.5 + dy) * 0.5 + y) / h - 0.5);
const Vector3 cx_1 = cx * cx_mult;
const Vector3 cy_1 = cy * cy_mult;
const Vector3 d = cx_1 +
cy_1 +
gaze;

L += Radiance(g_scene, n_scene, Ray(eye + d * 130.0, Normalize(d), EPSILON_SPHERE), rng) * (1.0 / nb_samples);
Expand All @@ -202,21 +193,3 @@ namespace smallpt {
WritePPM(w, h, Ls, fileName);
}
} // namespace smallpt

#ifndef CPP_EMBED_SMALLPT
using namespace smallpt;
int main(int argc, char* argv[]) {
const std::uint32_t nb_samples = (2 == argc) ? atoi(argv[1]) / 4 : 1;
const std::uint32_t w = 1024;
const std::uint32_t h = 768;

smallpt::Render(
scene, *(&scene + 1) - scene, // Geometry, Lights
27, 16.5, 47, // Params - Center of one sphere // must be Vector3()
w, h, nb_samples, 0, // Camera
new Vector3[w*h], "image.ppm" // Result
);

return 0;
}
#endif
69 changes: 41 additions & 28 deletions demos/ComputerGraphics/cpp-smallpt-d/diff-tracer-1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,9 @@ struct Dataset {
double Vx, Vy, Vz;
int step = 0;

Dataset() = default;
// Populate the data with target image (render example + random noice)
Dataset(const std::uint32_t nb_samples = 1, const std::uint32_t w = 1024u, const std::uint32_t h = 768u) :
Dataset(Sphere* scene[], const std::uint32_t nb_samples = 1, const std::uint32_t w = 1024u, const std::uint32_t h = 768u) :
nb_samples(nb_samples), w(w), h(h) {
// Create Target data/image
char fileName[4096];
Expand All @@ -77,38 +78,34 @@ struct Dataset {

// Function to perform a minimization step
// theta_x are the hypothesis parameters, dt is the generated dataset and
// clad_grad is the gradient function generated by Clad
// cost_grad is the gradient function generated by Clad
template <typename T>
void performStep(double& theta_0, double& theta_1, double& theta_2, Dataset dt, T clad_grad) {
double J_theta[3+2];
void performStep(Sphere* scene[], double theta[], Dataset dt, T cost_grad) {
double theta_dx[3];
double result[3] = {0, 0, 0};
// current?
for (size_t i = 0; i < dt.w*dt.h; i++) {
J_theta[0] = J_theta[1] = J_theta[2] = J_theta[3] = 0;
// clad_grad.execute(theta_0, theta_1, theta_2, dt.target[i], dt.current[i],
// &J_theta[0], &J_theta[1], &J_theta[2], &J_theta[3], &J_theta[4]
// );

result[0] += J_theta[0];
result[1] += J_theta[1];
result[2] += J_theta[2];
cost_grad.execute(scene, theta, dt, &theta_dx);

for(size_t j = 0; j < 3; ++j)
result[j] += theta_dx[j];

}

theta_0 -= dt.learning_rate * result[0] / (2 * dt.w*dt.h);
theta_1 -= dt.learning_rate * result[1] / (2 * dt.w*dt.h);
theta_2 -= dt.learning_rate * result[2] / (2 * dt.w*dt.h);
for(size_t i = 0; i < 3; ++i)
theta[i] -= dt.learning_rate * result[i] / (2 * dt.w * dt.h);
}

double d(Vector3 lhs, Vector3 rhs) {
return std::fabs(lhs.m_x - rhs.m_x) + std::fabs(lhs.m_y - rhs.m_y) + std::fabs(lhs.m_z - rhs.m_z);
}

// The cost function to minimize using gradient descent
// theta_x are the parameters to learn; x, y are the inputs and outputs of f
double cost(double theta[], Dataset dt) {
// theta are the parameters to learn; x, y are the inputs and outputs of f
double cost(Sphere* scene[], double theta[], Dataset dt) {
const size_t fileNameMaxSize = 4096;
char fileName[fileNameMaxSize];
// snprintf(fileName, fileNameMaxSize, "image-%d.ppm", dt.step++);
//snprintf(fileName, fileNameMaxSize, "image-%d.ppm", dt.step++);

double sum = 0.;

Expand All @@ -118,6 +115,7 @@ double cost(double theta[], Dataset dt) {
dt.w, dt.h, dt.nb_samples, 0, // Camera
dt.current, fileName // Result
);

for (int i=0; i<=dt.h; i++) {
for (int j=0; j<=dt.w; j++) {
int p = (dt.h - 1U - i) * dt.w + j;
Expand Down Expand Up @@ -149,16 +147,16 @@ double f1(double x[], int cnt) {
// Function to optimize the cost function of interest
// theta is the hypothesis parameter list and maxSteps is the maximum steps to
// perform
void optimize(double theta[3], Dataset dt, unsigned int maxSteps, double eps) {
void optimize(Sphere* scene[], double theta[3], Dataset dt, unsigned int maxSteps, double eps) {
auto diff = theta;
bool hasConverged = false;
int currentStep = 0;

// Call for Clad to differentiate the cost function specified before
auto clad_grad = clad::gradient(cost);
auto cost_grad = clad::gradient(cost, "theta");

do {
performStep(theta[0], theta[1], theta[2], dt, clad_grad);
performStep(scene, theta, dt, cost_grad);

std::cout << "Steps #" << currentStep << " Theta 0: " << theta[0]
<< " Theta 1: " << theta[1] << " Theta 2: " << theta[2] << std::endl;
Expand All @@ -172,18 +170,33 @@ void optimize(double theta[3], Dataset dt, unsigned int maxSteps, double eps) {
}

int main(int argc, char* argv[]) {
Sphere* scene[] = {
new Sphere(1e5, Vector3(1e5 + 1, 40.8, 81.6), Vector3(), Vector3(0.75, 0.25, 0.25), Reflection_t::Diffuse), // Left
new Sphere(1e5, Vector3(-1e5 + 99, 40.8, 81.6), Vector3(), Vector3(0.25, 0.25, 0.75), Reflection_t::Diffuse), // Right
new Sphere(1e5, Vector3(50, 40.8, 1e5), Vector3(), Vector3(0.75), Reflection_t::Diffuse), // Back
new Sphere(1e5, Vector3(50, 40.8, -1e5 + 170), Vector3(), Vector3(), Reflection_t::Diffuse), // Front
new Sphere(1e5, Vector3(50, 1e5, 81.6), Vector3(), Vector3(0.75), Reflection_t::Diffuse), // Bottom
new Sphere(1e5, Vector3(50, -1e5 + 81.6, 81.6), Vector3(), Vector3(0.75), Reflection_t::Diffuse), // Top
new Sphere(16.5, Vector3(27, 16.5, 47), Vector3(), Vector3(0.999), Reflection_t::Refractive), // Glass
new Sphere(16.5, Vector3(55, 30, 57), Vector3(), Vector3(0.999), Reflection_t::Refractive), // Glassr
new Sphere(16.5, Vector3(80, 60, 67), Vector3(), Vector3(0.999), Reflection_t::Refractive), // Glass
new Sphere(16.5, Vector3(73, 16.5, 78), Vector3(), Vector3(0.999), Reflection_t::Specular),// Mirror
new Sphere(600, Vector3(50, 681.6 - .27, 81.6), Vector3(12), Vector3(), Reflection_t::Diffuse) // Light
};

const std::uint32_t nb_samples = (2 == argc) ? atoi(argv[1]) / 4 : 1;

auto f_dx = clad::differentiate(f, "x");
auto f_dy = clad::differentiate(f, "y");
auto f_g = clad::gradient(f);
auto f_dx = clad::differentiate(f, "x");
auto f_dy = clad::differentiate(f, "y");
auto f_g = clad::gradient(f);

auto f1_dx = clad::differentiate(f1, "x[0]");
auto f1_g = clad::gradient(f1);

auto f1_dx = clad::differentiate(f1, "x[0]");
auto f1_g = clad::gradient(f1);
Dataset dt(scene, nb_samples, 1024u, 768u);

Dataset dt(nb_samples, 1024u, 768u);
double theta[] = {dt.Vx, dt.Vy, dt.Vz};
optimize(theta, dt, 10000, 1e-6);
optimize(scene, theta, dt, 10000, 1e-6);

std::cout << "Result: "
<< "(" << theta[0] << ", " << theta[1] << ", " << theta[2] << ")" << std::endl;
Expand Down
4 changes: 0 additions & 4 deletions demos/ComputerGraphics/cpp-smallpt-d/image.ppm

This file was deleted.

17 changes: 12 additions & 5 deletions lib/Differentiator/ReverseModeVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3715,12 +3715,19 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context,
Expr* MTEStore = GlobalStoreAndRef(Clone(clad_compat::GetSubExpr(MTE)), "_t",
/*force=*/true);

auto* MTEStoreDRE = dyn_cast<DeclRefExpr>(MTEStore);
DeclDiff<VarDecl> MTEDerived =
DifferentiateVarDecl(dyn_cast<VarDecl>(MTEStoreDRE->getDecl()));
addToCurrentBlock(BuildDeclStmt(MTEDerived.getDecl_dx()));
if (auto* MTEStoreDRE = dyn_cast<DeclRefExpr>(MTEStore)) {
DeclDiff<VarDecl> MTEDerived =
DifferentiateVarDecl(dyn_cast<VarDecl>(MTEStoreDRE->getDecl()));
addToCurrentBlock(BuildDeclStmt(MTEDerived.getDecl_dx()));

return StmtDiff{MTEStore, BuildDeclRef(MTEDerived.getDecl_dx())};
return StmtDiff{MTEStore, BuildDeclRef(MTEDerived.getDecl_dx())};
}

if (auto* MTEStoreCE = dyn_cast<CallExpr>(MTEStore)) {
return StmtDiff{MTEStore};
}

return StmtDiff{MTEStore};
}

StmtDiff ReverseModeVisitor::VisitSubstNonTypeTemplateParmExpr(
Expand Down

0 comments on commit afcc1d6

Please sign in to comment.