Closed SylvainCorlay closed 7 years ago
Nope, it not accepting non-const operators was a bug :)
Nope, it not accepting non-const operators was a bug :)
Thanks. PS: Actually my PR did not address that but only the forwarding issue. In the case LambdaT is const, operator()
is still of const type. Looking at a better way to infer the signature now.
@barche would it make sense to add a static assert that attribute types of functions passed to method
are not reference types?
What do you mean by attribute types?
I mean that binding foo(ArrayRef<double>& x)
does not work but foo(ArrayRef<double> x)
does. The former yields a dangling reference.
Did you try that? I get a compile error when I use a non-const ref:
error: non-const lvalue reference to type 'cxx_wrap::ArrayRef<double, 1>' cannot bind to a temporary of type 'jl_array_t *'
With a const ref it does work, the temporary returned from the conversion survives until the function is done.
Although if you want to use the ArrayRef
to modify the underlying julia array, it should be non const, so passing it by value is recommended right?
Hum, un-commenting example1
triggers a segfault in the Julia testing. This is surprising because we are actually not even calling the function.
If I'm reading the code correctly, you're returning a nullptr in static_type_mapping::julia_type, that would be a likely cause for the segfault.
Regarding the const ArrayRef: yes, to call a non-const method on that passing by value is better, even though you could always copy the const ref and it would still modify the same array.
So the issue is that the type mapping is not static since I compute the Julia type dynamically based on the dimension of the jlarray. The specialization of ConvertToJulia
does not make use of julia_type
.
The static part of the mapping is used to determine the signature of the function passed to ccall, but julia_type
is used at runtime when the Julia wrapper methods are generated. Having this return a nullptr will attempt to create a Julia method with a return or argument type that is a nullptr, so this will crash when the module is loaded by wrap_module
.
What is the consequence of apply_array_type
being called with the wrong number of dimensions in this context?
I would just omit the type parameters then, returning the base type using e.g.
return cxx_wrap::julia_type("AbstractArray");
@barche FYI,
cxx_wrap::julia_type("AbstractArray");
was accepting things such as Reshaped Arrays
which would result in segfaults.cxx_wrap::julia_type("Array");
which only accepts dense column-major arrays (the assumption that I am making here). It would still accept items with the wrong data type and segfault.Array{T}
where T
is the data type.static jl_datatype_t* julia_type()
{
// Array{T}
return (jl_datatype_t*)apply_type(
jl_get_global(jl_current_module, jl_symbol("Array")),
jl_svec1(cxx_wrap::julia_type<T>())
);
}
Also, in the CI, I noticed that Julia's Int
is either int64_t
or in32_t
depending on the platform, which is ptrdiff_t
. I was thinking that having a jl_int_t
typedef might be nice.
Julia already defines int_t
and uint_t
for these, but they are well hidden in dtypes.h
, which is included from julia.h
.
Cool! Thanks for the info Do you plan on releasing CxxWtap 0.4 soonish? Or should I not wait for it before tagging a first release of xtensor-julia?
As far as I can tell the basics needed to split off the C++ part of CxxWrap into a separate package is now complete, so I think I can tag 0.4, yes. One thing I would still like to check before is how VS2017 and VS2015 can be supported at the same time.
Eventually, it would be nice to have a clear story of how we handle not vendoring binary artefacts and headers in the the julia package directory, for contexts such as Anaconda or linux distributions.
For examples, having a flag for build.jl
to pass another installation prefix for cmake.
This PR reproduces the tests that we have in
xtensor-python
. Current issues.1)
CxxWrap
'sadd_lambda
function takes its third argument (the pointer tooperator()
)const
, which prevents the use of functors whereoperator()
is not const qualified.2) Unlike numpy arrays, in Julia, N-D arrays with different numbers of dimensions have different types. So in order to return an array with a number of dimension determined at runtime (such as for numpy-style broadcasting), we must create the type at runtime, which is what we do in the specialization of
ConvertToJulia::operator()
.For this reason, even though we use dynamic type mapping, we must override
static_type_mapping
for the typedefs here.