4

Following up on this question I now have a class Graph that includes a sparse matrix. Defined like

class Graph {
  var vdom: domain(2),
      SD: sparse subdomain(vdom),
      A: [SD] real;

proc init(A: []) {
  this.vdom = {A.domain.dim(1), A.domain.dim(2)};
  for ij in A.domain {
    this.SD += ij;
  }
}

producing the error

chingon-base-test.chpl:30: error: halt reached - Sparse domain/array index out of bounds: (1, 2) (expected to be within {1..0, 1..0}

It appears SD is not getting redefined. What is the correct pattern? In the previous post, we talked about dense arrays, this is for sparse.

I am calling it via

var nv: int = 8,
    D: domain(2) = {1..nv, 1..nv},
    SD: sparse subdomain(D),
    A: [SD] real;

SD += (1,2); A[1,2] = 1;
SD += (1,3); A[1,3] = 1;
SD += (1,4); A[1,4] = 1;
SD += (2,4); A[2,4] = 1;
SD += (3,4); A[3,4] = 1;
SD += (4,5); A[4,5] = 1;
SD += (5,6); A[5,6] = 1;
SD += (6,7); A[6,7] = 1;
SD += (6,8); A[6,8] = 1;
SD += (7,8); A[7,8] = 1;
g = new Graph(A);
writeln(g.A);
Brian Dolan
  • 3,086
  • 2
  • 24
  • 35
  • 1
    Side-note: Your test program could be written as: `SD += [(1,2), (1,3), (1,4), (2,4), (3,4), (4,5), (5,6), (6,7), (6,8), (7,8)]; A = 1;` -- This would be both faster, since it's doing a bulk-addition to the sparse domain, and less verbose. – ben-albrecht Dec 12 '17 at 15:38
  • Ah! That's interesting. If I have millions to add, should I do it in batches? Thanks for the tip. – Brian Dolan Dec 12 '17 at 16:26

1 Answers1

5

You should set the value of the vdom field during Phase 1 of initialization rather than relying on setting it during the default phase (Phase 2). Phase 1 handles the initial value of all fields, so if you don't set vdom explicitly, it will be {1..0, 1..0} when we make the initial value of the SD and A fields, which is why you are getting that error message.

proc init(A: []) {
  this.vdom = {A.domain.dim(1), A.domain.dim(2)};
  this.complete(); // insert this line here
  for ij in A.domain {
    this.SD += ij;
  }
}

Edit: with executing your sample call line and my fix, I get the following as output:

0.0 0.0 0.0
0.0
0.0
0.0
0.0
0.0 0.0
0.0
Brad
  • 3,839
  • 7
  • 25
Lydia Duncan
  • 595
  • 2
  • 8
  • Awesome, to get the values in, I had to add `for ij in A.domain { this.SD += ij; this.A(ij) = A(ij); // Assign value }` – Brian Dolan Dec 11 '17 at 18:46
  • 1
    I updated Lydia's answer on 2020-09-14 to reflect the current Chapel syntax for signaling that record initialization is over. – Brad Sep 14 '20 at 17:53