map function arguments of dense<f32,2> & foo

map function arguments of dense<f32,2> & foo

I am looking at the argument types that can be passed into a function to
be called by map. As far as I can see this

void testMapFn1(arbb::f32& t1, arbb::f32 t2, arbb::dense<:f32> t3, arbb::dense<:f32> & t4) {

arbb::usize col;
t1 = t2 + t3(col,0);
t4(col,0) = t1;

doesn't break any of the rules, but when i try and call it like

void testMapFn1Call(arbb::dense<:f32> & t1, arbb::dense<:f32> t2,
arbb::dense<:f32> t3, arbb::dense<:f32> & t4) {


I get a stack of compilation errors.

Its related to the last argument, if I remove that argument

void testMapFn2(arbb::f32& t1, arbb::f32 t2, arbb::dense<:f32> t3) {

arbb::usize col;
t1 = t2 + t3(col,0);

and call it

void testMapFn2Call(arbb::dense<:f32> & t1, arbb::dense<:f32> t2, arbb::dense<:f32> t3, arbb::dense<:f32> & t4) {


then it compiles happily.

Have a mis-understood the rules about arguments to map functions ?


5 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.


Although a function passed to arbb::map() can take containers as arguments, it cannot modify the container arguments. In another words, such functions cannot use container arguments as output arguments.


Hi Zhang,
Once again, thanks for the reply. I guess, however, that if a container contained a user defined type (UDT) of multiple
values, then this could be passed in to a mapped function and the individual UDT elements would be modifiable

something like

typedef array UDT1;

void func1(dense & t1) {

void func1Map(UDT1 & t1) {

t1[0] = 1;
t1[1] = 2;
. . .



Collecting dense containers into a UDT and passing a "single" argument is technically nothing else than passing each of the dense containers individually. Therefore the suggested code will not work for the reasons you already considered. One note, updating the fixed argument (testMapFn1) using the position is basically the scatter operator in ArBB. By today, there is still time left to apply for the upcoming webinar which is also showing a variety of answers of the question "How to update the values of a container according to an index". If you cannot attend, you can download the webinar's material later on.

Let me explain the purpose of the rules behind elemental functions. Exploiting parallelism by mapping an elemental function using the ArBB map operator is logically similar to applying the elemental function for each element of the varying arguments. Moreover, the order of the application cannot be determined. Although, the reproduced result is still holding the requirements of the determinism feature in ArBB. Since all parallelism is already exploited including this additional "order independence", there is no technical advantage of supporting element-wise operators inside the elemental function. Though, element-wise operators in ArBB are expressing parallelism. This background is the reasoning behind elemental functions in ArBB. For example, to only allow expressions on an element-by-element basis is one of these rules. However, having the syntactical sugar of element-wise functions within the elemental function is another story. We are are avoiding to introduce features in a way which might become contrary to a good parallel implementation. We are open for your suggestions on improving elemental functions, and we are carefully evaluating this feedback.

Hi Hanse,
Thanks for your reply. As to your first point, "Collecting dense containers into a UDT and passing a "single" argument
is technically nothing else than passing each of the dense containers
individually" maybe you are technically connect. If I have a dense container (lets say 2D) and at each element within that container is a UDT made up of an array then I think that I am following the logic of data parallelism by being able to operate on all elements of the array that relate to the my relative position. I have tried passing a dense> & as an element to a call(ed) function which in turn map(s) another element wise function taking elements of array & and been able to modify all of the elements of the array. This is conceptually much easier to understand and simpler to code than having to break everything up into individual dense objects of scalars.

I have been using arbb for a few weeks now and am beginning to get frustrated by some of the restrictions on what is allowed. For example, I have a 2D array that I bind to a dense but the operation I wish to perform is row based where the result of
the calculation on row i+1 is based on the result in i. To use arbb I have to split my 2D array into a set of 1D arrays and then call
the function repeatedly as a set of vector operations and then re-assemble my 2D array of results rather than simply being able to pass a rows of my 2D dense object in sequentially in a loop. I don't really see any reason for this restriction?

Other things that I am struggling with are that the types do not cast easily, for example in a map(ed) function
usize entry;
// Calculate next step based on position in array
i32 i;
i32 limit = entry; // Need this due to casting problems . . .
_for (i = 0, i
here I am having to use a temporary variable limit as it won't let me build a loop using entry due to some type problem.

If I then want to access the elements of an array in the loop
v[i] = 10;
this also won't compile as I'm not allowed to use i32 as an array index, it wants to be an int and i don't seem to be able
to do the temporary variable trick of
int v = i;
val[v] = 10;
similar to above, nor am i allowed to simply use
val[value(i)] = 10;
as you can't call value on local variables (so now i'm currently stuck on that one).

Sorry to seem negative and I'm sure these are things that are being worked on, but you did ask . . .


Leave a Comment

Please sign in to add a comment. Not a member? Join today