Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature request: mutable unsafe vectors #2

Open
chethega opened this issue Apr 20, 2018 · 8 comments
Open

Feature request: mutable unsafe vectors #2

chethega opened this issue Apr 20, 2018 · 8 comments

Comments

@chethega
Copy link

chethega commented Apr 20, 2018

An unsafe vector could also provide push!, pop!, etc which grow/shrink the view, respectively, overwriting entries of the parent.

This would be used via uview = push!(uview, val). These can be significantly faster than base vector push!/pop!, since we can avoid both the ccall and the stupid second read-increment-store due to the fact that vectors store both length and number of rows (why, oh why).

One would need to also store a pointer_from_objref to the underlying vector, in order to not exceed its length, and resize it if necessary. See JuliaLang/julia#24909.

@oschulz
Copy link
Collaborator

oschulz commented Apr 20, 2018

While it would, in theory, be nice to be able to grow an UnsafeVector, overwriting the parent array would be just a bit too unsafe ... :-)

pop! and popfirst! (which would be safe) are not possible either: They do, by definition, modify the vector, and UnsafeArray has to be immutable to be stack-allocated.

@oschulz oschulz closed this as completed Apr 20, 2018
@chethega
Copy link
Author

chethega commented Apr 20, 2018

While it would, in theory, be nice to be able to grow an UnsafeVector, overwriting the parent array would be just a bit too unsafe ... :-)

Why? I have a vector [1 .... k ... k+ell ... N], with an unsafe view defined by [k... k+ell]. Writing into the unsafe view makes sense (overwriting the parent entry k+ell+1). Moving k or k+ell to the left or right makes sense (sliding window). Increasing ell, and overwriting the slot there makes sense. We would need the pointer_from_objref to the parent, because we do not want to corrupt memory (write beyond the bounds of the parent), and hence need to check the parent's length on every shift of the unsafe view. Shifting the view to the right and writing into the slot is functionally equivalent to push!.

pop! and popfirst! (which would be safe) are not possible either: They do, by definition, modify the vector, and UnsafeArray has to be immutable to be stack-allocated.

Obviously the API would need to differ. Just like immutability of Int64 does not prevent n+=1, you could do uview,val = uvpop(uview). You're right that the API is different enough from base that this should be named differently.

@oschulz
Copy link
Collaborator

oschulz commented Apr 20, 2018

Well, for the use case of sliding windows, you would just create many unsafe views, but they wouldn't be resized. And if you need to resize an unsafe view, you can just create a new one. But the UnsafeArrays themselves are very lightweight (on purpose), and have no information on what the size of the original array was - so they can't grow (even by returning a new UnsafeArray) in a safe way.

In fact, since an UnsafeArray can be created from a memory pointer and a size, there may not even be an original array, at least not one allocated by Julia. But the user does have that information, and can create additional new unsafe views as required directly.

@oschulz
Copy link
Collaborator

oschulz commented Apr 20, 2018

Actually, the calloc-trick presented by foobar_lv2 in a recent thread on the Julia Discourse may profit from a kind of mutable unsafe vector that knows it's maximum bounds. It would be quite different from UnsafeArray though, and wouldn't support stack-allocated views.

@oschulz oschulz changed the title Feature request: unsafeVector Feature request: mutable unsafe vector Apr 20, 2018
@oschulz oschulz reopened this Apr 20, 2018
@oschulz oschulz changed the title Feature request: mutable unsafe vector Feature request: mutable unsafe vectors Apr 20, 2018
@chethega
Copy link
Author

Ok, you're right; mutable is the way to go for this. foobar from discourse is actually me, btw. I tend to use new pseudonyms for every account I make.

@oschulz
Copy link
Collaborator

oschulz commented Apr 22, 2018

Ok, I think a mutable version of UnsafeArray that would support use cases like we discussed on discourse (oversized malloc/calloc, growing via page faults and then handing final array to Julia) would fit in here. I probably won't get to do it right away, though, have to finish ArraysOfArrays.jl first ...

@oschulz
Copy link
Collaborator

oschulz commented Apr 22, 2018

As for sliding window use cases, I believe the right approach is to simply create a lot of throw-away views, as @uviews make them very very cheap.

@oschulz
Copy link
Collaborator

oschulz commented Apr 23, 2018

This could actually mesh well with TemporaryArrays.jl (new package, still in design phase). The idea there is to provide reusable temporary arrays, to avoid allocation cost for temporary arrays (e.g. target array for boradcast!s, etc.) in tight loops. I originally intended those to be UnsafeArrays backed by Vector{UInt8} behind the scenes, but manual (c)alloc/free and a ResizeableUnsafeArray may be a better fit. For that use case, ResizeableUnsafeArray itself would have to be an immutable type (kind of a hybrid of UnsafeArray and ElasticArray) that holds a pointer to a mutable "storage allocation" object. Or possibly an ElasticArray wrapped around mutable ResizableUnsafeVector.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants