# Promote\_shape dimension mismatch

**URL:** <https://discourse.julialang.org/t/promote-shape-dimension-mismatch/57529>\
**Category:** General Usage\
**Tags:** broadcast\
**Created:** [March 19, 2021, 11:11am UTC](https://discourse.julialang.org/t/promote-shape-dimension-mismatch/57529 "2021-03-19T11:11:06Z")\
**Posts on this page:** 18\
**Page:** 1

<div class="post-metadata">

**Author:** ![Marcell\_Havlik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marcell_havlik/32/37424_2.png) [@Marcell\_Havlik](https://discourse.julialang.org/u/Marcell_Havlik)\
**Post date:** [March 19, 2021, 11:11am UTC](https://discourse.julialang.org/t/promote-shape-dimension-mismatch/57529/1 "2021-03-19T11:11:06Z")

</div>

Hey,

I saw an error message:  
`ERROR: LoadError: DimensionMismatch("dimensions must match: a has dims (Base.OneTo(2), Base.OneTo(3), Base.OneTo(2), Base.OneTo(6)), b has dims (Base.OneTo(2), Base.OneTo(3), Base.OneTo(2), Base.OneTo(1)), mismatch at 4")`  
and I wanted to know what is the use of Base.OneTo in everywhere in the shape checking. Why don’t we just user size(matrix)?

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [March 19, 2021, 11:16am UTC](https://discourse.julialang.org/t/promote-shape-dimension-mismatch/57529/2 "2021-03-19T11:16:34Z")

</div>

> [@Marcell\_Havlik](#):
>
> I wanted to know what is the use of Base.OneTo in everywhere in the shape checking

`Base.OneTo(n)` is basically `1:n` but the compiler knows for certain (via the type) that the start index is `1`.

---

<div class="post-metadata">

**Author:** ![Marcell\_Havlik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marcell_havlik/32/37424_2.png) [@Marcell\_Havlik](https://discourse.julialang.org/u/Marcell_Havlik)\
**Post date:** [March 19, 2021, 11:35am UTC](https://discourse.julialang.org/t/promote-shape-dimension-mismatch/57529/3 "2021-03-19T11:35:50Z")

</div>

Yes, but why do we need anything like that?

I mean why don’t we just use size(…)?

We increase complexity and ad some redundancy with that without any benefit with the OneTo?

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [March 19, 2021, 11:37am UTC](https://discourse.julialang.org/t/promote-shape-dimension-mismatch/57529/4 "2021-03-19T11:37:05Z")

</div>

The benefit is that

> [@kristoffer.carlsson](#):
>
> the compiler knows for certain (via the type) that the start index is `1` .

and can thus generate better code in some cases.

---

<div class="post-metadata">

**Author:** ![Marcell\_Havlik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marcell_havlik/32/37424_2.png) [@Marcell\_Havlik](https://discourse.julialang.org/u/Marcell_Havlik)\
**Post date:** [March 19, 2021, 11:45am UTC](https://discourse.julialang.org/t/promote-shape-dimension-mismatch/57529/5 "2021-03-19T11:45:37Z")

</div>

For me this sounds strange, but I understand you.

I could imagine that, size(…) return with a list of Int instead of list of OneTo()-s (axes(…))…? 😃 The compiler should be able to optimize this too I think. Strange…  
For example here: [https://github.com/JuliaLang/julia/blob/69fcb5745bda8a5588c089f7b65831787cffc366/base/indices.jl#L169](https://github.com/JuliaLang/julia/blob/69fcb5745bda8a5588c089f7b65831787cffc366/base/indices.jl#L169)

---

<div class="post-metadata">

**Author:** ![mcabbott](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mcabbott/32/6603_2.png) [@mcabbott](https://discourse.julialang.org/u/mcabbott)\
**Post date:** [March 19, 2021, 11:52am UTC](https://discourse.julialang.org/t/promote-shape-dimension-mismatch/57529/6 "2021-03-19T11:52:39Z")

</div>

> [@Marcell\_Havlik](#):
>
> I mean why don’t we just use size(…)?

What I think you’re missing is OffsetArrays.jl: `axes(A)` is allowed to have ranges not starting at 1, so in general has more information than `size(A)`.

---

<div class="post-metadata">

**Author:** ![Marcell\_Havlik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marcell_havlik/32/37424_2.png) [@Marcell\_Havlik](https://discourse.julialang.org/u/Marcell_Havlik)\
**Post date:** [March 19, 2021, 11:54am UTC](https://discourse.julialang.org/t/promote-shape-dimension-mismatch/57529/7 "2021-03-19T11:54:20Z")

</div>

Damn those stupid OffsetArrays… that unnecessary redundancy that came with it… 😃 Should be separated pff… 😃

---

<div class="post-metadata">

**Author:** ![Marcell\_Havlik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marcell_havlik/32/37424_2.png) [@Marcell\_Havlik](https://discourse.julialang.org/u/Marcell_Havlik)\
**Post date:** [March 19, 2021, 2:40pm UTC](https://discourse.julialang.org/t/promote-shape-dimension-mismatch/57529/8 "2021-03-19T14:40:57Z")

</div>

Damn, sorry to continue but… why don’t we just create another for OffestArrays:

```julia
function promote_shape(a::AbstractArray, b::AbstractArray)
    promote_shape(size(a), size(b))
end

function promote_shape(a::OffsetArray, b::OffsetArray)
    promote_shape(axes(a), axes(b))
end

```

So we could essentially simplify the whole expressions in the end. (Also this is probably one of the most widely used feature, Array aritmetics.)

Also the developer won’t face with a long OneTo(…), OneTo(…)… things when it is just simple a size check in the error messages. 😃

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [March 20, 2021, 7:30am UTC](https://discourse.julialang.org/t/promote-shape-dimension-mismatch/57529/9 "2021-03-20T07:30:10Z")

</div>

What you are missing above is that one is free to define types _other_ than `OffsetArray` with similar functionality, so the first `promote_shape(a::AbstractArray, b::AbstractArray)` method would give bogus results.

`Base.OneTo` is just a minor optimization that is mostly a red herring here, the important point is that generalized indexing requires one uses `axes` etc.

---

<div class="post-metadata">

**Author:** ![Marcell\_Havlik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marcell_havlik/32/37424_2.png) [@Marcell\_Havlik](https://discourse.julialang.org/u/Marcell_Havlik)\
**Post date:** [March 20, 2021, 8:51am UTC](https://discourse.julialang.org/t/promote-shape-dimension-mismatch/57529/10 "2021-03-20T08:51:46Z")

</div>

Yeah, indeed. Then I would just do an otimised version for the Array:

```julia
function promote_shape(a::Array{A}, b::Array{B}) where {A,B}
    promote_shape(size(a), size(b))
end

```

I would do this because OneTo(…) add unnecessary complexity for the error promote for the “Array” types… and I am pretty sure it must add one more little by the OneTo struct in the optimisation process of the compiler… not to mention that I guess 90-99% of the people use the Array/Vector/Matrix most of their time, so it worth the optimisation. (Also julia is all about simplicity and if the core gets simpler it always worths the trade.) What do you think?

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [March 20, 2021, 10:18am UTC](https://discourse.julialang.org/t/promote-shape-dimension-mismatch/57529/11 "2021-03-20T10:18:23Z")

</div>

> [@Marcell\_Havlik](#):
>
> I would just do an otimised version for the Array

Pretty much the whole point of Julia is that you get these automatically — a specific version of the method is compiled for each call signature.

> [@Marcell\_Havlik](#):
>
> OneTo(…) add unnecessary complexity for the error

I guess one could make this error message prettier (eg print ranges of indices). But that’s orthogonal to the optimization issue.

---

<div class="post-metadata">

**Author:** ![Marcell\_Havlik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marcell_havlik/32/37424_2.png) [@Marcell\_Havlik](https://discourse.julialang.org/u/Marcell_Havlik)\
**Post date:** [March 20, 2021, 11:11am UTC](https://discourse.julialang.org/t/promote-shape-dimension-mismatch/57529/12 "2021-03-20T11:11:34Z")

</div>

I don’t see the why we don’t want to use the optimised version. I understand each point what you are saying. I just proposed an easy optimisation, that could provide better LLVM code faster, which is used crazy amount of times.

We can make specialisation based on our knowledge about the object. Using general version of the method is waste in this scenario.

I know julia is able to do many optimisation and compile the code only once, but I add 1 single specialisation that would make the code easier, cleaner and even faster a little bit at first run.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [March 20, 2021, 11:55am UTC](https://discourse.julialang.org/t/promote-shape-dimension-mismatch/57529/13 "2021-03-20T11:55:50Z")

</div>

> [@Marcell\_Havlik](#):
>
> Using general version of the method is waste in this scenario.

Did you actually check this? This may be an unwarranted assumption.

---

<div class="post-metadata">

**Author:** ![Marcell\_Havlik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marcell_havlik/32/37424_2.png) [@Marcell\_Havlik](https://discourse.julialang.org/u/Marcell_Havlik)\
**Post date:** [March 20, 2021, 12:43pm UTC](https://discourse.julialang.org/t/promote-shape-dimension-mismatch/57529/14 "2021-03-20T12:43:05Z")

</div>

No, I just checked broadcast.jl operation.jl and arraymath.jl code and realised this possible improvement option. It would be nice if someone who work on julialang could test it.

---

<div class="post-metadata">

**Author:** ![Marcell\_Havlik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marcell_havlik/32/37424_2.png) [@Marcell\_Havlik](https://discourse.julialang.org/u/Marcell_Havlik)\
**Post date:** [March 20, 2021, 12:59pm UTC](https://discourse.julialang.org/t/promote-shape-dimension-mismatch/57529/15 "2021-03-20T12:59:50Z")

</div>

I tested it in my local environment. I am on 1.6.0.rc1.

```julia
using Base: promote_shape

function Base.promote_shape(a::Array{A}, b::Array{B}) where {A,B}
   promote_shape(size(a), size(b))
end

q=randn(3,4)
p=randn(3,2)
p+q

```

For me it is really clean.  
The stacktrace changed from:  
`ERROR: LoadError: DimensionMismatch("dimensions must match: a has dims (Base.OneTo(3), Base.OneTo(2)), b has dims (Base.OneTo(3), Base.OneTo(4)), mismatch at 2")`  
to this:  
`ERROR: LoadError: DimensionMismatch("dimensions must match: a has dims (3, 2), b has dims (3, 4)")`  
I checked some @btime and @time which shows a very slight improvment on the compilation part (10%) and runtime (0-4%) as we could expect it.

Compilation @time info:  
from: (8.3% gc time can be substracted)  
`# 0.118740 seconds (382.40 k allocations: 21.776 MiB, 8.31% gc time, 99.89% compilation time)`  
to:  
`# 0.093647 seconds (354.44 k allocations: 19.927 MiB, 99.89% compilation time)`  
@btime info:  
from: `# 7.093 μs (2 allocations: 93.83 KiB)`  
to: `# 6.975 μs (2 allocations: 93.83 KiB)`

Do you think I should open a pull request to or an issue to ellaborate on it?

---

<div class="post-metadata">

**Author:** ![Marcell\_Havlik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marcell_havlik/32/37424_2.png) [@Marcell\_Havlik](https://discourse.julialang.org/u/Marcell_Havlik)\
**Post date:** [March 20, 2021, 1:12pm UTC](https://discourse.julialang.org/t/promote-shape-dimension-mismatch/57529/16 "2021-03-20T13:12:40Z")

</div>

Ok, I guess I just post it and the masters will decide anyway…  
I really think this could be help and beneficial for newcomers and advanced julianners.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [March 20, 2021, 4:37pm UTC](https://discourse.julialang.org/t/promote-shape-dimension-mismatch/57529/17 "2021-03-20T16:37:18Z")

</div>

It is unclear what and how you are benchmarking here.

`Base.promote_shape` should be on the order on a few tens of **nano** seconds.

Also, note that `Base.OneTo` also just encodes and integer, so there is no reason to expect a performance improvement.

---

<div class="post-metadata">

**Author:** ![Marcell\_Havlik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marcell_havlik/32/37424_2.png) [@Marcell\_Havlik](https://discourse.julialang.org/u/Marcell_Havlik)\
**Post date:** [March 20, 2021, 5:58pm UTC](https://discourse.julialang.org/t/promote-shape-dimension-mismatch/57529/18 "2021-03-20T17:58:11Z")

</div>

I am talking about compilation time.

Runtime should be optimal, I guess it should be the same.
