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

broadcasting in af_arith for binary operations [WIP] #2871

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

Copy link
Contributor

@syurkevi syurkevi commented May 5, 2020

Will prepend 1s until dimension sizes match, then 1s are treated as wildcards and are broadcasted to their matching sizes.

array A = range(dim4(32, 32, 3), 2);  // [32 32 3]
array B = -range(dim4(3)); //    [ 3 ] -> [1* 1* 3]

array C = A + B; // [32 32 3]

In cases where one of the arguments is a vector, prepending until dimensions match may not align well:

 array A = constant(-1, dim4(15, 3, 5)); // [15 3 5]
 array B = constant(1, dim4(3, 1));        // [ 1  1 3] - misaligned,
 // even though 3 intended to broadcast with second dimension of A

Upon a mismatch, the prepended vectors will be shifted left until there is a match. In the above example the broadcast will be a success after a single additional shift.

This manner of treating vectors is a workaround due to no difference between.

af::dim4 d1(3);
af::dim4 d2(3, 1);
af::dim4 d3(3, 1, 1);
af::dim4 d4(3, 1, 1, 1);
// d1 == d2 == d3 == d4

TODO:

  • n-ary operations?
  • complex values

const dim4 ldims = linfo.dims();
const dim4 rdims = rinfo.dims();

unsigned maxndims =
Copy link
Member

@9prady9 9prady9 May 14, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unsigned maxndims = std::max(ldims.ndims(), rdims.ndims());

Would this break logic ?

dim4 padded(1, 1, 1, 1);

const unsigned MAXDIMS = 4;
for (unsigned i = 0; i < MAXDIMS; ++i) {
Copy link
Member

@9prady9 9prady9 May 14, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MAXDIMS -> AF_MAX_DIMS

We can then remove this new constant MAXDIMS

@@ -46,6 +48,96 @@ static inline af_array arithOp(const af_array lhs, const af_array rhs,
return res;
}

dim4 paddims(const dim4 &dims, unsigned offset) {
Copy link
Member

@9prady9 9prady9 May 14, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

paddims -> padDims to be consistent

dim4 ltile(1, 1, 1, 1);
dim4 rtile(1, 1, 1, 1);
// check that dimensions are compatible
for (unsigned i = 0; i < 4; ++i) {
Copy link
Member

@9prady9 9prady9 May 14, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

4 -> AF_MAX_DIMS

detail::Array<T> lhst =
detail::tile<T>(modDims(getArray<T>(lhs), lpad), ltile);
detail::Array<T> rhst =
detail::tile<T>(modDims(getArray<T>(rhs), rpad), rtile);
Copy link
Member

@9prady9 9prady9 May 14, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add using statements for the following to fit convention we are following in other files.

  • using detail::Array
  • using detail::tile
  • using std::tie

detail::tile<T>(modDims(getArray<T>(rhs), rpad), rtile);

af_array res = getHandle(arithOp<T, op>(lhst, rhst, odims));
return res;
Copy link
Member

@9prady9 9prady9 May 14, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Above two lines can be clubbed.

@@ -582,3 +582,69 @@ TEST(Array, InitializerListAndDim4) {

ASSERT_ARRAYS_EQ(A, B);
}

TEST(Broadcast, Simple1) {
Copy link
Member

@umar456 umar456 Apr 4, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you create parameterized tests for the input dims? You also want to compare this functionality to the tiled version of the same operation. Additionally you should make sure that the kernels generated and the operations performed by these functions are what you expect.

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

Successfully merging this pull request may close these issues.

None yet

3 participants