Conversation
82fe1a3 to
cf0b311
Compare
|
I have a 2d array implementation on top of this: pub value struct matrix<a>
rows : int
cols : int
data : vector<a>
pub fun ref/assign/@index(mat : ref<h, matrix<a>>, idx : idx, assigned : a) : <pure,read<h>,write<h>> ()
trace(show(idx) ++ " in " ++ show(((!mat).rows, (!mat).cols))) // For debugging
(!mat).assert-valid-idx(idx)
fun unique-copy(matr : matrix<_>)
matr(data = matr.data.copy)
mat.ref/update fn(m : matrix<_>)
val Matrix(r, c, d) = m
val i = idx.int(c)
val d' = unsafe-total
d.set(i, assigned)
Matrix(r, c, d')Where import ds/matrix
fun main()
val matrix = ref(matrix(10, 10) fn(idx) idx)
matrix[(3, 3)] := (1, 2)
matrix.(!)[(3, 3)].showI get: Sometimes I also get an error from mimalloc saying that the free list is corrupted: The bounds above have an interesting binary form: |
|
It doesn't work with local-vars: pub fun local-var/assign/@index(mat : local-var<h, matrix<a>>, idx : idx, assigned : a) : <pure,read<h>,write<h>> ()
trace(show(idx) ++ " in " ++ show((mat.rows, mat.cols)))
mat.assert-valid-idx(idx)
mat.local-var/update(?unique-copy = unique-copy) fn(m)
m.unsafe-total-set(idx, assigned)Which fails with: type error: mat does not match the argument types
context : mat
term : mat
inferred type: local-var<$h,matrix<$a>>
expected type: local-var<_h2,local-var<_h1,_b>>Which I find really strange, as I've never had this problem myself before while working with local-var function parameters. |
|
If you look at the linked branch in the PR description you should see how to use this with vectors. I'm not sure what other code you have going on. Especially this last commit: TimWhiting@b0ef63b For unique-copy you need to dip into C code likely and make sure that you make a truly fresh copy with a reference count of 1, returning it. As I don't know how you defined However, I can point to something that is for sure causing issues - For the local var issue: |
Thanks! I will try your method.
Amazing, I didn't know that this was possible. |
|
I created a MRE of the issue with the corrupted free list on Koka v3.1.3 with this commit merged in this gist |
cf0b311 to
4050dd8
Compare
|
Wow that is really strange. Yes, I wouldn't expect the array to be copied using unique-copy (that is the point of this PR). However, I see the same strange behavior where it randomly will complete correctly, but randomly fail in mimalloc. It gets to around element 102 in the array when this happens. So I don't think it has anything to do with this PR in particular. It gets to element 129 if I compile -O2, so I'm assuming it actually gets further than that but the console doesn't quite keep up with the logging I'm doing. It seems to be an issue with mimalloc. The only thing that I can think of causing the issue is the repetitive allocation and subsequent deallocation of the update function. |
|
I'm happy to see that you can reproduce the behaviour. Do you know if Daan has any ideas?
Can you explain why? Don't we de/allocate the same closures very often anyway? And then why is this the first time we've encountered this? |
|
Oh, very interesting! We observed a similar error in the wild with mimalloc v3 .. I blamed it on an out of bounds error in the program but now I am wondering if it is a bug in mimalloc. I will try to repro. (see the end of issue microsoft/mimalloc#1098. edit: this may be not the case after all as I misunderstood that mimalloc was upgraded inside koka as well.) |
|
Ah, I cannot build it at this point. Can you clarify how to repro? I pull'd the latest
53 kk_unit_t kk_ref_vector_assign_borrow(kk_ref_t _r, kk_integer_t idx, kk_box_t value, kk_context_t* ctx) {
-> 54 struct kk_ref_s* r = kk_datatype_as_assert(struct kk_ref_s*, _r, KK_TAG_REF, ctx);.. so not sure; clearly there are some other bugs as well that should be fixed, but I am also quite interested to repro as is in case there is a mimalloc bug. Let me know how I can repro :-) |
|
This is my git log:
mimalloc |
|
Ah thanks -- i can try later. Did you upgrade to mimalloc v3.1.3 manually?
|
|
No, I did not upgrade mimalloc. How can I best do that? Maybe I should upgrade to Koka v3.2.0 and try again? |
|
No need to upgrade mimalloc. I think i misunderstood that you also upgraded mimalloc :-)
I think now it might be a bug in the primitives.
|
|
Hi @daanx, I have been testing on this branch: https://github.com/TimWhiting/koka/tree/unique-vectorsx (PR now available #762 for viewing the diff online), which updates my |
|
@TimWhiting : maybe try to compile with |
|
Thanks for the encouragement to take a closer look. I was dropping an already dropped reference (I had switched the closure from borrowed to owned, and thought I needed a I don't know why this didn't fail on the first iteration though. It does with debug assertions. Any idea of why that is? Does mimalloc not try to commit any deallocations until later - such that it can handle some amount of double frees until it flushes some buffer or something? |
f5ba674 to
2f8a219
Compare
|
Converted to draft, because I hadn't really considered value types, and there are some improvements I want to make that will make this a lot cleaner. |
0ba3cf1 to
5cdc1cc
Compare
5cdc1cc to
f50cabb
Compare
|
Okay, I was way overcomplicating this. As long as we ensure totality / no access of the local we can do this by simply passing ownership to the update function. I'd like to allow slightly more effects, but it would require some more implicit constraint work. |
2c83d90 to
00399ab
Compare
|
@daanx, I misspoke during our meeting, actually the string buffer that outperforms C++ concatenation is in #762 - based on this PR. Though this PR helps for the variants that use local variables. That PR adds unique updates to vectors, and unique updates to vectors in locals. It extends the test in this PR with another variant of string buffers that is faster than C++. More details on the performance evaluation is in this discussion, starting here: #765 (reply in thread) |
This allows for truly unique updating of locals.
To do so it needs to be able to copy a value such that it has a unique reference, and the update function needs to not have handleable effects.
Ideally we would introduce some syntax for this, or optimize the assignment syntax to use this when the rhs is total.
I have a version of unique vectors #550 that rebases on top of this https://github.com/TimWhiting/koka/tree/unique-vectorsx.