|
| 1 | +/***************************************************************************** |
| 2 | +
|
| 3 | +YASK: Yet Another Stencil Kit |
| 4 | +Copyright (c) 2014-2024, Intel Corporation |
| 5 | +
|
| 6 | +Permission is hereby granted, free of charge, to any person obtaining a copy |
| 7 | +of this software and associated documentation files (the "Software"), to |
| 8 | +deal in the Software without restriction, including without limitation the |
| 9 | +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or |
| 10 | +sell copies of the Software, and to permit persons to whom the Software is |
| 11 | +furnished to do so, subject to the following conditions: |
| 12 | +
|
| 13 | +* The above copyright notice and this permission notice shall be included in |
| 14 | + all copies or substantial portions of the Software. |
| 15 | +
|
| 16 | +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| 17 | +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| 18 | +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| 19 | +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| 20 | +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
| 21 | +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
| 22 | +IN THE SOFTWARE. |
| 23 | +
|
| 24 | +*****************************************************************************/ |
| 25 | + |
| 26 | +// Example stencil equations for 2D image filtering. |
| 27 | + |
| 28 | +// YASK stencil solution(s) in this file will be integrated into the YASK compiler utility. |
| 29 | +#include "yask_compiler_api.hpp" |
| 30 | +using namespace std; |
| 31 | +using namespace yask; |
| 32 | + |
| 33 | +// Create an anonymous namespace to ensure that types are local. |
| 34 | +namespace { |
| 35 | + |
| 36 | + using yn=yc_number_node_ptr; |
| 37 | + using yb=yc_bool_node_ptr; |
| 38 | + |
| 39 | + // A simple smoothing filter where each pixel is updated with the |
| 40 | + // average value of its neighbors. |
| 41 | + class BoxFilter : public yc_solution_with_radius_base { |
| 42 | + |
| 43 | + protected: |
| 44 | + // Indices & dimensions. |
| 45 | + MAKE_STEP_INDEX(n); // step dim. |
| 46 | + MAKE_DOMAIN_INDEX(x); // spatial dim. |
| 47 | + MAKE_DOMAIN_INDEX(y); // spatial dim. |
| 48 | + |
| 49 | + // Vars. |
| 50 | + MAKE_VAR(A, n, x, y); |
| 51 | + |
| 52 | + public: |
| 53 | + BoxFilter(string name="box_filter", int radius=2) : |
| 54 | + yc_solution_with_radius_base(name, radius) { } |
| 55 | + |
| 56 | + // Define equation at n+1 based on values at n. |
| 57 | + virtual void define() { |
| 58 | + auto r = get_radius(); |
| 59 | + |
| 60 | + // RHS of expression being created. |
| 61 | + yn v; |
| 62 | + |
| 63 | + // Add points in square from step n. |
| 64 | + for (int i = -r; i <= r; i++) |
| 65 | + for (int j = -r; j <= r; j++) |
| 66 | + v += A(n, x+i, y+j); |
| 67 | + |
| 68 | + // Average by dividing by number of points |
| 69 | + // in square. |
| 70 | + v /= r * r; |
| 71 | + |
| 72 | + // Define the value at n+1 to be expression v. |
| 73 | + A(n+1, x, y) EQUALS v; |
| 74 | + } |
| 75 | + }; |
| 76 | + REGISTER_SOLUTION(BoxFilter); |
| 77 | + |
| 78 | + // Isotropic Gaussian. |
| 79 | + // TODO: update to parameterize sigma (or perhaps parameterize |
| 80 | + // radius and determine good sigma value from requested radius). |
| 81 | + class GaussianFilter : public yc_solution_base { |
| 82 | + |
| 83 | + protected: |
| 84 | + // Indices & dimensions. |
| 85 | + MAKE_STEP_INDEX(n); // step dim. |
| 86 | + MAKE_DOMAIN_INDEX(x); // spatial dim. |
| 87 | + MAKE_DOMAIN_INDEX(y); // spatial dim. |
| 88 | + |
| 89 | + // Vars. |
| 90 | + MAKE_VAR(A, n, x, y); |
| 91 | + |
| 92 | + public: |
| 93 | + GaussianFilter(string name="gaussian_filter") : |
| 94 | + yc_solution_base(name) { } |
| 95 | + |
| 96 | + // Define equation at n+1 based on values at n. |
| 97 | + virtual void define() { |
| 98 | + |
| 99 | + // G(x, y) = exp(-(x^2 + y^2) / (2 * sigma^2)) / (2 * pi * sigma^2). |
| 100 | + // For the given coefficients, sigma = 1.0. |
| 101 | + // See https://homepages.inf.ed.ac.uk/rbf/HIPR2/gsmooth.htm |
| 102 | + |
| 103 | + // RHS of expression being created. |
| 104 | + yn v; |
| 105 | + |
| 106 | + // Add points in square from step n. |
| 107 | + double coeff[5][5] = { { 1., 4., 7., 4., 1. }, |
| 108 | + { 4., 16., 26., 16., 4. }, |
| 109 | + { 7., 26., 41., 26., 7. }, |
| 110 | + { 4., 16., 26., 16., 4. }, |
| 111 | + { 1., 4., 7., 4., 1. } }; |
| 112 | + double sum = 273.; |
| 113 | + for (int i = -2; i <= 2; i++) |
| 114 | + for (int j = -2; j <= 2; j++) { |
| 115 | + double c = coeff[i+2][j+2] / sum; |
| 116 | + v += A(n, x+i, y+j) * c; |
| 117 | + } |
| 118 | + |
| 119 | + // Define the value at n+1 to be expression v. |
| 120 | + A(n+1, x, y) EQUALS v; |
| 121 | + } |
| 122 | + }; |
| 123 | + REGISTER_SOLUTION(GaussianFilter); |
| 124 | + |
| 125 | +}; // namespace. |
0 commit comments