When attempting to reproduce a serialized domain, the function for reading/writing fails out during compilation with the following message:
$CHPL_HOME/modules/internal/DefaultAssociative.chpl:107: In function 'dsiSerialReadWrite':
$CHPL_HOME/modules/internal/DefaultAssociative.chpl:115: error: non-lvalue actual is passed to 'ref' formal 'x' of <~>
Source Code:
var c: channel(true,iokind.native,true);
var z: channel(false,iokind.native,true);
var lf = open('test.log' : string, iomode.cwr);
var seeds: domain(int);
var delta: [seeds] real;
var po: domain(int);
var pk: [po] real;
seeds.add(1);
delta[1] = 12;
c = lf.writer();
z = lf.reader();
c.write(seeds);
c.flush();
var l = z.read(po);
Compile command:
Execution command:
Associated Future Test(s):
chpl --version
:chpl version 1.19.0.2c1fa771fb
Copyright (c) 2004-2019, Cray Inc. (See LICENSE file for more details)
$CHPL_HOME/util/printchplenv --anonymize
:CHPL_TARGET_PLATFORM: darwin
CHPL_TARGET_COMPILER: clang
CHPL_TARGET_ARCH: x86_64
CHPL_TARGET_CPU: native
CHPL_LOCALE_MODEL: flat
CHPL_COMM: none
CHPL_TASKS: qthreads
CHPL_LAUNCHER: none
CHPL_TIMERS: generic
CHPL_UNWIND: none
CHPL_MEM: jemalloc
CHPL_ATOMICS: cstdlib
CHPL_GMP: gmp
CHPL_HWLOC: hwloc
CHPL_REGEXP: re2
CHPL_AUX_FILESYS: none
gcc --version
or clang --version
:Apple LLVM version 10.0.0 (clang-1000.11.45.5)
Target: x86_64-apple-darwin18.2.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
module list
:The cause of the error is pretty obvious looking at the code. I'm guessing a write routine was at some point naively turned into a readWrite routine without ever testing it:
for idx in this {
if first then
first = false;
else
f <~> new ioLiteral(", ");
f <~> idx;
The logic here is a bit busted: It's trying to iterate over the indices of the domain reading or writing them out. But of course, if you are reading them in, you can't iterate over them yet. Instead, it should presumably be reading an index, adding it to the domain, and repeating until it gets to the end of the domain.
I worked around this in my own code by setting a custom readThis and writeThis function for the record I'm passing through, as @bradcray suggested.
proc writeThis(f) {
f <~> new ioLiteral("{size: ") <~> this.seeds.size <~> new ioLiteral(" -- ");
var first = true;
for (s, c) in zip(this.seeds, this.delta) {
if first {
first = false;
} else {
f <~> new ioLiteral(", ");
}
f <~> new ioLiteral("(") <~> s <~> " : " <~> c <~> new ioLiteral(")");
}
f <~> new ioLiteral("}");
}
proc readThis(f) {
var size: int;
f <~> new ioLiteral("{size: ") <~> size <~> new ioLiteral(" -- ");
var first = true;
for i in 1..size {
if first {
first = false;
} else {
f <~> new ioLiteral(", ");
}
var s: int;
var c: real;
f <~> new ioLiteral("(") <~> s <~> new ioLiteral(" : ") <~> c <~> new ioLiteral(")");
this.seeds.add(s);
this.delta[s] = c;
}
f <~> new ioLiteral("}");
}
@ajoshpratt - if you are able to work from master, consider giving PR #13079 a try. It also enables binary I/O of these associative domains.