Create record containing an array

Hello,

I need a data structure that contains (among other things) an array with settable dimensions.

This what I have so far:

tyrecord Bob {
  var id : int;			/* defaults to 0 */
  var D : domain;
  var ar : [D] real;		/* default bounds are 0..4 */

  proc init() {
    this.id = 0;
    this.D = {0..4};
    this.ar = [0.0, 0.0, 0.0, 0.0, 0.0]; 
  }
}

var robert : Bob(?);		/* use the supplied default initialiser  */
writeln(robert.ar.size);	/* should be 5 */

Compile:

chpl Array_in_a_Record.chpl
Array_in_a_Record.chpl:21: error: cannot default-initialize a variable with generic type
Array_in_a_Record.chpl:21: note: 'robert' has generic type 'Bob'
Array_in_a_Record.chpl:21: note: cannot find initialization point to split-init this variable
Array_in_a_Record.chpl:22: note: 'robert' is used here before it is initialized

I add (?) to the declaration of 'robert' in response to a compiler warning. I don't know why that was needed and I don't understand the remaining error or know how to fix it.

Thanks,
Roger

Hi Roger —

There are a few ways to address this. Let me suggest a few in hopes that one might appeal to you and work for your use-case.

BTW, it looks like there's a copy-paste error in your code and that the first line should simply read record rather than tyrecord. In addition, the line numbers in the quoted message seem to refer to a larger program that this was taken from. For those following along, here's a cleaned up copy on ATO.

First, let me interpret the error messages you're getting:

  • the first "cannot default-initialize a variable with generic type" stems from the field 'D' being declared as 'domain' without saying more about its rank (and potentially index type, whether it's associative or rectangular, etc.). D is generic, and it's the fact that it's generic that's causing problems for Bob.
  • the second line asserts Bob is generic without providing much additional information to understand why. While the default initializer implies a concrete instantiation of Bob, the type signature Bob(?) does not specify which instantiation to use which is why the compiler is looking for an initializer expression to determine the missing details implied by the ?.
  • the third line mentions that the compiler is trying, and failing, to find an initial assignment to robert that it could use as an initializer expression to infer these details
  • the fourth notes that the first reference it finds to it is a use, but because it hasn't been initialized yet, this is a problem.

Probably the easiest way to resolve this is to make Bob non-generic by fleshing out the type for D. Of course, this is only possible if D will always have the same type across all instances of Bob. If it will, you could declare D as domain(1) to say "D is a 1D, default rectangular array" and then remove the (?) from Robert's declaration to take advantage of that concrete type and default initializer. Here are the lines that would change in this approach:

  var D : domain(1);
  ...
  var robert : Bob;

And here's the complete program on ATO.

Another approach would be to keep D generic and insert the missing initializer expression, as follows:

  var robert: Bob(?) = new Bob();

or simply:

  var robert = new Bob();

Here's the first of those two approaches on ATO.

There are other approaches as well where you could be more explicit about how Bob is generic using type and param fields to create distinct concrete type signatures for Bob, but I'm going to wait on those for now to avoid overwhelming you with details that might not matter if the first approach above would work.

Please let us know if you have follow-up questions,
-Brad

Hello Brad,

Bradcray via Chapel Programming Language notifications@chapel.discoursemail.com writes:

  • bradcray Core Chapel Developer
    December 4

Hi Roger —

There are a few ways to address this. Let me suggest a few in hopes
that one might appeal to you and work for your use-case.

Sorry about the copy-paste problems.

I need to digest what you have told me and to re-read the docs
concerning domains. I'll report back when I have done so.

Many thanks,
Roger

Hi Roger —

Sounds good. As I say, definitely let us know if something remains unclear, or you're having trouble expressing a particular pattern.

BTW, something that improved in Chapel 1.32 (which I didn't have time to verify earlier, but just have) is that to help identify generic domain fields, we now generate a warning if domain(?) isn't used as the type. Thus, where you have:

  var D: domain;

Chapel 1.32 warns with:

warning: please use 'domain(?)' for the type of a generic field storing any domain

to help alert users to the generic-ness of the field. This makes them more similar to other generic types (that are not fully defaulted), but due to the implementation of domains, the warnings lagged some of the other cases.

(Unfortunately, ATO is still stuck on Chapel 1.31, which is why my previous links weren't generating the warnings and why it took me until now to check my memory).

Best wishes,
-Brad

Hello Brad,

domain(1) fixed it and is self documenting.

Many thanks for taking the time to provide a full explanation. I should have read the docs more attentively.

Cheers,
Roger

1 Like

Hi Roger —

Glad you were able to get unblocked. No need to apologize for missing this—the docs are not always as nice as we'd like them to be and there are a lot of them.

-Brad