-
Notifications
You must be signed in to change notification settings - Fork 2
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
feat: define conversion rules #59
Changes from all commits
ee0d3e1
e3c09a5
5ab4335
7af724d
009bcaf
d6000ab
f2b1406
11fe5d5
11c7c46
3b8663e
9ea8d9c
34f33a7
c396ae7
1cc71e5
f193bf4
7d2c696
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,23 +4,19 @@ authors = ["Jim Pivarski <[email protected]>", "Jerry Ling <jerry.ling@cern | |
version = "0.1.2" | ||
|
||
[deps] | ||
Conda = "8f4d0f93-b110-5947-807f-2305c1781a2d" | ||
JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" | ||
Tables = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" | ||
|
||
[weakdeps] | ||
PythonCall = "6099a3de-0909-46bc-b1f4-468b9a2dfc0d" | ||
|
||
[extensions] | ||
AwkwardPythonCallExt = "PythonCall" | ||
Tables = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" | ||
|
||
[compat] | ||
JSON = "0.21.4" | ||
julia = "1.9" | ||
Tables = "1.11.1" | ||
julia = "1.9" | ||
PythonCall = "0.9" | ||
|
||
[extras] | ||
PythonCall = "6099a3de-0909-46bc-b1f4-468b9a2dfc0d" | ||
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" | ||
|
||
[targets] | ||
test = ["Test", "PythonCall"] | ||
test = ["Test"] |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
module AwkwardPythonCallExt | ||
using PythonCall | ||
using JSON | ||
import AwkwardArray | ||
|
||
function AwkwardArray.convert(layout::AwkwardArray.Content)::Py | ||
form, len, containers = AwkwardArray.to_buffers(layout) | ||
|
||
py_buffers = Dict{String,Any}() | ||
|
||
for (key, buffer) in containers | ||
py_buffers[key] = pyimport("numpy").asarray(buffer, dtype = pyimport("numpy").uint8) | ||
end | ||
|
||
pyimport("awkward").from_buffers(form, len, py_buffers) | ||
end | ||
|
||
function AwkwardArray.convert(array::Py)::AwkwardArray.Content | ||
form, len, _containers = pyimport("awkward").to_buffers(array) | ||
containers = pyconvert(Dict, _containers) | ||
|
||
julia_buffers = Dict{String,Vector{UInt8}}() | ||
|
||
for (key, buffer) in containers | ||
julia_buffers[key] = reinterpret(UInt8, buffer) | ||
end | ||
|
||
AwkwardArray.from_buffers( | ||
pyconvert(String, form.to_json()), | ||
pyconvert(Int, len), | ||
julia_buffers, | ||
) | ||
end | ||
|
||
# rule functions | ||
function pyconvert_rule_awkward_array_primitive(::Type{AwkwardArray.PrimitiveArray}, x::Py) | ||
jpivarski marked this conversation as resolved.
Show resolved
Hide resolved
|
||
array = AwkwardArray.convert(x) | ||
return PythonCall.pyconvert_return(array) | ||
end | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These rule functions should return There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is that distinct from encountering an Exception and raising it? For example, in Python, some overloading functions let you For Awkward Array conversion, there isn't any Python Awkward Array that would return There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
||
function pyconvert_rule_awkward_array_empty(::Type{AwkwardArray.EmptyArray}, x::Py) | ||
array = AwkwardArray.convert(x) | ||
return PythonCall.pyconvert_return(array) | ||
end | ||
|
||
function pyconvert_rule_awkward_array_listoffset(::Type{AwkwardArray.ListOffsetArray}, x::Py) | ||
array = AwkwardArray.convert(x) | ||
return PythonCall.pyconvert_return(array) | ||
end | ||
|
||
function pyconvert_rule_awkward_array_list(::Type{AwkwardArray.ListArray}, x::Py) | ||
array = AwkwardArray.convert(x) | ||
return PythonCall.pyconvert_return(array) | ||
end | ||
function pyconvert_rule_awkward_array_regular(::Type{AwkwardArray.RegularArray}, x::Py) | ||
array = AwkwardArray.convert(x) | ||
return PythonCall.pyconvert_return(array) | ||
end | ||
|
||
function pyconvert_rule_awkward_array_record(::Type{AwkwardArray.RecordArray}, x::Py) | ||
array = AwkwardArray.convert(x) | ||
return PythonCall.pyconvert_return(array) | ||
end | ||
|
||
function pyconvert_rule_awkward_array_tuple(::Type{AwkwardArray.TupleArray}, x::Py) | ||
array = AwkwardArray.convert(x) | ||
return PythonCall.pyconvert_return(array) | ||
end | ||
|
||
function pyconvert_rule_awkward_array_indexed(::Type{AwkwardArray.IndexedArray}, x::Py) | ||
array = AwkwardArray.convert(x) | ||
return PythonCall.pyconvert_return(array) | ||
end | ||
|
||
function pyconvert_rule_awkward_array_indexedoption(::Type{AwkwardArray.IndexedOptionArray}, x::Py) | ||
array = AwkwardArray.convert(x) | ||
return PythonCall.pyconvert_return(array) | ||
end | ||
|
||
function pyconvert_rule_awkward_array_bytemasked(::Type{AwkwardArray.ByteMaskedArray}, x::Py) | ||
array = AwkwardArray.convert(x) | ||
return PythonCall.pyconvert_return(array) | ||
end | ||
|
||
function pyconvert_rule_awkward_array_bitmasked(::Type{AwkwardArray.BitMaskedArray}, x::Py) | ||
array = AwkwardArray.convert(x) | ||
return PythonCall.pyconvert_return(array) | ||
end | ||
|
||
function pyconvert_rule_awkward_array_unmasked(::Type{AwkwardArray.UnmaskedArray}, x::Py) | ||
array = AwkwardArray.convert(x) | ||
return PythonCall.pyconvert_return(array) | ||
end | ||
|
||
function pyconvert_rule_awkward_array_union(::Type{AwkwardArray.UnionArray}, x::Py) | ||
array = AwkwardArray.convert(x) | ||
return PythonCall.pyconvert_return(array) | ||
end | ||
|
||
function __init__() | ||
PythonCall.pyconvert_add_rule("awkward.highlevel:Array", AwkwardArray.PrimitiveArray, pyconvert_rule_awkward_array_primitive, PythonCall.PYCONVERT_PRIORITY_ARRAY) | ||
PythonCall.pyconvert_add_rule("awkward.highlevel:Array", AwkwardArray.EmptyArray, pyconvert_rule_awkward_array_empty, PythonCall.PYCONVERT_PRIORITY_ARRAY) | ||
PythonCall.pyconvert_add_rule("awkward.highlevel:Array", AwkwardArray.ListOffsetArray, pyconvert_rule_awkward_array_listoffset, PythonCall.PYCONVERT_PRIORITY_ARRAY) | ||
PythonCall.pyconvert_add_rule("awkward.highlevel:Array", AwkwardArray.ListArray, pyconvert_rule_awkward_array_list, PythonCall.PYCONVERT_PRIORITY_ARRAY) | ||
PythonCall.pyconvert_add_rule("awkward.highlevel:Array", AwkwardArray.RegularArray, pyconvert_rule_awkward_array_regular, PythonCall.PYCONVERT_PRIORITY_ARRAY) | ||
PythonCall.pyconvert_add_rule("awkward.highlevel:Array", AwkwardArray.RecordArray, pyconvert_rule_awkward_array_record, PythonCall.PYCONVERT_PRIORITY_ARRAY) | ||
PythonCall.pyconvert_add_rule("awkward.highlevel:Array", AwkwardArray.TupleArray, pyconvert_rule_awkward_array_tuple, PythonCall.PYCONVERT_PRIORITY_ARRAY) | ||
PythonCall.pyconvert_add_rule("awkward.highlevel:Array", AwkwardArray.IndexedArray, pyconvert_rule_awkward_array_indexed, PythonCall.PYCONVERT_PRIORITY_ARRAY) | ||
PythonCall.pyconvert_add_rule("awkward.highlevel:Array", AwkwardArray.IndexedOptionArray, pyconvert_rule_awkward_array_indexedoption, PythonCall.PYCONVERT_PRIORITY_ARRAY) | ||
PythonCall.pyconvert_add_rule("awkward.highlevel:Array", AwkwardArray.ByteMaskedArray, pyconvert_rule_awkward_array_bytemasked, PythonCall.PYCONVERT_PRIORITY_ARRAY) | ||
PythonCall.pyconvert_add_rule("awkward.highlevel:Array", AwkwardArray.BitMaskedArray, pyconvert_rule_awkward_array_bitmasked, PythonCall.PYCONVERT_PRIORITY_ARRAY) | ||
PythonCall.pyconvert_add_rule("awkward.highlevel:Array", AwkwardArray.UnmaskedArray, pyconvert_rule_awkward_array_unmasked, PythonCall.PYCONVERT_PRIORITY_ARRAY) | ||
PythonCall.pyconvert_add_rule("awkward.highlevel:Array", AwkwardArray.UnionArray, pyconvert_rule_awkward_array_union, PythonCall.PYCONVERT_PRIORITY_ARRAY) | ||
end | ||
|
||
end # module |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Moelf - it could be due to my own setup, but I did not manage to get this
PythonCall
dependency when running from Python REPL. This is an attempt to fix it.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
before it was set up in a way such that installing
AwkwardArray.jl
does NOT imply needing a Python. If I were to do this, I would just make sure from the python side, it calls something to installPythonCall
.The way this PR implements it, you cannot use this package as a pure-Julia package, which may or may not be what you want.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's what we discussed today. Although it would be better (more opportunities) for this to be usable as a pure-Julia package, @ianna ran into some problems attempting to do so, and I think its primary value would be for users of both Python and Julia. (In Julia, there are already packages for some of these use-cases, such as ArrayOfArrays and StructArrays.)
So the decision between optionally depending on Python and strictly depending on Python is the result of a cost-benefit analysis. The benefit is small but positive; how big is the cost?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the way this PR does it sounds reasonable to me.