1 #ifndef _RECURSIVE_FILTER_H_
2 #define _RECURSIVE_FILTER_H_
82 v(var_name), e(var_extent) {}
85 Halide::Var
var(
void)
const {
return v; }
92 operator Halide::Expr(
void) {
93 return Halide::Internal::Variable::make(Halide::Int(32), v.name());
112 r(rec_var), c(causal) {}
115 Halide::Var
var(
void)
const {
return r.
var(); }
125 operator Halide::Expr(
void) {
126 return Halide::Internal::Variable::make(Halide::Int(32), r.
var().name());
150 static int max_threads_per_cuda_warp;
153 static int vectorization_width;
156 Halide::Internal::IntrusivePtr<RecFilterContents> contents;
162 std::vector<std::string> internal_functions(
FuncTag ftag);
173 void inline_func(std::string func_name);
183 Halide::Realization create_realization(
void);
194 std::string
name(
void)
const;
238 void define(std::vector<RecFilterDim> pure_args, std::vector<Halide::Expr> pure_def);
244 Halide::Target
target(
void);
257 Halide::Realization
realize(
void);
302 Halide::Func
func(std::string func_name);
318 void split(std::map<std::string, int> dims);
342 std::vector<RecFilter>
cascade(std::vector<int> a, std::vector<int> b);
359 std::vector<RecFilter>
cascade(std::vector<std::vector<int> > scan);
428 void compute_at(Halide::Func external, Halide::Var granularity);
519 std::vector<std::string> func_list;
521 std::map<int,std::vector<Halide::VarOrRVar> > var_list_by_tag(
RecFilterFunc f,
VarTag vtag);
524 bool contains_vars_with_tag(
VarTag vtag);
583 std::vector<RecFilterDim> args;
592 void operator=(
const Halide::Tuple &pure_def);
595 void operator=(Halide::FuncRefVar pure_def);
598 void operator=(Halide::FuncRefExpr pure_def);
601 void operator=(std::vector<Halide::Expr> pure_def);
604 operator Halide::Expr(
void);
616 std::vector<Halide::Expr> args;
622 operator Halide::Expr(
void);
649 int count (
void)
const;
665 std::ostream &
operator<<(std::ostream &s,
const Halide::Func &f);
666 std::ostream &
operator<<(std::ostream &s,
const Halide::Internal::Function &f);
693 Halide::Image<T> image;
698 if (w && h && c && d) {
699 image = Halide::Image<T>(w,h,c,d);
700 }
else if (w && h && c) {
701 image = Halide::Image<T>(w,h,c);
703 image = Halide::Image<T>(w,h);
705 image = Halide::Image<T>(w);
708 if (image.dimensions() == 1) {
709 for (
size_t x=0; x<w; x++) {
710 image(x) = T(MIN_ELEMENT + (rand() % MAX_ELEMENT));
713 else if (image.dimensions() == 2) {
714 for (
size_t y=0; y<h; y++) {
715 for (
size_t x=0; x<w; x++) {
716 image(x,y) = T(MIN_ELEMENT + (rand() % MAX_ELEMENT));
720 else if (image.dimensions() == 3) {
721 for (
size_t z=0; z<c; z++) {
722 for (
size_t y=0; y<h; y++) {
723 for (
size_t x=0; x<w; x++) {
724 image(x,y,z) = T(MIN_ELEMENT + (rand() % MAX_ELEMENT));
729 else if (image.dimensions() == 4) {
730 for (
size_t t=0; t<d; t++) {
731 for (
size_t z=0; z<c; z++) {
732 for (
size_t y=0; y<h; y++) {
733 for (
size_t x=0; x<w; x++) {
734 image(x,y,z,t) = T(MIN_ELEMENT + (rand() % MAX_ELEMENT));
746 std::ostream &operator<<(std::ostream &s, Halide::Image<T> image) {
748 if (image.dimensions() == 1) {
749 for (
size_t x=image.min(0); x<image.min(0)+image.extent(0); x++) {
750 s << std::setw(precision) << image(x) <<
" ";
754 else if (image.dimensions() == 2) {
755 for (
size_t y=image.min(1); y<image.min(1)+image.extent(1); y++) {
756 for (
size_t x=image.min(0); x<image.min(0)+image.extent(0); x++) {
757 s << std::setw(precision) << float(image(x,y)) <<
" ";
762 else if (image.dimensions() == 3) {
763 for (
size_t z=image.min(2); z<image.min(2)+image.extent(2); z++) {
764 for (
size_t y=image.min(1); y<image.min(1)+image.extent(1); y++) {
765 for (
size_t x=image.min(0); x<image.min(0)+image.extent(0); x++) {
766 s << std::setw(precision) << float(image(x,y,z)) <<
" ";
773 else if (image.dimensions() == 4) {
774 for (
size_t w=image.min(3); w<image.min(3)+image.extent(3); w++) {
775 for (
size_t z=image.min(2); z<image.min(2)+image.extent(2); z++) {
776 for (
size_t y=image.min(1); y<image.min(1)+image.extent(1); y++) {
777 for (
size_t x=image.min(0); x<image.min(0)+image.extent(0); x++) {
778 s << std::setw(precision) << float(image(x,y,z,w)) <<
" ";
793 template <
typename T>
803 : max_diff(0.0), mean_diff(0.0), ref(r), out(o)
805 assert(r.width() == o.width());
806 assert(r.height() == o.height());
807 assert(r.channels()== o.channels());
809 int width = r.width();
810 int height = r.height();
811 int channels= r.channels();
813 diff = Halide::Image<float>(width, height, channels);
815 for (
int z=0; z<channels; z++) {
816 for (
int y=0; y<height; y++) {
817 for (
int x=0; x<width; x++) {
818 diff(x,y,z) = r(x,y,z) - o(x,y,z);
819 float re = 100.0 * std::abs(
diff(x,y,z)) / (r(x,y,z) + 1e-9);
821 max_diff = std::max(re, max_diff);
825 mean_diff /= float(width*height*channels);
830 template <
typename T>
840 std::ostream &operator<<(std::ostream &s, const CheckResult<T> &v) {
841 s <<
"Max relative error = " << v.
max_diff <<
" % \n";
842 s <<
"Mean relative error = " << v.mean_diff <<
" % \n\n";
848 std::ostream &operator<<(std::ostream &s, const CheckResultVerbose<T> &v) {
849 s <<
"Reference" <<
"\n" << v.ref <<
"\n";
850 s <<
"Halide output" <<
"\n" << v.out <<
"\n";
851 s <<
"Difference " <<
"\n" << v.diff <<
"\n";
852 s <<
"Max relative error = " << v.max_diff <<
" % \n";
853 s <<
"Mean relative error = " << v.mean_diff <<
" % \n\n";
858 #endif // _RECURSIVE_FILTER_H_
Halide::Target target(void)
Get the compilation target, inferred from HL_JIT_TARGET.
RecFilterSchedule & split(VarTag v, int factor)
RecFilterSchedule & compute_locally(void)
VarTag inner_channels(void)
VarTag split_var(void) const
int as_integer(void) const
RecFilterSchedule & compute_globally(void)
Constructing an Expr from the final result of a recursive filter.
Halide::Image< T > out
Halide solution.
void gpu_auto_schedule(int tile_width=32)
Automatic GPU schedule for tiled or non-tiled recursive filter; calls RecFilter::gpu_auto_full_schedu...
std::string print_schedule(void) const
void split(RecFilterDim x, int tx)
RecFilterSchedule full_schedule(void)
Extract a handle to schedule non-tiled filter.
Halide::Func func(std::string func_name)
Extract the constituent function by name, useful for debugging:
Halide::Expr operator[](int)
Use this RecFilterRefVar as a call to the one of the output buffers of the internal recfilter...
std::string name(void) const
Name of the filter.
RecFilterDimAndCausality(void)
Empty constructor.
std::string print_synopsis(void) const
std::string print_functions(void) const
RecFilterSchedule intra_schedule(int id=0)
Extract a handle to schedule intra-tile functions of the tiled filter.
int num_pixels(void) const
Size of input/output buffer indexed by this dimension.
RecFilterSchedule & storage_layout(VarTag innermost, VarTag outermost)
RecFilterSchedule & gpu_blocks(VarTag v1)
RecFilter & operator=(const RecFilter &r)
Standard assignment operator.
Recursive filter function with scheduling interface.
VarTag outer_channels(void)
float max_diff
max diff percentage
RecFilterSchedule & reorder_storage(std::vector< VarTag > x)
Halide::Func as_func(void)
Cast the recfilter as a Halide::Func; this returns the function that holds the final result of this f...
bool noschedule
do not use automatic scheduling
void compile_jit(std::string filename="")
Trigger JIT compilation for specified hardware-platform target; dumps the generated codegen in human ...
int iterations
profiling iterations
Halide::Realization realize(void)
Compute the filter.
int min_width
min image width
void cpu_auto_schedule(void)
Automatic CPU schedule for tiled or non-tiled recursive filter; calls RecFilter::cpu_auto_full_schedu...
RecFilterSchedule(RecFilter &r, std::vector< std::string > fl)
void cpu_auto_inter_schedule(void)
Automatic CPU schedule for inter-tile functions of tiled filter.
std::vector< RecFilter > cascade_by_dimension(void)
Compute all scans in the same dimension in an overlapped fashion and cascade different dimensions...
RecFilterSchedule & fuse(VarTag v1, VarTag v2)
void apply_bounds(void)
Apply output domains bounds; this is performed implicitly for tiled filters, but it must be called by...
bool has_count(void) const
void gpu_auto_inter_schedule(void)
Automatic GPU schedule for inter-tile functions of tiled filter.
RecFilterDim(void)
Empty constructor.
RecFilterDim(std::string var_name, int var_extent)
Constructor.
void set_clamped_image_border(void)
CheckResultVerbose(Halide::Image< T > r, Halide::Image< T > o)
Info about scans in a particular dimension.
Compare ref and Halide solutions and print the verbose difference.
Halide::Image< float > diff
pixel wise diff
std::ostream & operator<<(std::ostream &s, const RecFilter &r)
Halide::Image< T > generate_random_image(size_t w, size_t h=0, size_t c=0, size_t d=0)
Generate an image of a given size with random entries.
void operator=(Halide::Expr pure_def)
Use this as the left-hand-side of a definition.
int max_width
max image width
Scheduling tags for RecFilter function dimensions.
static void set_max_threads_per_cuda_warp(int v)
Set the maximum threads to launch per CUDA warp, must be called before scheduling the RecFilter objec...
Data members of the recursive filter.
Arguments(int argc, char **argv)
Parse command line args from number of args and list of args.
bool same_except_count(const VarTag &t) const
void add_filter(RecFilterDim x, std::vector< float > coeff)
RecFilterSchedule & unroll(VarTag v, int factor=0)
RecFilterSchedule & reorder(std::vector< VarTag > x)
Scheduling tags for Functions.
RecFilterRefVar operator()(RecFilterDim x)
RecFilterDimAndCausality operator+(RecFilterDim x)
Operator to create causal scan indication, +x indicates causal scan where x is a RecFilterDim object...
void define(std::vector< RecFilterDim > pure_args, std::vector< Halide::Expr > pure_def)
Add a pure definition to the recursive filter.
int check(const VariableTag &t) const
void cpu_auto_full_schedule(void)
Automatic CPU schedule for non-tiled filter.
std::vector< RecFilter > cascade_by_causality(void)
Computing all causal scans in all dimensions in an overlapped fashion and all anticausal scans in an ...
Halide::Image< T > ref
reference solution
RecFilter(std::string name="")
Empty constructor.
RecFilter overlap_to_higher_order_filter(RecFilter fA, std::string name="O")
Overlap a given filter with the current filter creating a higher order filter.
RecFilterDimAndCausality(RecFilterDim rec_var, bool causal)
Constructor.
CheckResult(Halide::Image< T > r, Halide::Image< T > o)
Filter dimension augmented with causality.
Create an expression that can be used to initialize a pixel.
RecFilterRefVar(RecFilter r, std::vector< RecFilterDim > a)
Handle to schedule internal Halide functions that constitute the recursive filter.
void gpu_auto_intra_schedule(int id)
Automatic GPU schedule for intra-tile functions if tiled filter.
RecFilterSchedule inter_schedule(void)
Extract a handle to schedule intra-tile functions of the tiled filter.
void compute_at(RecFilter external)
Set final result of filter to be computed at an external recursive filter, useful for merging the fil...
void gpu_auto_full_schedule(int tile_width=32)
Automatic GPU schedule for non-tiled filter and return a handle for additional scheduling.
float mean_diff
mean diff percentage
bool nocheck
skip check Halide result against reference solution
Halide::Expr operator[](int)
Use this RecFilterRefVar as a call to the one of the output buffers of the internal recfilter...
std::string print_hl_code(void) const
RecFilterSchedule & vectorize(VarTag v, int factor=0)
void split_all_dimensions(int tx)
float profile(int iterations)
Profile the filter.
RecFilterRefExpr(RecFilter r, std::vector< Halide::Expr > a)
bool causal(void) const
Causality of the dimension.
Halide::Var var(void) const
Convert into Halide::Var for interoperability with Halide code.
RecFilterSchedule & gpu_threads(VarTag v1)
RecFilterSchedule & parallel(VarTag v, int factor=0)
Filter dimension for channels.
static void set_vectorization_width(int v)
Set the vectorization width, must be called before scheduling the RecFilter object.
int num_pixels(void) const
Size of input/output buffer indexed by this dimension.
VarTag & operator=(const VarTag &t)
RecFilterDimAndCausality operator-(RecFilterDim x)
Operator to create anticausal scan indication, -x indicates causal scan where x is a RecFilterDim obj...
std::vector< RecFilter > cascade(std::vector< int > a, std::vector< int > b)
Cascade the filter to produce multiple filters using list of list of scans and producing a list of re...
void cpu_auto_intra_schedule(void)
Automatic CPU schedule for intra-tile functions if tiled filter.
Halide::Var var(void) const
Convert into Halide::Var for interoperability with Halide code.
Compare ref and Halide solutions and print the mean square error.