From 1b4bec3fe4248b394089fcdfd521732a1cba6075 Mon Sep 17 00:00:00 2001 From: Ziyad Edher Date: Tue, 11 Oct 2022 22:02:04 -0700 Subject: [PATCH 1/2] Introduce reporting and some quality of life stuff --- Cargo.lock | 79 +++ Cargo.toml | 1 + benchmarks/snailtracer2/SnailTracer2.sol | 452 ++++++++++++++++++ .../snailtracer2/benchmark.evm-bench.json | 8 + outputs/build/snailtracer2/SnailTracer2.abi | 1 + outputs/build/snailtracer2/SnailTracer2.bin | 1 + src/build.rs | 3 + src/exec.rs | 18 +- src/main.rs | 95 ++-- src/metadata.rs | 6 +- src/results.rs | 125 +++-- src/run.rs | 4 +- 12 files changed, 691 insertions(+), 102 deletions(-) create mode 100644 benchmarks/snailtracer2/SnailTracer2.sol create mode 100644 benchmarks/snailtracer2/benchmark.evm-bench.json create mode 100644 outputs/build/snailtracer2/SnailTracer2.abi create mode 100644 outputs/build/snailtracer2/SnailTracer2.bin diff --git a/Cargo.lock b/Cargo.lock index 381d985b..9faa0e0b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -47,6 +47,12 @@ version = "1.0.65" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "98161a4e3e2184da77bb14f02184cdd111e83bbbcc9979dfee3c44b9a85f5602" +[[package]] +name = "arrayvec" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" + [[package]] name = "atty" version = "0.2.14" @@ -284,6 +290,7 @@ dependencies = [ "log", "serde", "serde_json", + "tabled", "users", ] @@ -803,6 +810,18 @@ version = "6.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ff7415e9ae3fff1225851df9e0d9e4e5479f947619774677a63572e55e80eff" +[[package]] +name = "papergrid" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae9bed2481d5ab6e31056945f4704ca7348a3858148c30725b8946b7a7818498" +dependencies = [ + "bytecount", + "fnv", + "strip-ansi-escapes", + "unicode-width", +] + [[package]] name = "parking_lot" version = "0.12.1" @@ -1032,6 +1051,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "strip-ansi-escapes" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "011cbb39cf7c1f62871aea3cc46e5817b0937b49e9447370c93cacbe93a766d8" +dependencies = [ + "vte", +] + [[package]] name = "strsim" version = "0.8.0" @@ -1079,6 +1107,30 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "tabled" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c8a1ea336f84dc7dfae1025b73904551b3c6a42347f4243387e990f94325895" +dependencies = [ + "papergrid", + "tabled_derive", + "unicode-width", +] + +[[package]] +name = "tabled_derive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "beca1b4eaceb4f2755df858b88d9b9315b7ccfd1ffd0d7a48a52602301f01a57" +dependencies = [ + "heck 0.4.0", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "termcolor" version = "1.1.3" @@ -1257,6 +1309,12 @@ dependencies = [ "log", ] +[[package]] +name = "utf8parse" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "936e4b492acfd135421d8dca4b1aa80a7bfc26e702ef3af710e0752684df5372" + [[package]] name = "uuid" version = "0.8.2" @@ -1275,6 +1333,27 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "vte" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6cbce692ab4ca2f1f3047fcf732430249c0e971bfdd2b234cf2c47ad93af5983" +dependencies = [ + "arrayvec", + "utf8parse", + "vte_generate_state_changes", +] + +[[package]] +name = "vte_generate_state_changes" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d257817081c7dffcdbab24b9e62d2def62e2ff7d00b1c20062551e6cccc145ff" +dependencies = [ + "proc-macro2", + "quote", +] + [[package]] name = "want" version = "0.3.0" diff --git a/Cargo.toml b/Cargo.toml index 50da773e..9d961c5f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,4 +22,5 @@ jsonschema = "0.16.0" log = "0.4.17" serde = "1.0.145" serde_json = "1.0.86" +tabled = "0.9.0" users = "0.11.0" diff --git a/benchmarks/snailtracer2/SnailTracer2.sol b/benchmarks/snailtracer2/SnailTracer2.sol new file mode 100644 index 00000000..fb03fda8 --- /dev/null +++ b/benchmarks/snailtracer2/SnailTracer2.sol @@ -0,0 +1,452 @@ +contract SnailTracer2 { + // Image properties for the path tracer + int width; // Width of the image being generated, fixed for life + int height; // Height of the image being generated, fixed for life + bytes buffer; // Buffer to accumulate image traces (ephemeral) + + // Configure the scene for the tracer to render + Ray camera; // Camera position for the image assembly + Vector deltaX; // Horizontal FoV angle increment per image pixel + Vector deltaY; // Vertical FoV andle increment per image pixel + Sphere[] spheres; // Array of shperes defining the scene to render + Triangle[] triangles; // Array of triangles defining the scene to render + + // TracePixel traces a single pixel of the configured image and returns the RGB + // values to the caller. This method is meant to be used specifically for high + // SPP renderings which would have a huge overhead otherwise. + function TracePixel(int x, int y, int spp) constant returns (byte r, byte g, byte b) { + Vector memory color = trace(x, y, spp); + return (byte(color.x), byte(color.y), byte(color.z)); + } + // TraceScanline traces a single horizontal scanline of the configured image and + // returns the RGB pixel value array. This method should be used for lower SPP + // rendering to void the overhead of by-pixel EVM calls. + function TraceScanline(int y, int spp) constant returns (bytes) { + for (int x = 0; x < width; x++) { + Vector memory color = trace(x, y, spp); + + buffer.push(byte(color.x)); + buffer.push(byte(color.y)); + buffer.push(byte(color.z)); + } + return buffer; + } + // TraceImage traces the entire image of the sconfigured scene and returns the + // RGB pixel value array containing all the data top-down, left-to-right. This + // method should only be callsed for very small images and SPP values as the + // cumulative gas and memory costs can push the EVM too hard. + function TraceImage(int spp) constant returns (bytes) { + for (int y = height - 1; y >= 0; y--) { + for (int x = 0; x < width; x++) { + Vector memory color = trace(x, y, spp); + + buffer.push(byte(color.x)); + buffer.push(byte(color.y)); + buffer.push(byte(color.z)); + } + } + return buffer; + } + // Benchmark sets up an ephemeral image configuration and traces a select few + // hand picked pixels to measure EVM execution performance. + function Benchmark() constant returns (byte r, byte g, byte b) { + // Configure the scene for benchmarking + width = 1024; height = 768; + + // Initialize the rendering parameters + camera = Ray(Vector(50000000, 52000000, 295600000), norm(Vector(0, -42612, -1000000)), 0, false); + deltaX = Vector(width * 513500 / height, 0, 0); + deltaY = div(mul(norm(cross(deltaX, camera.direction)), 513500), 1000000); + + // Initialize the scene bounding boxes + spheres.push(Sphere(100000000000, Vector(100001000000, 40800000, 81600000), Vector(0, 0, 0), Vector(750000, 250000, 250000), Material.Diffuse)); + spheres.push(Sphere(100000000000, Vector(-99901000000, 40800000, 81600000), Vector(0, 0, 0), Vector(250000, 250000, 750000), Material.Diffuse)); + spheres.push(Sphere(100000000000, Vector(50000000, 40800000, 100000000000), Vector(0, 0, 0), Vector(750000, 750000, 750000), Material.Diffuse)); + spheres.push(Sphere(100000000000, Vector(50000000, 40800000, -99830000000), Vector(0, 0, 0), Vector(0, 0, 0), Material.Diffuse)); + spheres.push(Sphere(100000000000, Vector(50000000, 100000000000, 81600000), Vector(0, 0, 0), Vector(750000, 750000, 750000), Material.Diffuse)); + spheres.push(Sphere(100000000000, Vector(50000000, -99918400000, 81600000), Vector(0, 0, 0), Vector(750000, 750000, 750000), Material.Diffuse)); + + // Initiallize the reflective sphere and the light source + spheres.push(Sphere(16500000, Vector(27000000, 16500000, 47000000), Vector(0, 0, 0), Vector(999000, 999000, 999000), Material.Specular)); + spheres.push(Sphere(600000000, Vector(50000000, 681330000, 81600000), Vector(12000000, 12000000, 12000000), Vector(0, 0, 0), Material.Diffuse)); + //spheres.push(Sphere(16500000, Vector(73000000, 16500000, 78000000), Vector(0, 0, 0), Vector(999000, 999000, 999000), Material.Refractive)); + + // Ethereum logo fron triangles + triangles.push(Triangle(Vector(56500000, 25740000, 78000000), Vector(73000000, 25740000, 94500000), Vector(73000000, 49500000, 78000000), Vector(0, 0, 0), Vector(0, 0, 0), Vector(999000, 999000, 999000), Material.Specular)); + triangles.push(Triangle(Vector(56500000, 23760000, 78000000), Vector(73000000, 0, 78000000), Vector(73000000, 23760000, 94500000), Vector(0, 0, 0), Vector(0, 0, 0), Vector(999000, 999000, 999000), Material.Specular)); + triangles.push(Triangle(Vector(89500000, 25740000, 78000000), Vector(73000000, 49500000, 78000000), Vector(73000000, 25740000, 94500000), Vector(0, 0, 0), Vector(0, 0, 0), Vector(999000, 999000, 999000), Material.Specular)); + triangles.push(Triangle(Vector(89500000, 23760000, 78000000), Vector(73000000, 23760000, 94500000), Vector(73000000, 0, 78000000), Vector(0, 0, 0), Vector(0, 0, 0), Vector(999000, 999000, 999000), Material.Specular)); + + // Ethereum logo back triangles + triangles.push(Triangle(Vector(56500000, 25740000, 78000000), Vector(73000000, 49500000, 78000000), Vector(73000000, 25740000, 61500000), Vector(0, 0, 0), Vector(0, 0, 0), Vector(999000, 999000, 999000), Material.Specular)); + triangles.push(Triangle(Vector(56500000, 23760000, 78000000), Vector(73000000, 23760000, 61500000), Vector(73000000, 0, 78000000), Vector(0, 0, 0), Vector(0, 0, 0), Vector(999000, 999000, 999000), Material.Specular)); + triangles.push(Triangle(Vector(89500000, 25740000, 78000000), Vector(73000000, 25740000, 61500000), Vector(73000000, 49500000, 78000000), Vector(0, 0, 0), Vector(0, 0, 0), Vector(999000, 999000, 999000), Material.Specular)); + triangles.push(Triangle(Vector(89500000, 23760000, 78000000), Vector(73000000, 0, 78000000), Vector(73000000, 23760000, 61500000), Vector(0, 0, 0), Vector(0, 0, 0), Vector(999000, 999000, 999000), Material.Specular)); + + // Ethereum logo middle rectangles + triangles.push(Triangle(Vector(56500000, 25740000, 78000000), Vector(73000000, 25740000, 61500000), Vector(89500000, 25740000, 78000000), Vector(0, 0, 0), Vector(0, 0, 0), Vector(999000, 999000, 999000), Material.Specular)); + triangles.push(Triangle(Vector(56500000, 25740000, 78000000), Vector(89500000, 25740000, 78000000), Vector(73000000, 25740000, 94500000), Vector(0, 0, 0), Vector(0, 0, 0), Vector(999000, 999000, 999000), Material.Specular)); + triangles.push(Triangle(Vector(56500000, 23760000, 78000000), Vector(89500000, 23760000, 78000000), Vector(73000000, 23760000, 61500000), Vector(0, 0, 0), Vector(0, 0, 0), Vector(999000, 999000, 999000), Material.Specular)); + triangles.push(Triangle(Vector(56500000, 23760000, 78000000), Vector(73000000, 23760000, 94500000), Vector(89500000, 23760000, 78000000), Vector(0, 0, 0), Vector(0, 0, 0), Vector(999000, 999000, 999000), Material.Specular)); + + // Calculate all the triangle surface normals + for (uint i=0; i 1000000) { return 1000000; } + return x; + } + // Square root calculation based on the Babylonian method + function sqrt(int x) internal returns (int y) { + int z = (x + 1) / 2; + y = x; + while (z < y) { + y = z; + z = (x/z + z) / 2; + } + } + // Sine calculation based on Taylor series expansion. + function sin(int x) internal returns (int y) { + // Ensure x is between [0, 2PI) (Taylor expansion is picky with large numbers) + while (x < 0) { + x += 6283184; + } + while (x >= 6283184) { + x -= 6283184; + } + // Calculate the sin based on the Taylor series + int s = 1; int n = x; int d = 1; int f = 2; + while (n > d) { + y += s * n / d; + n = n * x * x / 1000000 / 1000000; + d *= f * (f + 1); + s *= -1; + f += 2; + } + } + // Cosine calculation based on sine and Pythagorean identity. + function cos(int x) internal returns (int) { + int s = sin(x); return sqrt(1000000000000 - s*s); + } + // Abs returns the absolute value of x. + function abs(int x) internal returns (int) { + if (x > 0) { + return x; + } + return -x; + } + // Vector definition and operations + struct Vector { + int x; int y; int z; + } + + function add(Vector u, Vector v) internal returns (Vector) { + return Vector(u.x+v.x, u.y+v.y, u.z+v.z); + } + function sub(Vector u, Vector v) internal returns (Vector) { + return Vector(u.x-v.x, u.y-v.y, u.z-v.z); + } + function mul(Vector v, int m) internal returns (Vector) { + return Vector(m*v.x, m*v.y, m*v.z); + } + function mul(Vector u, Vector v) internal returns (Vector) { + return Vector(u.x*v.x, u.y*v.y, u.z*v.z); + } + function div(Vector v, int d) internal returns (Vector) { + return Vector(v.x/d, v.y/d, v.z/d); + } + function dot(Vector u, Vector v) internal returns (int) { + return u.x*v.x + u.y*v.y + u.z*v.z; + } + function cross(Vector u, Vector v) internal returns (Vector) { + return Vector(u.y*v.z - u.z*v.y, u.z*v.x - u.x*v.z, u.x*v.y - u.y*v.x); + } + function norm(Vector v) internal returns (Vector) { + int length = sqrt(v.x*v.x + v.y*v.y + v.z*v.z); + return Vector(v.x * 1000000 / length, v.y * 1000000 / length, v.z * 1000000 / length); + } + function clamp(Vector v) internal returns (Vector) { + return Vector(clamp(v.x), clamp(v.y), clamp(v.z)); + } + // Ray is a parametric line with an origin and a direction. + struct Ray { + Vector origin; + Vector direction; + int depth; + bool refract; + } + // Material is the various types of light-altering surfaces + enum Material { Diffuse, Specular, Refractive } + + // Primitive is the various types of geometric primitives + enum Primitive { Sphere, Triangle } + + // Sphere is a physical object to intersect the light rays with + struct Sphere { + int radius; + Vector position; + Vector emission; + Vector color; + Material reflection; + } + + // Triangle is a physical object to intersect the light rays with + struct Triangle { + Vector a; + Vector b; + Vector c; + Vector normal; + Vector emission; + Vector color; + Material reflection; + } + + // intersect calculates the intersection of a ray with a sphere, returning the + // distance till the first intersection point or zero in case of no intersection. + function intersect(Sphere s, Ray r) internal returns (int) { + Vector memory op = sub(s.position, r.origin); + + int b = dot(op, r.direction) / 1000000; + int det = b*b - dot(op, op) + s.radius*s.radius; + + // Bail out if ray misses the sphere + if (det < 0) { + return 0; + } + // Calculate the closer intersection point + det = sqrt(det); + if (b - det > 1000) { + return b - det; + } + if (b + det > 1000) { + return b + det; + } + return 0; + } + function intersect(Triangle t, Ray r) internal returns (int) { + Vector memory e1 = sub(t.b, t.a); + Vector memory e2 = sub(t.c, t.a); + + Vector memory p = cross(r.direction, e2); + + // Bail out if ray is is parallel to the triangle + int det = dot(e1, p) / 1000000; + if (det > -1000 && det < 1000) { + return 0; + } + // Calculate and test the 'u' parameter + Vector memory d = sub(r.origin, t.a); + + int u = dot(d, p) / det; + if(u < 0 || u > 1000000) { + return 0; + } + // Calculate and test the 'v' parameter + Vector memory q = cross(d, e1); + + int v = dot(r.direction, q) / det; + if(v < 0 || u + v > 1000000) { + return 0; + } + // Calculate and return the distance + int dist = dot(e2, q) / det; + if (dist < 1000) { + return 0; + } + return dist; + } + function radiance(Ray ray) internal returns (Vector) { + // Place a limit on the depth to prevent stack overflows + if (ray.depth > 10) { + return Vector(0, 0, 0); + } + // Find the closest object of intersection + int dist; Primitive p; uint id; (dist, p, id) = traceray(ray); + if (dist == 0) { + return Vector(0, 0, 0); + } + Sphere memory sphere; + Triangle memory triangle; + Vector memory color; + Vector memory emission; + + if (p == Primitive.Sphere) { + sphere = spheres[id]; + color = sphere.color; + emission = sphere.emission; + } else { + triangle = triangles[id]; + color = triangle.color; + emission = triangle.emission; + } + // After a number of reflections, randomly stop radiance calculation + int ref = 1; + if (color.z > ref) { + ref = color.z; + } + if (color.y > ref) { + ref = color.y; + } + if (color.z > ref) { + ref = color.z; + } + ray.depth++; + if (ray.depth > 5) { + if (rand() % 1000000 < ref) { + color = div(mul(color, 1000000), ref); + } else { + return emission; + } + } + // Calculate the primitive dependent radiance + Vector memory result; + if (p == Primitive.Sphere) { + result = radiance(ray, sphere, dist); + } else { + result = radiance(ray, triangle, dist); + } + return add(emission, div(mul(color, result), 1000000)); + } + function radiance(Ray ray, Sphere obj, int dist) internal returns (Vector) { + // Calculate the sphere intersection point and normal vectors for recursion + Vector memory intersect = add(ray.origin, div(mul(ray.direction, dist), 1000000)); + Vector memory normal = norm(sub(intersect, obj.position)); + + // For diffuse reflectivity + if (obj.reflection == Material.Diffuse) { + if (dot(normal, ray.direction) >= 0) { + normal = mul(normal, -1); + } + return diffuse(ray, intersect, normal); + } else { // For specular reflectivity + return specular(ray, intersect, normal); + } + } + function radiance(Ray ray, Triangle obj, int dist) internal returns (Vector) { + // Calculate the triangle intersection point for refraction + // We're cheating here, we don't have diffuse triangles :P + Vector memory intersect = add(ray.origin, div(mul(ray.direction, dist), 1000000)); + + // Calculate the refractive indices based on whether we're in or out + int nnt = 666666; // (1 air / 1.5 glass) + if (ray.refract) { + nnt = 1500000; // (1.5 glass / 1 air) + } + int ddn = dot(obj.normal, ray.direction) / 1000000; + if (ddn >= 0) { + ddn = -ddn; + } + // If the angle is too shallow, all light is reflected + int cos2t = 1000000000000 - nnt * nnt * (1000000000000 - ddn * ddn) / 1000000000000; + if (cos2t < 0) { + return specular(ray, intersect, obj.normal); + } + return refractive(ray, intersect, obj.normal, nnt, ddn, cos2t); + } + function diffuse(Ray ray, Vector intersect, Vector normal) internal returns (Vector) { + // Generate a random angle and distance from center + int r1 = int(6283184) * (rand() % 1000000) / 1000000; + int r2 = rand() % 1000000; int r2s = sqrt(r2) * 1000; + + // Create orthonormal coordinate frame + Vector memory u; + if (abs(normal.x) > 100000) { + u = Vector(0, 1000000, 0); + } else { + u = Vector(1000000, 0, 0); + } + u = norm(cross(u, normal)); + Vector memory v = norm(cross(normal, u)); + + // Generate the random reflection ray and continue path tracing + u = norm(add(add(mul(u, cos(r1) * r2s / 1000000), mul(v, sin(r1) * r2s / 1000000)), mul(normal, sqrt(1000000 - r2) * 1000))); + return radiance(Ray(intersect, u, ray.depth, ray.refract)); + } + function specular(Ray ray, Vector intersect, Vector normal) internal returns (Vector) { + Vector memory reflection = norm(sub(ray.direction, mul(normal, 2 * dot(normal, ray.direction) / 1000000))); + return radiance(Ray(intersect, reflection, ray.depth, ray.refract)); + } + function refractive(Ray ray, Vector intersect, Vector normal, int nnt, int ddn, int cos2t) internal returns (Vector) { + // Calculate the refraction rays for fresnel effects + int sign = -1; if (ray.refract) { sign = 1; } + Vector memory refraction = norm(div(sub(mul(ray.direction, nnt), mul(normal, sign * (ddn * nnt / 1000000 + sqrt(cos2t)))), 1000000)); + + // Calculate the fresnel probabilities + int c = 1000000 + ddn; + if (!ray.refract) { + c = 1000000 - dot(refraction, normal) / 1000000; + } + int re = 40000 + (1000000 - 40000) * c * c * c * c * c / 1000000000000000000000000000000; + + // Split a direct hit, otherwise trace only one ray + if (ray.depth <= 2) { + refraction = mul(radiance(Ray(intersect, refraction, ray.depth, !ray.refract)), 1000000 - re); // Reuse refraction variable (lame) + refraction = add(refraction, mul(specular(ray, intersect, normal), re)); + return div(refraction, 1000000); + } + if (rand() % 1000000 < 250000 + re / 2) { + return div(mul(specular(ray, intersect, normal), re), 250000 + re / 2); + } + return div(mul(radiance(Ray(intersect, refraction, ray.depth, !ray.refract)), 1000000 - re), 750000 - re / 2); + } + // traceray calculates the intersection of a ray with all the objects and + // returns the closest one. + function traceray(Ray ray) internal returns (int, Primitive, uint) { + int dist = 0; Primitive p; uint id; + + // Intersect the ray with all the spheres + for (uint i=0; i 0 && (dist == 0 || d < dist)) { + dist = d; p = Primitive.Sphere; id = i; + } + } + // Intersect the ray with all the triangles + for (i=0; i 0 && (dist == 0 || d < dist)) { + dist = d; p = Primitive.Triangle; id = i; + } + } + return (dist, p, id); + } +} \ No newline at end of file diff --git a/benchmarks/snailtracer2/benchmark.evm-bench.json b/benchmarks/snailtracer2/benchmark.evm-bench.json new file mode 100644 index 00000000..fa3daa5b --- /dev/null +++ b/benchmarks/snailtracer2/benchmark.evm-bench.json @@ -0,0 +1,8 @@ +{ + "$schema": "../schema.json", + "name": "snailtracer2", + "num-runs": 10, + "solc-version": "0.4.26", + "contract": "SnailTracer2.sol", + "calldata": "30627b7c" +} diff --git a/outputs/build/snailtracer2/SnailTracer2.abi b/outputs/build/snailtracer2/SnailTracer2.abi new file mode 100644 index 00000000..2ca17db2 --- /dev/null +++ b/outputs/build/snailtracer2/SnailTracer2.abi @@ -0,0 +1 @@ +[{"constant":true,"inputs":[],"name":"Benchmark","outputs":[{"name":"r","type":"bytes1"},{"name":"g","type":"bytes1"},{"name":"b","type":"bytes1"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"y","type":"int256"},{"name":"spp","type":"int256"}],"name":"TraceScanline","outputs":[{"name":"","type":"bytes"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"x","type":"int256"},{"name":"y","type":"int256"},{"name":"spp","type":"int256"}],"name":"TracePixel","outputs":[{"name":"r","type":"bytes1"},{"name":"g","type":"bytes1"},{"name":"b","type":"bytes1"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"spp","type":"int256"}],"name":"TraceImage","outputs":[{"name":"","type":"bytes"}],"payable":false,"stateMutability":"view","type":"function"}] \ No newline at end of file diff --git a/outputs/build/snailtracer2/SnailTracer2.bin b/outputs/build/snailtracer2/SnailTracer2.bin new file mode 100644 index 00000000..44d0d3e9 --- /dev/null +++ b/outputs/build/snailtracer2/SnailTracer2.bin @@ -0,0 +1 @@ +608060405234801561001057600080fd5b506144c8806100206000396000f3006080604052600436106100615763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166330627b7c811461006657806375ac892a146100bf578063784f13661461014f578063c29436011461016d575b600080fd5b34801561007257600080fd5b5061007b610185565b604080517fff000000000000000000000000000000000000000000000000000000000000009485168152928416602084015292168183015290519081900360600190f35b3480156100cb57600080fd5b506100da6004356024356129e9565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101145781810151838201526020016100fc565b50505050905090810190601f1680156101415780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561015b57600080fd5b5061007b600435602435604435612c99565b34801561017957600080fd5b506100da600435612cd7565b6000806000806101936143c6565b61019b614428565b61040060009081556103006001556040805160e0810182526302faf08060808201908152630319750060a083015263119e7f8060c08301528152815160608101835292835261a67319602084810191909152620f423f1992840192909252919082019061020790612fa4565b815260006020808301829052604092830182905283518051600355808201516004558301516005558381015180516006559081015160075582015160085582820151600955606092830151600a805460ff1916911515919091179055815192830190915260015490548291906207d5dc0281151561028157fe5b058152600060208083018290526040928301919091528251600b81905583820151600c81905593830151600d819055835160608181018652928152808401959095528484015282519081018352600654815260075491810191909152600854918101919091526103139161030a91610301916102fc91613034565b612fa4565b6207d5dc6130a2565b620f42406130d5565b8051600e55602080820151600f55604091820151601055815160a08101835264174876e8008152825160608082018552641748862a40825263026e8f00828501526304dd1e008286015282840191825284518082018652600080825281860181905281870181905284870191825286518084018852620b71b081526203d0908188018190528189015292850192835260808501818152601180546001808201808455929094528751600b9091027f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c688101918255965180517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c69890155808a01517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c6a8901558a01517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c6b880155935180517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c6c880155808901517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c6d8801558901517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c6e870155935180517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c6f870155968701517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c7086015595909601517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c7184015593517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c7290920180549195939493909160ff19169083600281111561058d57fe5b0217905550505050601160a06040519081016040528064174876e800815260200160606040519081016040528064174290493f19815260200163026e8f0081526020016304dd1e0081525081526020016060604051908101604052806000815260200160008152602001600081525081526020016060604051908101604052806203d09081526020016203d0908152602001620b71b081525081526020016000600281111561063857fe5b90528154600181810180855560009485526020948590208451600b90940201928355848401518051848401558086015160028086019190915560409182015160038601558186015180516004870155808801516005870155820151600686015560608601518051600787015596870151600886015595015160098401556080840151600a8401805492969193909260ff19169184908111156106d657fe5b0217905550505050601160a06040519081016040528064174876e80081526020016060604051908101604052806302faf080815260200163026e8f00815260200164174876e8008152508152602001606060405190810160405280600081526020016000815260200160008152508152602001606060405190810160405280620b71b08152602001620b71b08152602001620b71b081525081526020016000600281111561078057fe5b90528154600181810180855560009485526020948590208451600b90940201928355848401518051848401558086015160028086019190915560409182015160038601558186015180516004870155808801516005870155820151600686015560608601518051600787015596870151600886015595015160098401556080840151600a8401805492969193909260ff191691849081111561081e57fe5b0217905550505050601160a06040519081016040528064174876e80081526020016060604051908101604052806302faf080815260200163026e8f00815260200164173e54e97f198152508152602001606060405190810160405280600081526020016000815260200160008152508152602001606060405190810160405280600081526020016000815260200160008152508152602001600060028111156108c357fe5b90528154600181810180855560009485526020948590208451600b90940201928355848401518051848401558086015160028086019190915560409182015160038601558186015180516004870155808801516005870155820151600686015560608601518051600787015596870151600886015595015160098401556080840151600a8401805492969193909260ff191691849081111561096157fe5b0217905550505050601160a06040519081016040528064174876e80081526020016060604051908101604052806302faf080815260200164174876e80081526020016304dd1e008152508152602001606060405190810160405280600081526020016000815260200160008152508152602001606060405190810160405280620b71b08152602001620b71b08152602001620b71b0815250815260200160006002811115610a0b57fe5b90528154600181810180855560009485526020948590208451600b90940201928355848401518051848401558086015160028086019190915560409182015160038601558186015180516004870155808801516005870155820151600686015560608601518051600787015596870151600886015595015160098401556080840151600a8401805492969193909260ff1916918490811115610aa957fe5b0217905550505050601160a06040519081016040528064174876e80081526020016060604051908101604052806302faf080815260200164174399c9ff1981526020016304dd1e008152508152602001606060405190810160405280600081526020016000815260200160008152508152602001606060405190810160405280620b71b08152602001620b71b08152602001620b71b0815250815260200160006002811115610b5457fe5b90528154600181810180855560009485526020948590208451600b90940201928355848401518051848401558086015160028086019190915560409182015160038601558186015180516004870155808801516005870155820151600686015560608601518051600787015596870151600886015595015160098401556080840151600a8401805492969193909260ff1916918490811115610bf257fe5b0217905550505050601160a06040519081016040528062fbc520815260200160606040519081016040528063019bfcc0815260200162fbc52081526020016302cd29c08152508152602001606060405190810160405280600081526020016000815260200160008152508152602001606060405190810160405280620f3e588152602001620f3e588152602001620f3e58815250815260200160016002811115610c9857fe5b90528154600181810180855560009485526020948590208451600b90940201928355848401518051848401558086015160028086019190915560409182015160038601558186015180516004870155808801516005870155820151600686015560608601518051600787015596870151600886015595015160098401556080840151600a8401805492969193909260ff1916918490811115610d3657fe5b0217905550505050601160a0604051908101604052806323c3460081526020016060604051908101604052806302faf080815260200163289c455081526020016304dd1e00815250815260200160606040519081016040528062b71b00815260200162b71b00815260200162b71b00815250815260200160606040519081016040528060008152602001600081526020016000815250815260200160006002811115610dde57fe5b90528154600181810180855560009485526020948590208451600b90940201928355848401518051848401558086015160028086019190915560409182015160038601558186015180516004870155808801516005870155820151600686015560608601518051600787015596870151600886015595015160098401556080840151600a8401805492969193909260ff1916918490811115610e7c57fe5b0217905550505050601260e06040519081016040528060606040519081016040528063035e1f208152602001630188c2e081526020016304a62f808152508152602001606060405190810160405280630459e4408152602001630188c2e081526020016305a1f4a08152508152602001606060405190810160405280630459e44081526020016302f34f6081526020016304a62f808152508152602001606060405190810160405280600081526020016000815260200160008152508152602001606060405190810160405280600081526020016000815260200160008152508152602001606060405190810160405280620f3e588152602001620f3e588152602001620f3e58815250815260200160016002811115610f9857fe5b90528154600181810180855560009485526020948590208451805160139095029091019384558086015184840155604090810151600280860191909155868601518051600387015580880151600487015582015160058601558186015180516006870155808801516007870155820151600886015560608601518051600987015580880151600a870155820151600b86015560808601518051600c87015580880151600d870155820151600e86015560a08601518051600f870155968701516010860155950151601184015560c084015160128401805492969193909260ff191691849081111561108557fe5b0217905550505050601260e06040519081016040528060606040519081016040528063035e1f20815260200163016a8c8081526020016304a62f808152508152602001606060405190810160405280630459e4408152602001600081526020016304a62f808152508152602001606060405190810160405280630459e440815260200163016a8c8081526020016305a1f4a08152508152602001606060405190810160405280600081526020016000815260200160008152508152602001606060405190810160405280600081526020016000815260200160008152508152602001606060405190810160405280620f3e588152602001620f3e588152602001620f3e5881525081526020016001600281111561119e57fe5b90528154600181810180855560009485526020948590208451805160139095029091019384558086015184840155604090810151600280860191909155868601518051600387015580880151600487015582015160058601558186015180516006870155808801516007870155820151600886015560608601518051600987015580880151600a870155820151600b86015560808601518051600c87015580880151600d870155820151600e86015560a08601518051600f870155968701516010860155950151601184015560c084015160128401805492969193909260ff191691849081111561128b57fe5b0217905550505050601260e060405190810160405280606060405190810160405280630555a9608152602001630188c2e081526020016304a62f808152508152602001606060405190810160405280630459e44081526020016302f34f6081526020016304a62f808152508152602001606060405190810160405280630459e4408152602001630188c2e081526020016305a1f4a08152508152602001606060405190810160405280600081526020016000815260200160008152508152602001606060405190810160405280600081526020016000815260200160008152508152602001606060405190810160405280620f3e588152602001620f3e588152602001620f3e588152508152602001600160028111156113a757fe5b90528154600181810180855560009485526020948590208451805160139095029091019384558086015184840155604090810151600280860191909155868601518051600387015580880151600487015582015160058601558186015180516006870155808801516007870155820151600886015560608601518051600987015580880151600a870155820151600b86015560808601518051600c87015580880151600d870155820151600e86015560a08601518051600f870155968701516010860155950151601184015560c084015160128401805492969193909260ff191691849081111561149457fe5b0217905550505050601260e060405190810160405280606060405190810160405280630555a960815260200163016a8c8081526020016304a62f808152508152602001606060405190810160405280630459e440815260200163016a8c8081526020016305a1f4a08152508152602001606060405190810160405280630459e4408152602001600081526020016304a62f808152508152602001606060405190810160405280600081526020016000815260200160008152508152602001606060405190810160405280600081526020016000815260200160008152508152602001606060405190810160405280620f3e588152602001620f3e588152602001620f3e588152508152602001600160028111156115ad57fe5b90528154600181810180855560009485526020948590208451805160139095029091019384558086015184840155604090810151600280860191909155868601518051600387015580880151600487015582015160058601558186015180516006870155808801516007870155820151600886015560608601518051600987015580880151600a870155820151600b86015560808601518051600c87015580880151600d870155820151600e86015560a08601518051600f870155968701516010860155950151601184015560c084015160128401805492969193909260ff191691849081111561169a57fe5b0217905550505050601260e06040519081016040528060606040519081016040528063035e1f208152602001630188c2e081526020016304a62f808152508152602001606060405190810160405280630459e44081526020016302f34f6081526020016304a62f808152508152602001606060405190810160405280630459e4408152602001630188c2e081526020016303aa6a608152508152602001606060405190810160405280600081526020016000815260200160008152508152602001606060405190810160405280600081526020016000815260200160008152508152602001606060405190810160405280620f3e588152602001620f3e588152602001620f3e588152508152602001600160028111156117b657fe5b90528154600181810180855560009485526020948590208451805160139095029091019384558086015184840155604090810151600280860191909155868601518051600387015580880151600487015582015160058601558186015180516006870155808801516007870155820151600886015560608601518051600987015580880151600a870155820151600b86015560808601518051600c87015580880151600d870155820151600e86015560a08601518051600f870155968701516010860155950151601184015560c084015160128401805492969193909260ff19169184908111156118a357fe5b0217905550505050601260e06040519081016040528060606040519081016040528063035e1f20815260200163016a8c8081526020016304a62f808152508152602001606060405190810160405280630459e440815260200163016a8c8081526020016303aa6a608152508152602001606060405190810160405280630459e4408152602001600081526020016304a62f808152508152602001606060405190810160405280600081526020016000815260200160008152508152602001606060405190810160405280600081526020016000815260200160008152508152602001606060405190810160405280620f3e588152602001620f3e588152602001620f3e588152508152602001600160028111156119bc57fe5b90528154600181810180855560009485526020948590208451805160139095029091019384558086015184840155604090810151600280860191909155868601518051600387015580880151600487015582015160058601558186015180516006870155808801516007870155820151600886015560608601518051600987015580880151600a870155820151600b86015560808601518051600c87015580880151600d870155820151600e86015560a08601518051600f870155968701516010860155950151601184015560c084015160128401805492969193909260ff1916918490811115611aa957fe5b0217905550505050601260e060405190810160405280606060405190810160405280630555a9608152602001630188c2e081526020016304a62f808152508152602001606060405190810160405280630459e4408152602001630188c2e081526020016303aa6a608152508152602001606060405190810160405280630459e44081526020016302f34f6081526020016304a62f808152508152602001606060405190810160405280600081526020016000815260200160008152508152602001606060405190810160405280600081526020016000815260200160008152508152602001606060405190810160405280620f3e588152602001620f3e588152602001620f3e58815250815260200160016002811115611bc557fe5b90528154600181810180855560009485526020948590208451805160139095029091019384558086015184840155604090810151600280860191909155868601518051600387015580880151600487015582015160058601558186015180516006870155808801516007870155820151600886015560608601518051600987015580880151600a870155820151600b86015560808601518051600c87015580880151600d870155820151600e86015560a08601518051600f870155968701516010860155950151601184015560c084015160128401805492969193909260ff1916918490811115611cb257fe5b0217905550505050601260e060405190810160405280606060405190810160405280630555a960815260200163016a8c8081526020016304a62f808152508152602001606060405190810160405280630459e4408152602001600081526020016304a62f808152508152602001606060405190810160405280630459e440815260200163016a8c8081526020016303aa6a608152508152602001606060405190810160405280600081526020016000815260200160008152508152602001606060405190810160405280600081526020016000815260200160008152508152602001606060405190810160405280620f3e588152602001620f3e588152602001620f3e58815250815260200160016002811115611dcb57fe5b90528154600181810180855560009485526020948590208451805160139095029091019384558086015184840155604090810151600280860191909155868601518051600387015580880151600487015582015160058601558186015180516006870155808801516007870155820151600886015560608601518051600987015580880151600a870155820151600b86015560808601518051600c87015580880151600d870155820151600e86015560a08601518051600f870155968701516010860155950151601184015560c084015160128401805492969193909260ff1916918490811115611eb857fe5b0217905550505050601260e06040519081016040528060606040519081016040528063035e1f208152602001630188c2e081526020016304a62f808152508152602001606060405190810160405280630459e4408152602001630188c2e081526020016303aa6a608152508152602001606060405190810160405280630555a9608152602001630188c2e081526020016304a62f808152508152602001606060405190810160405280600081526020016000815260200160008152508152602001606060405190810160405280600081526020016000815260200160008152508152602001606060405190810160405280620f3e588152602001620f3e588152602001620f3e58815250815260200160016002811115611fd457fe5b90528154600181810180855560009485526020948590208451805160139095029091019384558086015184840155604090810151600280860191909155868601518051600387015580880151600487015582015160058601558186015180516006870155808801516007870155820151600886015560608601518051600987015580880151600a870155820151600b86015560808601518051600c87015580880151600d870155820151600e86015560a08601518051600f870155968701516010860155950151601184015560c084015160128401805492969193909260ff19169184908111156120c157fe5b0217905550505050601260e06040519081016040528060606040519081016040528063035e1f208152602001630188c2e081526020016304a62f808152508152602001606060405190810160405280630555a9608152602001630188c2e081526020016304a62f808152508152602001606060405190810160405280630459e4408152602001630188c2e081526020016305a1f4a08152508152602001606060405190810160405280600081526020016000815260200160008152508152602001606060405190810160405280600081526020016000815260200160008152508152602001606060405190810160405280620f3e588152602001620f3e588152602001620f3e588152508152602001600160028111156121dd57fe5b90528154600181810180855560009485526020948590208451805160139095029091019384558086015184840155604090810151600280860191909155868601518051600387015580880151600487015582015160058601558186015180516006870155808801516007870155820151600886015560608601518051600987015580880151600a870155820151600b86015560808601518051600c87015580880151600d870155820151600e86015560a08601518051600f870155968701516010860155950151601184015560c084015160128401805492969193909260ff19169184908111156122ca57fe5b0217905550505050601260e06040519081016040528060606040519081016040528063035e1f20815260200163016a8c8081526020016304a62f808152508152602001606060405190810160405280630555a960815260200163016a8c8081526020016304a62f808152508152602001606060405190810160405280630459e440815260200163016a8c8081526020016303aa6a608152508152602001606060405190810160405280600081526020016000815260200160008152508152602001606060405190810160405280600081526020016000815260200160008152508152602001606060405190810160405280620f3e588152602001620f3e588152602001620f3e588152508152602001600160028111156123e657fe5b90528154600181810180855560009485526020948590208451805160139095029091019384558086015184840155604090810151600280860191909155868601518051600387015580880151600487015582015160058601558186015180516006870155808801516007870155820151600886015560608601518051600987015580880151600a870155820151600b86015560808601518051600c87015580880151600d870155820151600e86015560a08601518051600f870155968701516010860155950151601184015560c084015160128401805492969193909260ff19169184908111156124d357fe5b0217905550505050601260e06040519081016040528060606040519081016040528063035e1f20815260200163016a8c8081526020016304a62f808152508152602001606060405190810160405280630459e440815260200163016a8c8081526020016305a1f4a08152508152602001606060405190810160405280630555a960815260200163016a8c8081526020016304a62f808152508152602001606060405190810160405280600081526020016000815260200160008152508152602001606060405190810160405280600081526020016000815260200160008152508152602001606060405190810160405280620f3e588152602001620f3e588152602001620f3e588152508152602001600160028111156125ef57fe5b90528154600181810180855560009485526020948590208451805160139095029091019384558086015184840155604090810151600280860191909155868601518051600387015580880151600487015582015160058601558186015180516006870155808801516007870155820151600886015560608601518051600987015580880151600a870155820151600b86015560808601518051600c87015580880151600d870155820151600e86015560a08601518051600f870155968701516010860155950151601184015560c084015160128401805492969193909260ff19169184908111156126dc57fe5b0217905550505050600092505b6012548310156128af57601280548490811061270157fe5b600091825260209182902060408051610140810182526013909302909101805460e08401908152600182015461010085015260028083015461012086015290845282516060818101855260038401548252600484015482880152600584015482860152858701919091528351808201855260068401548152600784015481880152600884015481860152858501528351808201855260098401548152600a84015481880152600b840154818601528186015283518082018552600c8401548152600d84015481880152600e84015481860152608086015283519081018452600f830154815260108301549581019590955260118201549285019290925260a0830193909352601283015491929160c084019160ff9091169081111561282257fe5b600281111561282d57fe5b8152505091506128626102fc61284b8460200151856000015161312c565b61285d8560400151866000015161312c565b613034565b601280548590811061287057fe5b906000526020600020906013020160090160008201518160000155602082015181600101556040820151816002015590505082806001019350506126e9565b6060604051908101604052806001546000546207d5dc028115156128cf57fe5b058152600060208083018290526040928301919091528251600b81905583820151600c81905593830151600d8190558351606081810186529281528084019590955284840152825190810183526006548152600754918101919091526008549181019190915261294a9161030a91610301916102fc91613034565b8051600e556020810151600f556040015160105561297781612972610200610180600861316b565b613326565b905061298d8161297261014561021c600861316b565b90506129a18161297261025880600861316b565b90506129b78161297261020a61020c600861316b565b90506129c48160046130d5565b8051602082015160409092015160f860020a9182029992820298500295509350505050565b606060006129f5614428565b600091505b600054821215612c0757612a0f82868661316b565b90506002816000015160f860020a0290808054603f811680603e8114612a5157600283018455600183161515612a43578192505b600160028404019350612a69565b600084815260209081902060ff198516905560419094555b5050509060018203815460011615612a905790600052602060002090602091828204019190065b90919290919091601f036101000a81548160ff0219169060f860020a84040217905550506002816020015160f860020a0290808054603f811680603e8114612af457600283018455600183161515612ae6578192505b600160028404019350612b0c565b600084815260209081902060ff198516905560419094555b5050509060018203815460011615612b335790600052602060002090602091828204019190065b90919290919091601f036101000a81548160ff0219169060f860020a84040217905550506002816040015160f860020a0290808054603f811680603e8114612b9757600283018455600183161515612b89578192505b600160028404019350612baf565b600084815260209081902060ff198516905560419094555b5050509060018203815460011615612bd65790600052602060002090602091828204019190065b90919290919091601f036101000a81548160ff0219169060f860020a840402179055505081806001019250506129fa565b6002805460408051602060018416156101000260001901909316849004601f81018490048402820184019092528181529291830182828015612c8a5780601f10612c5f57610100808354040283529160200191612c8a565b820191906000526020600020905b815481529060010190602001808311612c6d57829003601f168201915b50505050509250505092915050565b6000806000612ca6614428565b612cb187878761316b565b8051602082015160409092015160f860020a9182029a9282029950029650945050505050565b6060600080612ce4614428565b600180540392505b60008312612f1257600091505b600054821215612f0657612d0e82848761316b565b90506002816000015160f860020a0290808054603f811680603e8114612d5057600283018455600183161515612d42578192505b600160028404019350612d68565b600084815260209081902060ff198516905560419094555b5050509060018203815460011615612d8f5790600052602060002090602091828204019190065b90919290919091601f036101000a81548160ff0219169060f860020a84040217905550506002816020015160f860020a0290808054603f811680603e8114612df357600283018455600183161515612de5578192505b600160028404019350612e0b565b600084815260209081902060ff198516905560419094555b5050509060018203815460011615612e325790600052602060002090602091828204019190065b90919290919091601f036101000a81548160ff0219169060f860020a84040217905550506002816040015160f860020a0290808054603f811680603e8114612e9657600283018455600183161515612e88578192505b600160028404019350612eae565b600084815260209081902060ff198516905560419094555b5050509060018203815460011615612ed55790600052602060002090602091828204019190065b90919290919091601f036101000a81548160ff0219169060f860020a84040217905550508180600101925050612cf9565b60001990920191612cec565b6002805460408051602060018416156101000260001901909316849004601f81018490048402820184019092528181529291830182828015612f955780601f10612f6a57610100808354040283529160200191612f95565b820191906000526020600020905b815481529060010190602001808311612f7857829003601f168201915b50505050509350505050919050565b612fac614428565b604082015160208301518351600092612fd2929180029180029190910190800201613364565b9050606060405190810160405280828560000151620f424002811515612ff457fe5b058152602001828560200151620f42400281151561300e57fe5b058152602001828560400151620f42400281151561302857fe5b05905291505b50919050565b61303c614428565b60606040519081016040528083602001518560400151028460400151866020015102038152602001836040015185600001510284600001518660400151020381526020018360000151856020015102846020015186600001510203815250905092915050565b6130aa614428565b5060408051606081018252835183028152602080850151840290820152928101519091029082015290565b6130dd614428565b6060604051908101604052808385600001518115156130f857fe5b05815260200183856020015181151561310d57fe5b05815260200183856040015181151561312257fe5b0590529392505050565b613134614428565b5060408051606081018252825184510381526020808401518186015103908201528282015184830151039181019190915292915050565b613173614428565b600061317d614428565b61318561444a565b6000546013805463ffffffff1916918802890163ffffffff169190911790556131ac614428565b9350600092505b848312156133055760408051606081018252600b548152600c546020820152600d5491810191909152600054613287916132619161030a9161322a916207a12090816131fd613399565b63ffffffff1681151561320c57fe5b0663ffffffff168e620f4240020181151561322357fe5b05036130a2565b60408051606081018252600e548152600f5460208201526010549181019190915260015461297291906207a12090816131fd613399565b604080516060810182526006548152600754602082015260085491810191909152613326565b6040805160e081019091526003546080820190815260045460a083015260055460c08301529193509081906132c19061297286608c6130a2565b81526020016132cf84612fa4565b815260006020820181905260409091015290506132f8846129726132f2846133c2565b886130d5565b93506001909201916131b3565b61331b61030a613314866137af565b60ff6130a2565b979650505050505050565b61332e614428565b50604080516060810182528251845101815260208084015181860151019082015291810151928101519092019181019190915290565b80600260018201055b8181121561302e57809150600281828581151561338657fe5b050181151561339157fe5b05905061336d565b6013805463ffffffff19811663ffffffff9182166341c64e6d0261303901821617918290551690565b6133ca614428565b60008060006133d7614480565b6133df6143c6565b6133e7614428565b6133ef614428565b60006133f9614428565b600a8b60400151131561342c576060604051908101604052806000815260200160008152602001600081525099506137a1565b6134358b6137fe565b919a5098509650881515613469576060604051908101604052806000815260200160008152602001600081525099506137a1565b600088600181111561347757fe5b141561356757601180548890811061348b57fe5b60009182526020918290206040805160a081018252600b90930290910180548352815160608181018452600183015482526002808401548388015260038401548386015285870192909252835180820185526004840154815260058401548188015260068401548186015285850152835180820185526007840154815260088401549681019690965260098301549386019390935291830193909352600a830154919291608084019160ff9091169081111561354357fe5b600281111561354e57fe5b81525050955085606001519350856040015192506136b6565b601280548890811061357557fe5b600091825260209182902060408051610140810182526013909302909101805460e08401908152600182015461010085015260028083015461012086015290845282516060818101855260038401548252600484015482880152600584015482860152858701919091528351808201855260068401548152600784015481880152600884015481860152858501528351808201855260098401548152600a84015481880152600b840154818601528186015283518082018552600c8401548152600d84015481880152600e84015481860152608086015283519081018452600f830154815260108301549581019590955260118201549285019290925260a0830193909352601283015491929160c084019160ff9091169081111561369657fe5b60028111156136a157fe5b8152505094508460a001519350846080015192505b6001915081846040015113156136ce57836040015191505b81846020015113156136e257836020015191505b81846040015113156136f657836040015191505b60408b01805160010190819052600512156137595781620f4240613718613399565b63ffffffff1681151561372757fe5b0663ffffffff1612156137515761374a61374485620f42406130a2565b836130d5565b9350613759565b8299506137a1565b600088600181111561376757fe5b141561377f576137788b878b613abc565b905061378d565b61378a8b868b613b64565b90505b61379e8361297261030a8785613c34565b99505b505050505050505050919050565b6137b7614428565b6060604051908101604052806137d08460000151613c72565b81526020016137e28460200151613c72565b81526020016137f48460400151613c72565b905290505b919050565b6000808080808080805b601154821015613924576138f060118381548110151561382457fe5b60009182526020918290206040805160a081018252600b90930290910180548352815160608181018452600183015482526002808401548388015260038401548386015285870192909252835180820185526004840154815260058401548188015260068401548186015285850152835180820185526007840154815260088401549681019690965260098301549386019390935291830193909352600a830154919291608084019160ff909116908111156138dc57fe5b60028111156138e757fe5b9052508a613c9d565b9050600081138015613909575084158061390957508481125b1561391957809450600093508192505b600190910190613808565b600091505b601254821015613aae57613a7a60128381548110151561394557fe5b600091825260209182902060408051610140810182526013909302909101805460e08401908152600182015461010085015260028083015461012086015290845282516060818101855260038401548252600484015482880152600584015482860152858701919091528351808201855260068401548152600784015481880152600884015481860152858501528351808201855260098401548152600a84015481880152600b840154818601528186015283518082018552600c8401548152600d84015481880152600e84015481860152608086015283519081018452600f830154815260108301549581019590955260118201549285019290925260a0830193909352601283015491929160c084019160ff90911690811115613a6657fe5b6002811115613a7157fe5b9052508a613d4a565b9050600081138015613a935750841580613a9357508481125b15613aa357809450600193508192505b600190910190613929565b509297919650945092505050565b613ac4614428565b613acc614428565b613ad4614428565b613aed866000015161297261030a8960200151886130a2565b9150613b006102fc83876020015161312c565b9050600085608001516002811115613b1457fe5b1415613b50576000613b2a828860200151613eb9565b12613b3e57613b3b816000196130a2565b90505b613b49868383613ede565b9250613b5b565b613b4986838361407e565b50509392505050565b613b6c614428565b613b74614428565b6000806000613b92886000015161297261030a8b602001518a6130a2565b9350620a2c2a9250876060015115613bab576216e36092505b620f4240613bc188606001518a60200151613eb9565b811515613bca57fe5b05915060008212613bdc578160000391505b64e8d4a510008380028380028203020564e8d4a510000390506000811215613c1457613c0d8885896060015161407e565b9450613c29565b613c26888589606001518686866140fd565b94505b505050509392505050565b613c3c614428565b50604080516060810182528251845102815260208084015181860151029082015291810151928101519092029181019190915290565b600080821215613c84575060006137f9565b620f4240821315613c995750620f42406137f9565b5090565b6000613ca7614428565b600080613cbc8660200151866000015161312c565b9250620f4240613cd0848760200151613eb9565b811515613cd957fe5b875191900592508002613cec8480613eb9565b838402030190506000811215613d055760009350613d41565b613d0e81613364565b90506103e88183031315613d26578082039350613d41565b6103e88183011315613d3c578082019350613d41565b600093505b50505092915050565b6000613d54614428565b613d5c614428565b613d64614428565b6000613d6e614428565b6000613d78614428565b600080613d8d8c602001518d6000015161312c565b9850613da18c604001518d6000015161312c565b9750613db18b6020015189613034565b9650620f4240613dc18a89613eb9565b811515613dca57fe5b0595506103e71986138015613de057506103e886125b15613dee5760009950613eaa565b8a518c51613dfc919061312c565b945085613e098689613eb9565b811515613e1257fe5b0593506000841280613e265750620f424084135b15613e345760009950613eaa565b613e3e858a613034565b925085613e4f8c6020015185613eb9565b811515613e5857fe5b0591506000821280613e6e5750620f4240828501135b15613e7c5760009950613eaa565b85613e878985613eb9565b811515613e9057fe5b0590506103e8811215613ea65760009950613eaa565b8099505b50505050505050505092915050565b6040808201519083015160208084015190850151845186510291020191020192915050565b613ee6614428565b6000806000613ef3614428565b613efb614428565b620f424080613f08613399565b63ffffffff16811515613f1757fe5b0663ffffffff16625fdfb002811515613f2c57fe5b059450620f4240613f3b613399565b63ffffffff16811515613f4a57fe5b0663ffffffff169350613f5c84613364565b6103e8029250620186a0613f7388600001516142f5565b1315613fa15760606040519081016040528060008152602001620f4240815260200160008152509150613fc5565b606060405190810160405280620f4240815260200160008152602001600081525091505b613fd26102fc8389613034565b9150613fe16102fc8884613034565b905061403b6102fc61402061400e85620f424088613ffe8c61430d565b0281151561400857fe5b056130a2565b61297285620f424089613ffe8d614334565b6129728a61403289620f424003613364565b6103e8026130a2565b91506140716080604051908101604052808a81526020018481526020018b6040015181526020018b6060015115158152506133c2565b9998505050505050505050565b614086614428565b61408e614428565b60208501516140be906102fc906140b986620f42406140ad8285613eb9565b60020281151561400857fe5b61312c565b90506140f460806040519081016040528086815260200183815260200187604001518152602001876060015115158152506133c2565b95945050505050565b614105614428565b600061410f614428565b60008060001993508a606001511561412657600193505b6141636102fc61030a61413d8e602001518c6130a2565b6140b98d61414a8c613364565b620f42408f8f0281151561415a57fe5b05018a026130a2565b925086620f42400191508a60600151151561419857620f4240614186848b613eb9565b81151561418f57fe5b05620f42400391505b5060408a0151619c406c0c9f2c9cd04674edea40000000620ea6008480028502850285020205019060021261423a5761420a6141ff6080604051908101604052808d81526020018681526020018e6040015181526020018e606001511515158152506133c2565b82620f4240036130a2565b92506142248361297261421e8e8e8e61407e565b846130a2565b925061423383620f42406130d5565b94506142e7565b600281056203d09001620f424061424f613399565b63ffffffff1681151561425e57fe5b0663ffffffff1612156142905761423361428261427c8d8d8d61407e565b836130a2565b600283056203d090016130d5565b6142e46142d66142cb6080604051908101604052808e81526020018781526020018f6040015181526020018f606001511515158152506133c2565b83620f4240036130a2565b60028305620b71b0036130d5565b94505b505050509695505050505050565b6000808213156143065750806137f9565b5060000390565b60008061431983614334565b905061432d81820264e8d4a5100003613364565b9392505050565b60008060008060005b600086121561435357625fdfb08601955061433d565b5b625fdfb0861261436b57625fdfb086039550614354565b506001925084915082905060025b818313156143bd578183850281151561438e57fe5b059490940193620f42408684028702819005600095909503940592506001810181029190910290600201614379565b50505050919050565b610260604051908101604052806143db614428565b81526020016143e8614428565b81526020016143f5614428565b8152602001614402614428565b815260200161440f614428565b815260200161441c614428565b81526020016000905290565b6060604051908101604052806000815260200160008152602001600081525090565b6101006040519081016040528061445f614428565b815260200161446c614428565b815260006020820181905260409091015290565b61016060405190810160405280600081526020016144026144285600a165627a7a72305820c26f9eccb4ff2ec47e839247fdf33916d737c70ae48059e2e3fd9664abce61860029 \ No newline at end of file diff --git a/src/build.rs b/src/build.rs index 97256144..0c75b4d5 100644 --- a/src/build.rs +++ b/src/build.rs @@ -1,6 +1,7 @@ use std::{ collections::HashSet, error, + fs::create_dir_all, path::{Path, PathBuf}, process::Command, }; @@ -47,6 +48,8 @@ fn build_benchmark( let docker_contract_path = PathBuf::from("/benchmark").join(&contract_name); let docker_build_path = PathBuf::from("/build"); + create_dir_all(&build_context.build_path)?; + let out = Command::new(&build_context.docker_executable) .arg("run") .args([ diff --git a/src/exec.rs b/src/exec.rs index 6ff6d064..704116f8 100644 --- a/src/exec.rs +++ b/src/exec.rs @@ -1,9 +1,13 @@ use std::{ + error, path::{Path, PathBuf}, - process::{exit, Command}, + process::Command, }; -pub fn validate_executable_or_exit(name: &str, executable: &Path) -> PathBuf { +pub fn validate_executable( + name: &str, + executable: &Path, +) -> Result> { log::trace!("validating executable {} ({name})", executable.display()); match Command::new(&executable).arg("--version").output() { Ok(out) => { @@ -14,17 +18,13 @@ pub fn validate_executable_or_exit(name: &str, executable: &Path) -> PathBuf { .expect("could not decode program stdout") .trim_end_matches("\n") ); - executable.to_path_buf() + Ok(executable.to_path_buf()) } Err(e) => match e.kind() { std::io::ErrorKind::NotFound => { - log::error!("{name} not found, tried {}", executable.display()); - exit(-1); - } - _ => { - log::error!("unknown error: {e}"); - exit(-1); + Err(format!("{name} not found, tried {}", executable.display()).into()) } + _ => Err(format!("unknown error: {e}").into()), }, } } diff --git a/src/main.rs b/src/main.rs index ef990e9f..25d941b0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,9 +1,9 @@ -use std::{path::PathBuf, process::exit}; +use std::{error, path::PathBuf, process::exit}; extern crate glob; use clap::Parser; -use results::record_results; +use results::{print_results, record_results}; mod build; mod exec; @@ -13,7 +13,7 @@ mod run; use crate::{ build::build_benchmarks, - exec::validate_executable_or_exit, + exec::validate_executable, metadata::{find_benchmarks, find_runners, BenchmarkDefaults}, run::run_benchmarks_on_runners, }; @@ -77,56 +77,47 @@ fn main() { let args = Args::parse(); - let docker_executable = validate_executable_or_exit("docker", &args.docker_executable); - let _ = validate_executable_or_exit("cargo", &PathBuf::from("cargo")); - - let benchmarks_path = args.benchmark_search_path.canonicalize().unwrap(); - let benchmarks = find_benchmarks( - &args.benchmark_metadata_name, - &args.benchmark_metadata_schema, - &benchmarks_path, - BenchmarkDefaults { - solc_version: args.default_solc_version, - num_runs: args.default_num_runs, - calldata: hex::decode(args.default_calldata_str.to_string()) - .expect("error parsing default calldata"), - }, - ) + (|| -> Result<(), Box> { + let docker_executable = validate_executable("docker", &args.docker_executable)?; + let _ = validate_executable("cargo", &PathBuf::from("cargo"))?; + + let default_calldata = hex::decode(args.default_calldata_str.to_string())?; + + let benchmarks_path = args.benchmark_search_path.canonicalize()?; + let benchmarks = find_benchmarks( + &args.benchmark_metadata_name, + &args.benchmark_metadata_schema, + &benchmarks_path, + BenchmarkDefaults { + solc_version: args.default_solc_version, + num_runs: args.default_num_runs, + calldata: default_calldata, + }, + )?; + + let runners_path = args.runner_search_path.canonicalize()?; + let runners = find_runners( + &args.runner_metadata_name, + &args.runner_metadata_schema, + &runners_path, + (), + )?; + + let outputs_path = args.output_path.canonicalize()?; + + let builds_path = outputs_path.join("build"); + let built_benchmarks = build_benchmarks(&benchmarks, &docker_executable, &builds_path)?; + + let results = run_benchmarks_on_runners(&built_benchmarks, &runners)?; + + let results_path = outputs_path.join("results"); + let result_file_path = record_results(&results_path, args.output_file_name, &results)?; + print_results(&result_file_path)?; + + Ok(()) + })() .unwrap_or_else(|e| { - log::error!("could not find benchmarks: {e}"); + log::error!("{e}"); exit(-1); }); - - let runners_path = args.runner_search_path.canonicalize().unwrap(); - let runners = find_runners( - &args.runner_metadata_name, - &args.runner_metadata_schema, - &runners_path, - (), - ) - .unwrap_or_else(|e| { - log::error!("could not find runners: {e}"); - exit(-1); - }); - - let outputs_path = args.output_path.canonicalize().unwrap(); - - let builds_path = outputs_path.join("build"); - let built_benchmarks = build_benchmarks(&benchmarks, &docker_executable, &builds_path) - .unwrap_or_else(|e| { - log::error!("could not build benchmarks: {e}"); - exit(-1); - }); - - let results = run_benchmarks_on_runners(&built_benchmarks, &runners).unwrap_or_else(|e| { - log::error!("could not run benchmarks: {e}"); - exit(-1); - }); - - let results_path = outputs_path.join("results"); - let _result_file_path = record_results(&results_path, args.output_file_name, &results) - .unwrap_or_else(|e| { - log::error!("could not record results: {e}"); - exit(-1); - }); } diff --git a/src/metadata.rs b/src/metadata.rs index e186b444..0ff360c9 100644 --- a/src/metadata.rs +++ b/src/metadata.rs @@ -5,7 +5,7 @@ use std::{ }; use glob::glob; -use serde::Serialize; +use serde::{Deserialize, Serialize}; pub trait MetadataParser where @@ -55,7 +55,7 @@ where ) -> Result>; } -#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize)] +#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] pub struct Benchmark { pub name: String, pub solc_version: String, @@ -123,7 +123,7 @@ impl MetadataParser for Benchmark { } } -#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize)] +#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] pub struct Runner { pub name: String, pub entry: PathBuf, diff --git a/src/results.rs b/src/results.rs index 9cb0110f..c03b03a6 100644 --- a/src/results.rs +++ b/src/results.rs @@ -1,14 +1,27 @@ use std::{ - collections::HashSet, + collections::{HashMap, HashSet}, error, fs::{self, create_dir_all}, io::Write, path::{Path, PathBuf}, + time::Duration, }; use chrono; +use serde::{Deserialize, Serialize}; +use tabled::{builder::Builder, Style}; -use crate::{metadata::Runner, run::Results}; +use crate::{ + metadata::{Benchmark, Runner}, + run::{Results, RunResult}, +}; + +#[derive(Deserialize, Serialize)] +struct ResultsFormatted { + benchmarks: HashMap, + runners: HashMap, + runs: HashMap>, +} pub fn record_results( results_path: &Path, @@ -26,39 +39,27 @@ pub fn record_results( } } - let mut data = serde_json::Map::new(); - - data.insert( - "benchmarks".to_string(), - serde_json::Value::Object(serde_json::Map::from_iter( - results - .keys() - .map(|x| (x.name.clone(), serde_json::to_value(x).unwrap())), - )), - ); - data.insert( - "runners".to_string(), - serde_json::Value::Object(serde_json::Map::from_iter( - runners - .into_iter() - .map(|x| (x.name.clone(), serde_json::to_value(x).unwrap())), - )), - ); - - let mut runs = serde_json::Map::new(); - for (benchmark, benchmark_results) in results { - let mut runner_runs = serde_json::Map::new(); - for (runner, run_results) in benchmark_results { - runner_runs.insert(runner.name.clone(), serde_json::to_value(run_results)?); - } - runs.insert( - benchmark.name.clone(), - serde_json::Value::Object(runner_runs), - ); - } - data.insert("runs".to_string(), serde_json::Value::Object(runs)); - - let result = serde_json::Value::Object(data); + let results_formatted = ResultsFormatted { + benchmarks: results + .keys() + .map(|b| (b.name.clone(), b.clone())) + .collect(), + runners: runners + .into_iter() + .map(|r| (r.name.clone(), r.clone())) + .collect(), + runs: results + .iter() + .map(|(b, br)| { + ( + b.name.clone(), + br.iter() + .map(|(r, rr)| (r.name.clone(), rr.clone())) + .collect(), + ) + }) + .collect(), + }; let result_file_path = results_path.join(result_file_name.unwrap_or(format!( "{}.evm-bench.results.json", @@ -69,7 +70,11 @@ pub fn record_results( .write(true) .truncate(true) .open(&result_file_path)?; - write!(result_file, "{}", serde_json::to_string_pretty(&result)?)?; + write!( + result_file, + "{}", + serde_json::to_string_pretty(&results_formatted)? + )?; log::info!( "wrote out results to {}", @@ -77,3 +82,51 @@ pub fn record_results( ); Ok(result_file_path) } + +pub fn print_results(results_file_path: &Path) -> Result<(), Box> { + log::info!( + "reading and parsing results from {}...", + results_file_path.to_string_lossy() + ); + let results = + serde_json::from_str::(&fs::read_to_string(results_file_path)?)?; + log::debug!( + "read and parsed results from {}", + results_file_path.to_string_lossy() + ); + + let mut runner_names: Vec<_> = results.runners.keys().cloned().collect(); + runner_names.sort(); + + let mut runs = results.runs.into_iter().collect::>(); + runs.sort_by_key(|(b, _)| b.clone()); + + let mut builder = Builder::default(); + for (benchmark_name, benchmark_runs) in runs.iter() { + let vals = runner_names.iter().map(|runner_name| { + let run = benchmark_runs.get(runner_name)?; + Some( + run.run_times + .iter() + .fold(Duration::ZERO, |a, v| a + v.clone()) + .div_f64(run.run_times.len() as f64), + ) + }); + let mut record = vec![benchmark_name.clone()]; + record.extend( + vals.map(|val| Some(format!("{:?}", val?))) + .map(|s| s.unwrap_or("".into())), + ); + builder.add_record(record); + } + + let mut columns = vec!["".to_owned()]; + columns.extend(runner_names); + builder.set_columns(columns); + + let mut table = builder.build(); + table.with(Style::rounded()); + println!("{}", table); + + Ok(()) +} diff --git a/src/run.rs b/src/run.rs index 750d68c7..7ff367d2 100644 --- a/src/run.rs +++ b/src/run.rs @@ -5,14 +5,14 @@ use std::{ time::Duration, }; -use serde::Serialize; +use serde::{Deserialize, Serialize}; use crate::{ build::BuiltBenchmark, metadata::{Benchmark, Runner}, }; -#[derive(Debug, Serialize)] +#[derive(Clone, Debug, Deserialize, Serialize)] pub struct RunResult { pub run_times: Vec, } From aeb16c51f0697a72fb4911f9ccb9cbdd2519bc92 Mon Sep 17 00:00:00 2001 From: Ziyad Edher Date: Tue, 11 Oct 2022 22:03:10 -0700 Subject: [PATCH 2/2] Remove duplicate benchmark --- benchmarks/snailtracer2/SnailTracer2.sol | 452 ------------------ .../snailtracer2/benchmark.evm-bench.json | 8 - 2 files changed, 460 deletions(-) delete mode 100644 benchmarks/snailtracer2/SnailTracer2.sol delete mode 100644 benchmarks/snailtracer2/benchmark.evm-bench.json diff --git a/benchmarks/snailtracer2/SnailTracer2.sol b/benchmarks/snailtracer2/SnailTracer2.sol deleted file mode 100644 index fb03fda8..00000000 --- a/benchmarks/snailtracer2/SnailTracer2.sol +++ /dev/null @@ -1,452 +0,0 @@ -contract SnailTracer2 { - // Image properties for the path tracer - int width; // Width of the image being generated, fixed for life - int height; // Height of the image being generated, fixed for life - bytes buffer; // Buffer to accumulate image traces (ephemeral) - - // Configure the scene for the tracer to render - Ray camera; // Camera position for the image assembly - Vector deltaX; // Horizontal FoV angle increment per image pixel - Vector deltaY; // Vertical FoV andle increment per image pixel - Sphere[] spheres; // Array of shperes defining the scene to render - Triangle[] triangles; // Array of triangles defining the scene to render - - // TracePixel traces a single pixel of the configured image and returns the RGB - // values to the caller. This method is meant to be used specifically for high - // SPP renderings which would have a huge overhead otherwise. - function TracePixel(int x, int y, int spp) constant returns (byte r, byte g, byte b) { - Vector memory color = trace(x, y, spp); - return (byte(color.x), byte(color.y), byte(color.z)); - } - // TraceScanline traces a single horizontal scanline of the configured image and - // returns the RGB pixel value array. This method should be used for lower SPP - // rendering to void the overhead of by-pixel EVM calls. - function TraceScanline(int y, int spp) constant returns (bytes) { - for (int x = 0; x < width; x++) { - Vector memory color = trace(x, y, spp); - - buffer.push(byte(color.x)); - buffer.push(byte(color.y)); - buffer.push(byte(color.z)); - } - return buffer; - } - // TraceImage traces the entire image of the sconfigured scene and returns the - // RGB pixel value array containing all the data top-down, left-to-right. This - // method should only be callsed for very small images and SPP values as the - // cumulative gas and memory costs can push the EVM too hard. - function TraceImage(int spp) constant returns (bytes) { - for (int y = height - 1; y >= 0; y--) { - for (int x = 0; x < width; x++) { - Vector memory color = trace(x, y, spp); - - buffer.push(byte(color.x)); - buffer.push(byte(color.y)); - buffer.push(byte(color.z)); - } - } - return buffer; - } - // Benchmark sets up an ephemeral image configuration and traces a select few - // hand picked pixels to measure EVM execution performance. - function Benchmark() constant returns (byte r, byte g, byte b) { - // Configure the scene for benchmarking - width = 1024; height = 768; - - // Initialize the rendering parameters - camera = Ray(Vector(50000000, 52000000, 295600000), norm(Vector(0, -42612, -1000000)), 0, false); - deltaX = Vector(width * 513500 / height, 0, 0); - deltaY = div(mul(norm(cross(deltaX, camera.direction)), 513500), 1000000); - - // Initialize the scene bounding boxes - spheres.push(Sphere(100000000000, Vector(100001000000, 40800000, 81600000), Vector(0, 0, 0), Vector(750000, 250000, 250000), Material.Diffuse)); - spheres.push(Sphere(100000000000, Vector(-99901000000, 40800000, 81600000), Vector(0, 0, 0), Vector(250000, 250000, 750000), Material.Diffuse)); - spheres.push(Sphere(100000000000, Vector(50000000, 40800000, 100000000000), Vector(0, 0, 0), Vector(750000, 750000, 750000), Material.Diffuse)); - spheres.push(Sphere(100000000000, Vector(50000000, 40800000, -99830000000), Vector(0, 0, 0), Vector(0, 0, 0), Material.Diffuse)); - spheres.push(Sphere(100000000000, Vector(50000000, 100000000000, 81600000), Vector(0, 0, 0), Vector(750000, 750000, 750000), Material.Diffuse)); - spheres.push(Sphere(100000000000, Vector(50000000, -99918400000, 81600000), Vector(0, 0, 0), Vector(750000, 750000, 750000), Material.Diffuse)); - - // Initiallize the reflective sphere and the light source - spheres.push(Sphere(16500000, Vector(27000000, 16500000, 47000000), Vector(0, 0, 0), Vector(999000, 999000, 999000), Material.Specular)); - spheres.push(Sphere(600000000, Vector(50000000, 681330000, 81600000), Vector(12000000, 12000000, 12000000), Vector(0, 0, 0), Material.Diffuse)); - //spheres.push(Sphere(16500000, Vector(73000000, 16500000, 78000000), Vector(0, 0, 0), Vector(999000, 999000, 999000), Material.Refractive)); - - // Ethereum logo fron triangles - triangles.push(Triangle(Vector(56500000, 25740000, 78000000), Vector(73000000, 25740000, 94500000), Vector(73000000, 49500000, 78000000), Vector(0, 0, 0), Vector(0, 0, 0), Vector(999000, 999000, 999000), Material.Specular)); - triangles.push(Triangle(Vector(56500000, 23760000, 78000000), Vector(73000000, 0, 78000000), Vector(73000000, 23760000, 94500000), Vector(0, 0, 0), Vector(0, 0, 0), Vector(999000, 999000, 999000), Material.Specular)); - triangles.push(Triangle(Vector(89500000, 25740000, 78000000), Vector(73000000, 49500000, 78000000), Vector(73000000, 25740000, 94500000), Vector(0, 0, 0), Vector(0, 0, 0), Vector(999000, 999000, 999000), Material.Specular)); - triangles.push(Triangle(Vector(89500000, 23760000, 78000000), Vector(73000000, 23760000, 94500000), Vector(73000000, 0, 78000000), Vector(0, 0, 0), Vector(0, 0, 0), Vector(999000, 999000, 999000), Material.Specular)); - - // Ethereum logo back triangles - triangles.push(Triangle(Vector(56500000, 25740000, 78000000), Vector(73000000, 49500000, 78000000), Vector(73000000, 25740000, 61500000), Vector(0, 0, 0), Vector(0, 0, 0), Vector(999000, 999000, 999000), Material.Specular)); - triangles.push(Triangle(Vector(56500000, 23760000, 78000000), Vector(73000000, 23760000, 61500000), Vector(73000000, 0, 78000000), Vector(0, 0, 0), Vector(0, 0, 0), Vector(999000, 999000, 999000), Material.Specular)); - triangles.push(Triangle(Vector(89500000, 25740000, 78000000), Vector(73000000, 25740000, 61500000), Vector(73000000, 49500000, 78000000), Vector(0, 0, 0), Vector(0, 0, 0), Vector(999000, 999000, 999000), Material.Specular)); - triangles.push(Triangle(Vector(89500000, 23760000, 78000000), Vector(73000000, 0, 78000000), Vector(73000000, 23760000, 61500000), Vector(0, 0, 0), Vector(0, 0, 0), Vector(999000, 999000, 999000), Material.Specular)); - - // Ethereum logo middle rectangles - triangles.push(Triangle(Vector(56500000, 25740000, 78000000), Vector(73000000, 25740000, 61500000), Vector(89500000, 25740000, 78000000), Vector(0, 0, 0), Vector(0, 0, 0), Vector(999000, 999000, 999000), Material.Specular)); - triangles.push(Triangle(Vector(56500000, 25740000, 78000000), Vector(89500000, 25740000, 78000000), Vector(73000000, 25740000, 94500000), Vector(0, 0, 0), Vector(0, 0, 0), Vector(999000, 999000, 999000), Material.Specular)); - triangles.push(Triangle(Vector(56500000, 23760000, 78000000), Vector(89500000, 23760000, 78000000), Vector(73000000, 23760000, 61500000), Vector(0, 0, 0), Vector(0, 0, 0), Vector(999000, 999000, 999000), Material.Specular)); - triangles.push(Triangle(Vector(56500000, 23760000, 78000000), Vector(73000000, 23760000, 94500000), Vector(89500000, 23760000, 78000000), Vector(0, 0, 0), Vector(0, 0, 0), Vector(999000, 999000, 999000), Material.Specular)); - - // Calculate all the triangle surface normals - for (uint i=0; i 1000000) { return 1000000; } - return x; - } - // Square root calculation based on the Babylonian method - function sqrt(int x) internal returns (int y) { - int z = (x + 1) / 2; - y = x; - while (z < y) { - y = z; - z = (x/z + z) / 2; - } - } - // Sine calculation based on Taylor series expansion. - function sin(int x) internal returns (int y) { - // Ensure x is between [0, 2PI) (Taylor expansion is picky with large numbers) - while (x < 0) { - x += 6283184; - } - while (x >= 6283184) { - x -= 6283184; - } - // Calculate the sin based on the Taylor series - int s = 1; int n = x; int d = 1; int f = 2; - while (n > d) { - y += s * n / d; - n = n * x * x / 1000000 / 1000000; - d *= f * (f + 1); - s *= -1; - f += 2; - } - } - // Cosine calculation based on sine and Pythagorean identity. - function cos(int x) internal returns (int) { - int s = sin(x); return sqrt(1000000000000 - s*s); - } - // Abs returns the absolute value of x. - function abs(int x) internal returns (int) { - if (x > 0) { - return x; - } - return -x; - } - // Vector definition and operations - struct Vector { - int x; int y; int z; - } - - function add(Vector u, Vector v) internal returns (Vector) { - return Vector(u.x+v.x, u.y+v.y, u.z+v.z); - } - function sub(Vector u, Vector v) internal returns (Vector) { - return Vector(u.x-v.x, u.y-v.y, u.z-v.z); - } - function mul(Vector v, int m) internal returns (Vector) { - return Vector(m*v.x, m*v.y, m*v.z); - } - function mul(Vector u, Vector v) internal returns (Vector) { - return Vector(u.x*v.x, u.y*v.y, u.z*v.z); - } - function div(Vector v, int d) internal returns (Vector) { - return Vector(v.x/d, v.y/d, v.z/d); - } - function dot(Vector u, Vector v) internal returns (int) { - return u.x*v.x + u.y*v.y + u.z*v.z; - } - function cross(Vector u, Vector v) internal returns (Vector) { - return Vector(u.y*v.z - u.z*v.y, u.z*v.x - u.x*v.z, u.x*v.y - u.y*v.x); - } - function norm(Vector v) internal returns (Vector) { - int length = sqrt(v.x*v.x + v.y*v.y + v.z*v.z); - return Vector(v.x * 1000000 / length, v.y * 1000000 / length, v.z * 1000000 / length); - } - function clamp(Vector v) internal returns (Vector) { - return Vector(clamp(v.x), clamp(v.y), clamp(v.z)); - } - // Ray is a parametric line with an origin and a direction. - struct Ray { - Vector origin; - Vector direction; - int depth; - bool refract; - } - // Material is the various types of light-altering surfaces - enum Material { Diffuse, Specular, Refractive } - - // Primitive is the various types of geometric primitives - enum Primitive { Sphere, Triangle } - - // Sphere is a physical object to intersect the light rays with - struct Sphere { - int radius; - Vector position; - Vector emission; - Vector color; - Material reflection; - } - - // Triangle is a physical object to intersect the light rays with - struct Triangle { - Vector a; - Vector b; - Vector c; - Vector normal; - Vector emission; - Vector color; - Material reflection; - } - - // intersect calculates the intersection of a ray with a sphere, returning the - // distance till the first intersection point or zero in case of no intersection. - function intersect(Sphere s, Ray r) internal returns (int) { - Vector memory op = sub(s.position, r.origin); - - int b = dot(op, r.direction) / 1000000; - int det = b*b - dot(op, op) + s.radius*s.radius; - - // Bail out if ray misses the sphere - if (det < 0) { - return 0; - } - // Calculate the closer intersection point - det = sqrt(det); - if (b - det > 1000) { - return b - det; - } - if (b + det > 1000) { - return b + det; - } - return 0; - } - function intersect(Triangle t, Ray r) internal returns (int) { - Vector memory e1 = sub(t.b, t.a); - Vector memory e2 = sub(t.c, t.a); - - Vector memory p = cross(r.direction, e2); - - // Bail out if ray is is parallel to the triangle - int det = dot(e1, p) / 1000000; - if (det > -1000 && det < 1000) { - return 0; - } - // Calculate and test the 'u' parameter - Vector memory d = sub(r.origin, t.a); - - int u = dot(d, p) / det; - if(u < 0 || u > 1000000) { - return 0; - } - // Calculate and test the 'v' parameter - Vector memory q = cross(d, e1); - - int v = dot(r.direction, q) / det; - if(v < 0 || u + v > 1000000) { - return 0; - } - // Calculate and return the distance - int dist = dot(e2, q) / det; - if (dist < 1000) { - return 0; - } - return dist; - } - function radiance(Ray ray) internal returns (Vector) { - // Place a limit on the depth to prevent stack overflows - if (ray.depth > 10) { - return Vector(0, 0, 0); - } - // Find the closest object of intersection - int dist; Primitive p; uint id; (dist, p, id) = traceray(ray); - if (dist == 0) { - return Vector(0, 0, 0); - } - Sphere memory sphere; - Triangle memory triangle; - Vector memory color; - Vector memory emission; - - if (p == Primitive.Sphere) { - sphere = spheres[id]; - color = sphere.color; - emission = sphere.emission; - } else { - triangle = triangles[id]; - color = triangle.color; - emission = triangle.emission; - } - // After a number of reflections, randomly stop radiance calculation - int ref = 1; - if (color.z > ref) { - ref = color.z; - } - if (color.y > ref) { - ref = color.y; - } - if (color.z > ref) { - ref = color.z; - } - ray.depth++; - if (ray.depth > 5) { - if (rand() % 1000000 < ref) { - color = div(mul(color, 1000000), ref); - } else { - return emission; - } - } - // Calculate the primitive dependent radiance - Vector memory result; - if (p == Primitive.Sphere) { - result = radiance(ray, sphere, dist); - } else { - result = radiance(ray, triangle, dist); - } - return add(emission, div(mul(color, result), 1000000)); - } - function radiance(Ray ray, Sphere obj, int dist) internal returns (Vector) { - // Calculate the sphere intersection point and normal vectors for recursion - Vector memory intersect = add(ray.origin, div(mul(ray.direction, dist), 1000000)); - Vector memory normal = norm(sub(intersect, obj.position)); - - // For diffuse reflectivity - if (obj.reflection == Material.Diffuse) { - if (dot(normal, ray.direction) >= 0) { - normal = mul(normal, -1); - } - return diffuse(ray, intersect, normal); - } else { // For specular reflectivity - return specular(ray, intersect, normal); - } - } - function radiance(Ray ray, Triangle obj, int dist) internal returns (Vector) { - // Calculate the triangle intersection point for refraction - // We're cheating here, we don't have diffuse triangles :P - Vector memory intersect = add(ray.origin, div(mul(ray.direction, dist), 1000000)); - - // Calculate the refractive indices based on whether we're in or out - int nnt = 666666; // (1 air / 1.5 glass) - if (ray.refract) { - nnt = 1500000; // (1.5 glass / 1 air) - } - int ddn = dot(obj.normal, ray.direction) / 1000000; - if (ddn >= 0) { - ddn = -ddn; - } - // If the angle is too shallow, all light is reflected - int cos2t = 1000000000000 - nnt * nnt * (1000000000000 - ddn * ddn) / 1000000000000; - if (cos2t < 0) { - return specular(ray, intersect, obj.normal); - } - return refractive(ray, intersect, obj.normal, nnt, ddn, cos2t); - } - function diffuse(Ray ray, Vector intersect, Vector normal) internal returns (Vector) { - // Generate a random angle and distance from center - int r1 = int(6283184) * (rand() % 1000000) / 1000000; - int r2 = rand() % 1000000; int r2s = sqrt(r2) * 1000; - - // Create orthonormal coordinate frame - Vector memory u; - if (abs(normal.x) > 100000) { - u = Vector(0, 1000000, 0); - } else { - u = Vector(1000000, 0, 0); - } - u = norm(cross(u, normal)); - Vector memory v = norm(cross(normal, u)); - - // Generate the random reflection ray and continue path tracing - u = norm(add(add(mul(u, cos(r1) * r2s / 1000000), mul(v, sin(r1) * r2s / 1000000)), mul(normal, sqrt(1000000 - r2) * 1000))); - return radiance(Ray(intersect, u, ray.depth, ray.refract)); - } - function specular(Ray ray, Vector intersect, Vector normal) internal returns (Vector) { - Vector memory reflection = norm(sub(ray.direction, mul(normal, 2 * dot(normal, ray.direction) / 1000000))); - return radiance(Ray(intersect, reflection, ray.depth, ray.refract)); - } - function refractive(Ray ray, Vector intersect, Vector normal, int nnt, int ddn, int cos2t) internal returns (Vector) { - // Calculate the refraction rays for fresnel effects - int sign = -1; if (ray.refract) { sign = 1; } - Vector memory refraction = norm(div(sub(mul(ray.direction, nnt), mul(normal, sign * (ddn * nnt / 1000000 + sqrt(cos2t)))), 1000000)); - - // Calculate the fresnel probabilities - int c = 1000000 + ddn; - if (!ray.refract) { - c = 1000000 - dot(refraction, normal) / 1000000; - } - int re = 40000 + (1000000 - 40000) * c * c * c * c * c / 1000000000000000000000000000000; - - // Split a direct hit, otherwise trace only one ray - if (ray.depth <= 2) { - refraction = mul(radiance(Ray(intersect, refraction, ray.depth, !ray.refract)), 1000000 - re); // Reuse refraction variable (lame) - refraction = add(refraction, mul(specular(ray, intersect, normal), re)); - return div(refraction, 1000000); - } - if (rand() % 1000000 < 250000 + re / 2) { - return div(mul(specular(ray, intersect, normal), re), 250000 + re / 2); - } - return div(mul(radiance(Ray(intersect, refraction, ray.depth, !ray.refract)), 1000000 - re), 750000 - re / 2); - } - // traceray calculates the intersection of a ray with all the objects and - // returns the closest one. - function traceray(Ray ray) internal returns (int, Primitive, uint) { - int dist = 0; Primitive p; uint id; - - // Intersect the ray with all the spheres - for (uint i=0; i 0 && (dist == 0 || d < dist)) { - dist = d; p = Primitive.Sphere; id = i; - } - } - // Intersect the ray with all the triangles - for (i=0; i 0 && (dist == 0 || d < dist)) { - dist = d; p = Primitive.Triangle; id = i; - } - } - return (dist, p, id); - } -} \ No newline at end of file diff --git a/benchmarks/snailtracer2/benchmark.evm-bench.json b/benchmarks/snailtracer2/benchmark.evm-bench.json deleted file mode 100644 index fa3daa5b..00000000 --- a/benchmarks/snailtracer2/benchmark.evm-bench.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "$schema": "../schema.json", - "name": "snailtracer2", - "num-runs": 10, - "solc-version": "0.4.26", - "contract": "SnailTracer2.sol", - "calldata": "30627b7c" -}