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

Error when writing Array{Float64, 0} #197

Closed
tomchor opened this issue Dec 21, 2022 · 3 comments
Closed

Error when writing Array{Float64, 0} #197

tomchor opened this issue Dec 21, 2022 · 3 comments

Comments

@tomchor
Copy link

tomchor commented Dec 21, 2022

Describe the bug

I get an error when trying to write a type Array{Float64, 0} to an index of a variable with an unbounded dimension. The error is also reported in CliMA/Oceananigans.jl#2857

To Reproduce

using NCDatasets

a = reshape([1.], 1, 1, 1)
b = dropdims(a, dims=(1, 2, 3))

ds = NCDataset("/tmp/test.nc","c")
time = defDim(ds,"time",Inf)
v = defVar(ds,"temp",Float32,("time",))
ds["temp"][1] = b

close(ds)

In believe this comes from the function call T(data) in this line:

nc_put_var1(v.ds.ncid,v.varid,[i-1 for i in indexes[ndims(v):-1:1]],T(data))

Expected behavior

I expected the Array to be successfully writen to the NetCDF. For reference, this MWE works, which shows that the issue comes when using an unbounded dimension:

using NCDatasets
    
a = reshape([1.], 1, 1, 1)
b = dropdims(a, dims=(1, 2, 3))

ds = NCDataset("/tmp/test.nc","c")
v = defVar(ds,"temp",Float32,())
ds["temp"][] = b

close(ds)

Environment

Full output

julia> a = reshape([1.], 1, 1, 1)
1×1×1 Array{Float64, 3}:
[:, :, 1] =
 1.0

julia> b = dropdims(a, dims=(1, 2, 3))
0-dimensional Array{Float64, 0}:
1.0

julia> ds = NCDataset("/tmp/test.nc","c")
NCDataset: /tmp/test.nc
Group: /



julia> time = defDim(ds,"time",Inf)

julia> v = defVar(ds,"temp",Float32,("time",))
temp (0)
  Datatype:    Float32
  Dimensions:  time

julia> ds["temp"][1] = b
ERROR: MethodError: no method matching Float32(::Array{Float32, 0})
Closest candidates are:
  (::Type{T})(::AbstractChar) where T<:Union{AbstractChar, Number} at char.jl:50
  (::Type{T})(::Base.TwicePrecision) where T<:Number at twiceprecision.jl:266
  (::Type{T})(::Complex) where T<:Real at complex.jl:44
  ...
Stacktrace:
 [1] setindex!(v::NCDatasets.Variable{Float32, 1, NCDataset{Nothing}}, data::Array{Float32, 0}, indexes::Int64)
   @ NCDatasets ~/.julia/packages/NCDatasets/sLdiM/src/variable.jl:308
 [2] setindex!(v::NCDatasets.CFVariable{Float32, 1, NCDatasets.Variable{Float32, 1, NCDataset{Nothing}}, NCDatasets.Attributes{NCDataset{Nothing}}, NamedTuple{(:fillvalue, :missing_values, :scale_factor, :add_offset, :calendar, :time_origin, :time_factor), Tuple{Nothing, Tuple{}, Nothing, Nothing, Nothing, Nothing, Nothing}}}, data::Array{Float64, 0}, indexes::Int64)
   @ NCDatasets ~/.julia/packages/NCDatasets/sLdiM/src/cfvariable.jl:765
 [3] top-level scope
   @ REPL[34]:1

julia> close(ds)
closed NetCDF NCDataset

I was wondering if this is something that should be dealt with on the NCDatasets side, or if this is by design and we should deal with it on the Oceananigans side.

Thanks

Alexander-Barth added a commit that referenced this issue Jan 13, 2023
@Alexander-Barth
Copy link
Owner

Thanks a lot for the very detailed bug report!

I noticed that also in Base julia complains a bit about this:

b = dropdims([1], dims=(1,))
temp = [1.,2.,3.]
temp[1] = b # ERROR: MethodError: Cannot `convert` an object of type Array{Float64, 0} to an object of type Float64

But the following works in Julia:

b = dropdims([1], dims=(1,))
temp = [0.,2.,3.]
temp[1:1] = b # ok

In the master version (but not in v0.12.11) the following now work too with NCDatasets,

using NCDatasets
b = dropdims([1.], dims=(1,))

isfile("/tmp/test.nc") || rm("/tmp/test.nc")
ds = NCDataset("/tmp/test.nc","c")
time = defDim(ds,"time",Inf) # works also for fixed size arrays
v = defVar(ds,"temp",Float32,("time",))
ds["temp"][1:1] = b
close(ds)

Are you fine to use ds["temp"][1:1] in your code when using 0-dimensional arrays?
(thanks for your great work on Oceananigans :-) )

@tomchor
Copy link
Author

tomchor commented Jan 14, 2023

Thanks a lot for the very detailed bug report!

I noticed that also in Base julia complains a bit about this:

b = dropdims([1], dims=(1,))
temp = [1.,2.,3.]
temp[1] = b # ERROR: MethodError: Cannot `convert` an object of type Array{Float64, 0} to an object of type Float64

But the following works in Julia:

b = dropdims([1], dims=(1,))
temp = [0.,2.,3.]
temp[1:1] = b # ok

In the master version (but not in v0.12.11) the following now work too with NCDatasets,

using NCDatasets
b = dropdims([1.], dims=(1,))

isfile("/tmp/test.nc") || rm("/tmp/test.nc")
ds = NCDataset("/tmp/test.nc","c")
time = defDim(ds,"time",Inf) # works also for fixed size arrays
v = defVar(ds,"temp",Float32,("time",))
ds["temp"][1:1] = b
close(ds)

Are you fine to use ds["temp"][1:1] in your code when using 0-dimensional arrays?

Thanks for the fix! I think this solution will work out (let's see how the discussion on the relevant PR (CliMA/Oceananigans.jl#2865) goes to be sure...)

(thanks for your great work on Oceananigans :-) )

Thank you! But I can't take the merit there. I'm only a very minor contributor :)
But yeah, I think the main developers there do a really good job!

@Alexander-Barth
Copy link
Owner

I am closing the issue; feel free to re-open if there are still some difference between Base.Array and NCDatasets regarding the 0-D arrays.

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