Segmentation Fault in program using groupmerger and appender
mihai-varga opened this issue · comments
Mihai Varga commented
The Weld program below generates a seg fault when running on multiple threads and the input size is sufficiently large (len(x) ~ 1mil)
|x:vec[i64], mod:i64|
let table = result(
for(x, groupmerger[i64, i64], |b, i, n|
merge(b, {n % mod, i})
)
);
let join = for(rangeiter(0L, mod, 1L), {appender[i64], appender[i64]}, |b, i, n|
if(keyexists(table, n),
for(lookup(table, n), b, |b1, i1, n1|
{merge(b1.$0, n1), merge(b1.$1, i)}
),
b
)
);
let left = for(result(join.$0), appender[i64], |b, i, n|
merge(b, n)
);
let right = for(result(join.$1), appender[i64], |b, i, n|
merge(b, n)
);
{result(left), result(right)}
It's not easy to reproduce on my machine and if I replace left and right with let left = join.$0; let right = join.$1
it seems to work just fine.
you can see the whole C code here: https://pastebin.com/9VGNbs02
Mihai Varga commented
I can actually get the seg fault in 2 locations:
*** Error in `./out': corrupted double-linked list: 0x0000000001818d30 ***
======= Backtrace: =========
/lib64/libc.so.6(+0x7cbac)[0x7f15bf437bac]
/lib64/libc.so.6(+0x8847b)[0x7f15bf44347b]
/lib64/libc.so.6(cfree+0x16e)[0x7f15bf4483be]
/export/scratch1/mihai/weld/my/lib/libweld.so(weld_rt_result_vb+0x985)[0x7f15bfa14255]
the traced execution ended in:
merge(b__2, n__2)
end
merge(b__2, n__2)
end
for [fringeiter(a), ] fn7_tmp__2 b__3 i__3 n__3 F10 F11 true
fn11_tmp = result(fn7_tmp__2)
fn11_tmp__1 = join.$1
fn11_tmp__2 = result(fn11_tmp__1)
#0 0x00007ffff6aa6812 in weld_rt_new_vb_piece () from /export/scratch1/mihai/weld/my/lib/libweld.so
#1 0x00007ffff7ff3e08 in f9_par ()
#2 0x00007ffff6aa95fa in work_loop(int, run_data*) () from /export/scratch1/mihai/weld/my/lib/libweld.so
#3 0x00007ffff6aa8c05 in thread_func(void*) () from /export/scratch1/mihai/weld/my/lib/libweld.so
and the trace ends in:
merge(b__2, n__2)
end
merge(b__2, n__2)
end
merg
The optimized program is:
|x:vec[i64],mod:i64|
(let table:dict[i64,vec[i64]]=(result(
for(
x:vec[i64],
groupmerger[i64,i64],
|b:groupmerger[i64,i64],i:i64,n:i64|
merge(b:groupmerger[i64,i64],{(n:i64%mod:i64),i:i64})
)
));(let join:{appender[i64],appender[i64]}=(for(
rangeiter([],0L,mod:i64,1L),
{appender[i64],appender[i64]},
|b__1:{appender[i64],appender[i64]},i__1:i64,n__1:i64|
if(
keyexists(table:dict[i64,vec[i64]],n__1:i64),
for(
lookup(table:dict[i64,vec[i64]],n__1:i64),
b__1:{appender[i64],appender[i64]},
|b1:{appender[i64],appender[i64]},i1:i64,n1:i64|
{merge(b1.$0,n1:i64),merge(b1.$1,i__1:i64)}
),
b__1:{appender[i64],appender[i64]}
)
));{result(
(let a:vec[i64]=(result(
join.$0
));for(
fringeiter(a:vec[i64]),
for(
simditer(a:vec[i64]),
appender[i64],
|b__2:appender[i64],i__2:i64,n__2:simd[i64]|
merge(b__2:appender[i64],n__2:simd[i64])
),
|b__3:appender[i64],i__3:i64,n__3:i64|
merge(b__3:appender[i64],n__3:i64)
))
),result(
(let a__1:vec[i64]=(result(
join.$1
));for(
fringeiter(a__1:vec[i64]),
for(
simditer(a__1:vec[i64]),
appender[i64],
|b__4:appender[i64],i__4:i64,n__4:simd[i64]|
merge(b__4:appender[i64],n__4:simd[i64])
),
|b__5:appender[i64],i__5:i64,n__5:i64|
merge(b__5:appender[i64],n__5:i64)
))
)}))