2

I have a domain D, and I want to use it to index several matrices A. Something of the form

var dom: domain(1) = {0..5};
var mats: [dom] <?>;

var a0 = [[0.0, 0.1, 0.2], [0.3, 0.4, 0.5]];
var a1 = [[1.0, 1.1, 1.2, 1.3], [1.4, 1.5, 1.6, 1.7]];

mats[0] = a0;
mats[1] = a1;

Each a will be 2D but have different sizes. Yes, some of these will be sparse (but need not be for purposes of this question)

== UPDATE ==

For clarity, I have a series of layers (it's a neural net), say 1..15. I created var layerDom = {1..15} Each layer has multiple objects associated with it, like error so I have

var errors: [layerDom] real;  // Just a number

And I'd like to have

var Ws: [layerDom] <matrixy thingy>;  // Weight matrices all of different shape.
Brian Dolan
  • 3,086
  • 2
  • 24
  • 35
  • I *think* you're asking "How to declare an array of arrays, where the sub-arrays have varying size in Chapel?". If so, the answer wouldn't depend on the arrays being sparse or not, so I think that detail can be ignored here, as you noted. Does that sound right? – ben-albrecht Aug 28 '17 at 17:26
  • I think sparsity is probably not a factor here, but I'm often wrong so I'd leave it up to you. Really, I'd like to have `var arrDom = {1...15}` and then get the 7th array back when I need it. – Brian Dolan Aug 28 '17 at 17:51

1 Answers1

2

As of Chapel 1.15 there isn't an elegant way to create an array of arrays where the inner arrays have different sizes. This is because the inner arrays all share the same domain, meaning that changing one array's domain changes all arrays.

To achieve the desired effect, you need to create an array of records/classes that contain an array:

record Weight {
  var D : domain(2);
  var A : [D] real;
}

var layers = 4;
var weights : [1..layers] Weight;
for i in 1..layers {
  weights[i].D = {1..i, 1..i};
  weights[i].A = i;
}

for w in weights do writeln(w.A, "\n");

// 1.0
// 
// 2.0 2.0
// 2.0 2.0
// 
// 3.0 3.0 3.0
// 3.0 3.0 3.0
// 3.0 3.0 3.0
// 
// 4.0 4.0 4.0 4.0
// 4.0 4.0 4.0 4.0
// 4.0 4.0 4.0 4.0
// 4.0 4.0 4.0 4.0
// 
benharsh
  • 396
  • 1
  • 8
  • so if I want to multiply one weight by another, I would need to do `dot(weights[7].A, weights[9].A.T)`, correct? – Brian Dolan Aug 28 '17 at 19:11
  • 1
    I believe so (provided the weights at `7` and `9` are valid sizes for `dot`). – benharsh Aug 28 '17 at 19:26
  • Is there any plan to support this in the future? – Brian Dolan Aug 28 '17 at 19:53
  • ...and why a "record" and not a class? – Brian Dolan Aug 28 '17 at 19:55
  • 1
    I believe the Chapel team wants to support these kinds of arrays (also known as 'skyline' arrays), and has wanted to for a long time. Thus far it hasn't been important enough compared to other features. I chose a `record` so that the memory would be managed for you. A `class` would be perfectly fine. – benharsh Aug 28 '17 at 22:04