Halide internal error issue - halide

Here's the code. I'm using Halide on VS2013, Win64 trunk of Aug 5, 2015. When I execute diag.compile_to_lowered_stmt("diag.html", {}, HTML) (with a 16MB stack), I get the following error message:
"Internal error at E:\Code\Halide\src\IR.cpp:160
Condition failed: a.type() == b.type()
LT of mismatched types"
I have confirmed that the error occurs because of the line:
diag(x, y, c) = select(m135(x, y) > m45(x, y), f45(x, y, c), select(m45(x, y) > m135(x, y), f135(x, y, c), f4x4(x, y, c)));
The only way I've been able to remove the error is to remove both selects (the function is unusable in that case, of course.) I've tried converting the condition to an Expr, and I've also checked the types of m45 and m135 (by assigning them to an Expr t1, and then looking at t1.type().) I note that changing the ">" to an "<" or even ">=" does NOT change the error message from "LT".
Any ideas?
Code is still the same as my previous post:
Image<uint8_t> orig_uint = Tools::load_image("../foo.ppm");
Var x, y, c;
Func orig("orig"), orig_lum("orig_lum"), m45("m45"), m135("m135"), f45("f45"), f135("f135"), f4x4_horiz("f4x4_horiz"), f4x4("f4x4"), diag("diag");
Func orig_clamped = BoundaryConditions::repeat_edge(orig_uint);
const float wta = 1.0f, wtb = 3.0f, wt0 = wta * wta, wt1 = wta * wtb, wt2 = wtb * wtb;
orig(x, y, c) = cast<float_t>(orig_clamped(x, y, c));
orig_lum(x, y) = 0.299f * orig(x, y, 0) + 0.587f * orig(x, y, 1) + 0.114f * orig(x, y, 2);
m45(x, y) = abs(orig_lum(x - 1, y - 1) - orig_lum(x, y)) + abs(orig_lum(x, y) - orig_lum(x + 1, y + 1)) + abs(orig_lum(x + 1, y + 1) - orig_lum(x + 2, y + 2));
m135(x, y) = abs(orig_lum(x + 2, y - 1) - orig_lum(x + 1, y)) + abs(orig_lum(x + 1, y) - orig_lum(x, y + 1)) + abs(orig_lum(x, y + 1) - orig_lum(x - 1, y + 2));
f45(x, y, c) = wta * (orig(x - 1, y - 1, c) + orig(x + 2, y + 2, c)) + wtb * (orig(x, y, c) + orig(x + 1, y + 1, c));
f135(x, y, c) = wta * (orig(x - 1, y + 2, c) + orig(x + 2, y - 1, c)) + wtb * (orig(x, y + 1, c) + orig(x + 1, y, c));
f4x4_horiz(x, y, c) = wta * (orig(x - 1, y, c) + orig(x + 2, y, c)) + wtb * (orig(x, y, c) + orig(x + 1, y, c));
f4x4(x, y, c) = wta * (f4x4_horiz(x, y - 1, c) + f4x4_horiz(x, y + 2, c)) + wtb * (f4x4_horiz(x, y, c) + f4x4_horiz(x, y + 1, c));
diag(x, y, c) = select(m135(x, y) > m45(x, y), f45(x, y, c), select(m45(x, y) > m135(x, y), f135(x, y, c), f4x4(x, y, c)));
// schedule
orig_lum.compute_root();
m45.compute_root().bound(x, 0, orig_uint.width()).bound(y, 0, orig_uint.height());
m135.compute_root().bound(x, 0, orig_uint.width()).bound(y, 0, orig_uint.height());
f45.compute_at(diag, x);
f135.compute_at(diag, x);
f4x4.compute_at(diag, x);
diag.compute_root();
// compile so we can take a look at the code
diag.compile_to_lowered_stmt("diag.html", {}, HTML); // stack oflo here

It's a bug in Halide. Fix pushed by Andrew Adams an hour ago (thanks!)

Related

Why Do i receive "Singleton variable" warning and incorrect result?

i'm writing a simple function in prolog (beginer). Function calculates a specific type of quadratic equation (but this is not important, calculations are correct).
liniowa(A, B, R, W) :-
Delta is 4*A*A*R - 4*B*B + 4*R,
( Delta < 0
-> false
; ( Delta == 0
-> X is -B/(2*A),
Y is A*X + B,
W = punkt(X, Y)
; X1 is (-B + sqrt(Delta)) / (2*A),
Y1 is A*X1 + B,
X2 is (-B - sqrt(Delta)) / (2*A),
Y2 is A*X2 + B,
writeln(X1), writeln(Y1), writeln(X2), writeln(Y2),
W = punkt(X1, Y1) ; W = punkt(X2, Y2)
)
).
When i run this function, i receive warnings:
Singleton variable in branch: X2
Singleton variable in branch: Y2
In the result i receive strange things. In writeln(X2), writeln(Y2) everything is ok, but then there is sth strange in punkt(X2, Y2):
1.4142135623730951
1.4142135623730951
-1.4142135623730951
-1.4142135623730951
W = punkt(1.4142135623730951, 1.4142135623730951)
W = punkt(_1344, _1346)
What's happening? How should I make it?
The syntax of ->/2 is horrendous at the best of times. That no official better syntax has been developed in 30 years is a sad statement, but of what? I won't say anything more about this.
It is best to separate out the program parts into separate predicates.
(A further refinement could be to separate out the case "Delta == 0" into a dedicated delta_positive(A,B,W), thus avoiding having to make a decision on delta_positive/4 and thus cutting and guarding.
liniowa(A, B, R, W) :-
Delta is 4*A*A*R - 4*B*B + 4*R,
( Delta < 0 -> false ; delta_positive(Delta,A,B,W) ).
delta_positive(0,A,B,W) :-
!, % commit to this clause
X is -B/(2*A),
Y is A*X + B,
W = punkt(X,Y).
delta_positive(Delta,A,B,W) :-
Delta \== 0, % superfluous, but makes things clear
!, % commit is also superfluous
X1 is (-B + sqrt(Delta)) / (2*A),
Y1 is A*X1 + B,
X2 is (-B - sqrt(Delta)) / (2*A),
Y2 is A*X2 + B,
format("X1=~q, Y1=~q, Y2=~q, Y2=~q\n",[X1,Y1,X2,Y2]),
(W = punkt(X1, Y1) ; W = punkt(X2, Y2)).
This immediately shows that parantheses are missing around the expression:
(W = punkt(X1, Y1) ; W = punkt(X2, Y2)).
I tried solving it:-
liniowa(A, B, R, W) :-
Delta is 4*A*A*R - 4*B*B + 4*R,
( Delta < 0
-> false
; ( Delta == 0
-> X is -B/(2*A),
Y is A*X + B,
W = punkt(X, Y)
; X1 is (-B + sqrt(Delta)) / (2*A),
Y1 is A*X1 + B,
X2 is (-B - sqrt(Delta)) / (2*A),
Y2 is A*X2 + B,
writeln(X1), writeln(Y1), writeln(X2), writeln(Y2),
W = punkt(X1, Y1) ); X2 is (-B - sqrt(Delta)) / (2*A),
Y2 is A*X2 + B, W = punkt(X2, Y2)
).
?-liniowa(2, 3, 4, W).
0.9083123951776999
4.8166247903554
-2.4083123951777
-1.8166247903553998
W = punkt(0.9083123951776999, 4.8166247903554)
W = punkt(-2.4083123951777, -1.8166247903553998)
I believe that in your code the calculation is being done in the previous step, that's why it is unable to pick it in the last case.

For integers A>0, B>0, N>0, find integers x>0,y>0 such that N-(Ax+By) is smallest non-negative

Example :
A=5, B=2, N=12
Then let x=2, y=1, so 12 - (5(2) + 2(1)) = 0.
Another example:
A=5, B=4, N=12
Here x=1, y=1 is the best possible. Note x=2, y=0 would be better except that x=0 is not allowed.
I'm looking for something fast.
Note it's sufficient to find the value of Ax+By. It's not necessary to give x or y explicitly.
If gcd(A,B)|N, then N is your maximal value. Otherwise, it's the greatest multiple of gcd(A,B) that's smaller than N. Using 4x+2y=13 as an example, that value is gcd(4,2)*6=12 realized by 4(2)+2(2)=12 (among many solutions).
As a formula, your maximal value is Floor(N/gcd(A,B))*gcd(A,B).
Edit: If both x and y must be positive, this may not work. However, won't even be a solution if A+B>N. Here's an algorithm for you...
from math import floor, ceil
def euclid_wallis(m, n):
col1 = [1, 0, m]
col2 = [0, 1, n]
while col2[-1] != 0:
f = -1 * (col1[-1] // col2[-1])
col2, col1 = [x2 * f + x1 for x1, x2 in zip(col1, col2)], col2
return col1, col2
def positive_solutions(A, B, N):
(x, y, gcf), (cx, cy, _) = euclid_wallis(A, B)
f = N // gcf
while f > 0:
fx, fy, n = f*x, f*y, f*gcf
k_min = (-fx + 0.) / cx
k_max = (-fy + 0.) / cy
if cx < 0:
k_min, k_max = k_max, k_min
if floor(k_min) + 1 <= ceil(k_max) - 1:
example_k = int(floor(k_min) + 1)
return fx + cx * example_k, fy + cy * example_k, n
if k_max <= 1:
raise Exception('No solution - A: {}, B: {}, N: {}'.format(A, B, N))
f -= 1
print positive_solutions(5, 4, 12) # (1, 1, 9)
print positive_solutions(2, 3, 6) # (1, 1, 5)
print positive_solutions(23, 37, 238) # (7, 2, 235)
A brute-force O(N^2 / A / B) algorithm, implemented in plain Python3:
import math
def axby(A, B, N):
return [A * x + B * y
for x in range(1, 1 + math.ceil(N / A))
for y in range(1, 1 + math.ceil(N / B))
if (N - A * x - B * y) >= 0]
def bestAxBy(A, B, N):
return min(axby(A, B, N), key=lambda x: N - x)
This matched your examples:
In [2]: bestAxBy(5, 2, 12)
Out[2]: 12 # 5 * (2) + 2 * (1)
In [3]: bestAxBy(5, 4, 12)
Out[3]: 9 # 5 * (1) + 4 * (1)
Have no idea what algorithm that might be, but I think you need something like that (C#)
static class Program
{
static int solve( int a, int b, int N )
{
if( a <= 0 || b <= 0 || N <= 0 )
throw new ArgumentOutOfRangeException();
if( a + b > N )
return -1; // Even x=1, y=1 still more then N
int x = 1;
int y = ( N - ( x * a ) ) / b;
int zInitial = a * x + b * y;
int zMax = zInitial;
while( true )
{
x++;
y = ( N - ( x * a ) ) / b;
if( y <= 0 )
return zMax; // With that x, no positive y possible
int z = a * x + b * y;
if( z > zMax )
zMax = z; // Nice, found better
if( z == zInitial )
return zMax; // x/y/z are periodical, returned where started, meaning no new values are expected
}
}
static void Main( string[] args )
{
int r = solve( 5, 4, 12 );
Console.WriteLine( "{0}", r );
}
}

Algorithm for drawing a polygon grid

Is there an algorithm for drawing grids of n-sided polygons. Here is an example for hexagons:
It's my solution using grid package.
library(grid)
hexagon_layer <- function(x, y, r) {
axis.x <- c(x, x + 3 * r, x + 6 * r, x + 9 * r, x + 12 * r, x + 15 *
r, x + 18 * r, x + 1.5 * r, x + 4.5 * r, x + 7.5 * r, x + 10.5 *
r, x + 13.5 * r, x + 16.5 * r, x + 1.5 * r, x + 4.5 * r, x + 7.5 *
r, x + 10.5 * r, x + 13.5 * r, x + 16.5 * r)
axis.y <- c(rep(y, 7), rep(y + r * sqrt(3)/2, 6), rep(y - r * sqrt(3)/2,
6))
hexagon <- function(x, y, r) {
grid.path(x = c(x + 0.5 * r, x + r, x + 0.5 * r, x - 0.5 * r, x -
r, x - 0.5 * r), y = c(y + r * sqrt(3)/2, y, y - r * sqrt(3)/2,
y - r * sqrt(3)/2, y, y + r * sqrt(3)/2))
}
for (i in 1:length(axis.x)) {
hexagon(axis.x[i], axis.y[i], r = 0.05)
next
}
}
for (i in seq(1, 21, by = 2)) {
hexagon_layer(x = 0.05, y = i * 0.05 * sqrt(3)/2, r = 0.05)
next
}

Cryptarithmetic multiplication returning false

I would think my prolog code would work for this multiplication problem but it's returning false. Am I missing something?
solve(T,W,O,S,I,X,E,L,V) :-
X = [T,W,O,S,I,X,E,L,V],
Digits = [0,1,2,3,4,5,6,7,8,9],
assign_digits(X, Digits),
T > 0,
S > 0,
(100*T + 10*W + O) * (100*S + 10*I + X) =:=
100000*T + 10000*W + 1000*E + 100*L + 10*V + E,
write(X).
You used the same variable X for both a digit and the list of variables.
Just rename the variables that represents the list of all variables:
solve(T,W,O,S,I,X,E,L,V) :-
Vars = [T,W,O,S,I,X,E,L,V],
Digits = [0,1,2,3,4,5,6,7,8,9],
assign_digits(Vars, Digits),
T > 0,
S > 0,
(100*T + 10*W + O) * (100*S + 10*I + X) =:=
100000*T + 10000*W + 1000*E + 100*L + 10*V + E,
write(Vars).

Unwanted evaluation on prolog

I was making a prolog knowledge base to implement geometry rules. When testing if a rectangle had a right angle, I found two answers.
?- rect_tri(triangle(line(point(0,0),point(0,1)),line(point(0,1),point(1,0)),line(point(1,0),point(0,0)))).
true ;
false.
Here is the kwnoledge base:
point(X,Y).
line(X,Y) :- X = point(A,B), Y = point(C,D), not(X = Y).
len(X,R) :- X = line(P,Q), P = point(A,B), Q = point(C,D), not(P = Q),
R is sqrt((A - C) * (A - C) + (B - D) * (B - D)).
triangle(X,Y,Z) :- X = point(A,B), Y = point(C,D), Z = point(E,F),
not(X = Y), not(X = Z), not(Y = Z),
L1 = line(X,Y), L2 = line(X,Z), L3 = line(Y,Z),
len(L1,G), len(L2,H), len(L3,I),
G + H > I, G + I > H, H + I > G.
triangle(X,Y,Z) :- X = line(A,B), Y = line(B,C), line(A,C),
len(X,G), len(Y,H), len(Z,I),
G + H > I, G + I > H, H + I > G.
rect_tri(X) :- X = triangle(A,B,C), len(A,G), len(B,H), len(C,I),
(G is sqrt(H * H + I * I);
H is sqrt(G * G + I * I);
I is sqrt(H * H + G * G)).
When tracing, I found that the answer true comes when prolog hits the line H is sqrt(G * G + I * I), and false when it evaluates the last line.
I don't want the last evaluation to occur, because I want it to exit when a true has been found.
Daniel comment probably shows the most sensible way to solve your problem. Some other option...
in modern compilers there is the if/then/else construct:
rect_tri(X) :- X = triangle(A,B,C), len(A,G), len(B,H), len(C,I),
( G is sqrt(H * H + I * I)
-> true
; H is sqrt(G * G + I * I)
-> true
; I is sqrt(H * H + G * G)
).
You could as well use cuts (old fashioned way, somewhat more readable here):
rect_tri(X) :- X = triangle(A,B,C), len(A,G), len(B,H), len(C,I),
( G is sqrt(H * H + I * I), !
; H is sqrt(G * G + I * I), !
; I is sqrt(H * H + G * G)
).

Resources