When using higher-order functions like list_map, one needs to build closure-functions and pass them as arguments. Afterwards, the built closures become garbage. Is there a way to build such closure-functions on the call stack (so that they are automatically freed after the call)?
As is specified in the tutorial, you can use the following syntax:
var bar = lam# (): int => x * y
Related
A snip of Rust code:
pub fn main() {
let a = "hello";
let b = a.len();
let c =b;
println!("len:{}",c)
}
When debugging in CLion, Is it possible to evaluate a function? For example, debug the code step by step, now the code is running to the last line println!... and the current step stops here, by adding the expression a.len() to the watch a variable window, the IDE can't evaluate the a.len(). It says: error: no field named len
This is the same reason you can't make conditional breakpoints for Rust code:
Can't create a conditional breakpoint in VSCode-LLDB with Rust
I hope, I'm not too late to answer this, but with both lldb and gdb, Rust debugging capability is currently rather constrained.
Expressions that are straightforward work; anything complex is likely to produce issues.
My observations from rust-lldb trying this, are that only a small portion of Rust is understood by the expression parser.
There is no support for macros.
Non-used functions are not included in the final binary.
For instance, since that method is not included in the binary, you are unable to execute capacity() on the HashMap in the debugger.
Methods must be named as follows:
struct value.method(&struct value)
There is no technique that I've discovered to call monomorphized functions on generic structs (like HashMap).
For example, "hello" is a const char [5] including the trailing NUL byte. String constants "..." in lldb expressions are produced as C-style string constants.
Therefore, they are not valid functions
I'm trying to translate the resize app from the halide repository from the inline declarations to a generator. Everything seems to work fine, except for this:
Func clamped = BoundaryConditions::repeat_edge(input);`
In the original code, input is declared like so ImageParam input(Float(32), 3). In my generator, I've translated this to: Input<Func> input { "input", Float(32), 3 }. I'm then declaring the clamped in the exact same way as the original code. When compiling, I'm getting this error:
Halide.h:15202:50: error: no member named 'dim' in 'Halide::GeneratorInput<Halide::Func>'
object_bounds.push_back({ Expr(func_like.dim(i).min()), Expr(func_like.dim(i).extent()) });
~~~~~~~~~ ^
Is there a way to create a BoundaryConditions::repeat_edge on an Input<Func>?
There is, associate a Buffer<> with it. (Maybe a Buffer in your case, try it out).
struct MyGen : Generator<MyGen> {
Input<Buffer<>> dim_only_input_buffer{ "dim_only_input_buffer", 3 };
...
};
I ran into something similar, you can see more about this in this github issue
The idea of Input<Func> is that it may be instantiated with another Func when composing generators together. (E.g. the output of one generator may be the input to another and the graph of all connected generators is compiled as a single Halide program.) The problem is Funcs do not have fixed bounds like Buffers do. Hence one cannot ask for (e.g.) the width of a Func.
For a generator which is designed to always be used with concrete memory, one can use Input. To impose a boundary condition on an Input, the bounds need to be passed as explicit parameters to the generator. E.g. as other Inputs.
I am new to using Halide and I am playing around with implementing algorithms first. I am trying to write a function which, depending on the value of the 8 pixels around it, either skips to the next pixel or does some processing and then moves on to the next pixel. When trying to write this I get the following compiler error:
84:5: error: value of type 'Halide::Expr' is not contextually convertible to 'bool'
if(input(x,y) > 0)
I have done all the tutorials and have seen that the select function is an option, but is there a way to either compare the values of a function or store them somewhere?
I also may be thinking about this problem wrong or might not be implementing it with the right "Halide mindset", so any suggestions would be great. Thank you in advance for everything!
The underlying issue here is that, although they are syntactically interleaved, and Halide code is constructed by running C++ code, Halide code is not C++ code and vice versa. Halide code is entirely defined by the Halide::* data structures you build up inside Funcs. if is a C control flow construct; you can use it to conditionally build different Halide programs, but you can't use it inside the logic of the Halide program (inside an Expr/Func). select is to Halide (an Expr which conditionally evaluates to one of two values) as if/else is to C (a statement which conditionally executes one of two sub-statements).
Rest assured, you're hardly alone in having this confusion early on. I want to write a tutorial specifically addressing how to think about staged programming inside Halide.
Until then, the short, "how do I do what I want" answer is as you suspected and as Khouri pointed out: use a select.
Since you've provided no code other than the one line, I'm assuming input is a Func and both x and y are Vars. If so, the result of input(x,y) is an Expr that you cannot evaluate with an if, as the error message indicates.
For the scenario that you describe, you might have something like this:
Var x, y;
Func input; input(x,y) = ...;
Func output; output(x,y) = select
// examine surrounding values
( input(x-1,y-1) > 0
&& input(x+0,y-1) > 0
&& ...
&& input(x+1,y+1) > 0
// true case
, ( input(x-1,y-1)
+ input(x+0,y-1)
+ ...
+ input(x+1,y+1)
) / 8
// false case
, input(x,y)
);
Working in Halide definitely requires a different mindset. You have to think in a more mathematical form. That is, a statement of a(x,y) = b(x,y) will be enforced for all cases of x and y.
Algorithm and scheduling should be separate, although the algorithm may need to be tweaked to allow for better scheduling.
How can I disable tail calls to a specific function in Visual Studio?
The reason I need this is because I have a function that breaks to the debugger that I use when an error occurs and I need to see what function called it.
I cannot change global optimization options because the project runs too slow without optimizations.
(I'm assuming you're writing in C, because you failed to indicate the language or give any code.)
One way to ensure that an optimizing C compiler doesn't convert a Tail-Recursive Call into a jump would be to call through a function pointer variable. Set the function pointer equal to the function you want to recursively call, declare it volatile to keep the optimizer from outsmarting you, and replace
return x * factorial(x-1);
with
static int (*volatile factorial_fp)(int) = factorial;
return x * (*factorial_fp)(x-1);
For the following statement inside function func(), I'm trying to figure out the variable name (which is 'dictionary' in the example) that points to the malloc'ed memory region.
Void func() {
uint64_t * dictionary = (uint64_t *) malloc ( sizeof(uint64_t) * 128 );
}
The instrumented malloc() can record the start address and size of the allocation. However, no knowledge of variable 'dictionary' that will be assigned to, any features from the compilers side can help to solve this problem, without modifying the compiler to instrument such assignment statements?
One way I've been thinking is to use the feature that variable 'dictionary' and function 'malloc' is on one source code line or next to each other, the dwarf provides line information.
One thing you can do with Clang and LLVM is emit the code with debug information and then look for malloc calls. These will be assigned to LLVM values, which can be traced (when not compiled with optimizations, that is) to the original C/C++ source code via the debug information metadata.