3

I am trying to use the GFOR construct, but I can't even make it work for basic stuff.

I suspect that the GFOR loop does not work with linear indexes, am I correct?

Here are some code samples that don't work

af::array x(100, 200);
af::array y(100, 200);
af::array xx(100, 200);
gfor(af::seq i, (100 * 200)) {
    xx(i) = x(i) + y(i);
}

This one is supposed to do a simple addition element-wise (I know I can just do xx = x+y, I just want to show that gfor is not working as expected). The error is Invalid input size:203 in function seqToDims.

Another one is a more simple program, like this

af::array x(100, 200);
af::array y(100, 200);
gfor(af::seq i, (100 * 200)) {
    y(i) = x(i) + 1;
}

Same error.

I have seen the documentation and what I think is that gfor does not work with linear indexes and I need to somehow work "line-by-line" or "column-by-column", because the examples in the docs always show something like A(span,i) and not A(i).

Apart from that, what I really want to do is something simple: I have: an array image(rows,cols), an array x_(8, rows*cols), an array ax(8,1); and a scalar which is found by sum(x_(span,i)*ax) (it's actually the dot product, but the dot() function is not supported in gfor), this scalar is computed by using the columns of x_ (size of 8) and the ax which is of size 8 too.

I want

e(i) = image(i) - sum<float>(ax * x_(span,i));

I can't seem to make it work because not even the simple gfor loops above work, which is unexpected, what am I doing wrong?

Thanks!

Robert Crovella
  • 143,785
  • 11
  • 213
  • 257
eikonoules
  • 53
  • 3
  • I have the same question, I have not managed to make gfor work for anything. not even the example on the docs (ie A = A+1). – mkln Feb 11 '20 at 02:57

1 Answers1

0

You have declared 2-dimensional arrays, but you are trying to address them with only one dimension. You cannot have

array x(100, 200);
x(150) = 10;   // The second dimension is missing here.

You can use gfor to create a sequence and use this sequence in one of the dimensions. You can use the usual ways to address the other dimension, i.e. 'span'.

array x(100, 200); // 100 columns, 200 rows
gfor (seq i, 200) {   // will create a sequence from 0...199
   x(span, i) += 10;  // will take a slice of x: the entire column (span) of row 'i'
                      // and add the value 10 to it
}

Note that x is now being addressed with two dimensions? The first dimension is span, in other words, the entire span of that dimension. The second dimension is the sequence defined in gfor. You can of course swap the dimensions:

array x(100, 200); // same as above
gfor (seq i, 100) {  // create  a sequence from 0..99  (not 199)
   x(i, span) += 20; // access x by rows (span) and the sequence i
}

From your code I can deduct that you are still thinking linearly/sequentially, like a C(++) programmer. The giveaway is seq i, (100*200) You are trying to iterate over the entire elements (rows*cols), but arrayfire uses vector arithmetics. You do not want to access individual elements. You want to access vectors/slices/entire rows or colums and do something with them.

And for what you are actually trying to acomplish (e(i) = image(i)...) have a look at the arrayfire batch function. This might help.

Nimantha
  • 6,405
  • 6
  • 28
  • 69
Hajo Kirchhoff
  • 1,969
  • 8
  • 17