Chapel programming language | Peak developer hours are 0600-1700 PT (UTC-07/08) weekdays | Developer Resources: http://www.chapel-lang.org/developers.html
Hi there, I am new to chapel and I'm having some troubles installing mason. I did manage to build and install chapel (on WSL, ubuntu 21.04)
lferrant@LAPTOP-HGM2FD2S:~/IntervalAnalysis$ chpl --version
chpl version 1.26.0
built with LLVM version 13.0.0
Copyright 2020-2022 Hewlett Packard Enterprise Development LP
Copyright 2004-2019 Cray Inc.
(See LICENSE file for more details)
however when I do sudo make mason
from CHPL_HOME
I get in the end
Making the modules...
make[2]: Nothing to be done for 'default'.
cd tools/mason && make && make install
make[1]: Nothing to be done for 'default'.
make[1]: Nothing to be done for 'install'.
and nothing happens, no error message nor is mason installed. Any ideas what can cause this?
question about infinity (the floating point number), the docs has the following entry here
proc INFINITYparam:real(64)
it looked like a typo and indeed calling INFINITYparam()
or INFINITY()
failed (the latter with an internal compiler error, Internal errors indicate a bug in the Chapel compiler ("It's us, not you")
) . I was about to open a PR to update the docs entry to param INFINITY
but then I noticed that also NAN was written the same way here, so I'm not sure it's a typo anymore
Barriers
module to synchronize all locales? I have a distributed loop and need to ensure that all locales have completed initialization before proceeding further
AllLocalesBarriers
package module that’s optimized for the “single task per locale” case and would be the optimal, and probably simplest, way to do such a barrier if its contraints fit your needs. If not, the Barriers
module should be up to the task where the main difference is that it doesn’t make any assumptions about how many tasks or where they are running. Note that barriers tend to work better in coforall loops in Chapel than forall loops since they are blocking operations and forall loops don’t guarantee the number of tasks that will be running. They can be used in forall loops with a certain amount of heroic programming, but the result is typically code that is more brittle to changes in the number of tasks, iterator, iterand, etc. More commonly, I think when a forall loop needs a barrier, we just split it into two forall loops and rely on the loops’ fork-join semantics to get the equivalent.
apt
seems to be silently failing...
is it expected that I cannot print types? trying
var a = 1;
writeln(a.type);
produces
sanbox.chpl:8: error: unresolved call 'writeln(type int(64))'
$CHPL_HOME/modules/standard/ChapelIO.chpl:774: note: this candidate did not match: writeln(const args ...?n)
sanbox.chpl:8: note: because actual argument #1 is a type
$CHPL_HOME/modules/standard/ChapelIO.chpl:774: note: but is passed to non-type varargs formal 'args'
sanbox.chpl:8: note: other candidates are:
$CHPL_HOME/modules/standard/ChapelIO.chpl:780: note: writeln()
It seems a little strange because in the error message it does print the type
static inline double elapsed_time()
{
static _Thread_local struct timespec previous_time;
struct timespec current_time;
double tdiff;
if(clock_gettime(CLOCK_MONOTONIC, ¤t_time) != 0) handle_error("clock_gettime");
tdiff = (double)current_time.tv_sec-previous_time.tv_sec+1e-9*((double)current_time.tv_nsec-previous_time.tv_nsec);
previous_time = current_time;
return tdiff;
}
--library
flag) from within one application? E.g. say I generate libA.so and libB.so using the same version of Chapel compiler (and using the same environment), is it safe to dlload both libA.so and libB.so into one executable? and is this going to cause trouble like over-subscription?
.so
and all libraries make use of that. Based on my memory, I don’t think this has progressed beyond the “that would be a good idea” phase of design and discussion.
Hopefully this will make sense. I would like to define a type
in my code which includes the ClassName
and the memory management strategy owned
/shared
... something like:
type GenericValue = shared GenericValueClass;
type GenericList = shared GenericListClass(GenericValue);
// but the later I need a borrowed of the GenericList or the GenericValue type passed in or returned from a proc
that's where the error comes... so I would like to see the ability to have borrowed
potentially be used with owned
or shared
...
Make sense? otherwise I have to liter my code with owned
or shared
// this might turn into
proc foo(lst : borrowed GenericList) : borrowed GenericValue
{
//...
}
Good day everyone! Can someone help me understand why the following happens
record R {
var dom: domain(1);
var num: real;
var arr: [dom] real;
}
record S {
var num : real;
var num2 : real;
}
proc foo(a : real, b : real) {return new S(a, b);}
proc foo(val : real, grad : [?D] real) {return new R(D, val, grad);}
var a = foo(1.0, 2.0),
b = foo(1.0, [1.0, 2.0]);
writeln("a = ", a, " with type ", a.type : string);
writeln("b = ", b, " with type ", b.type : string);
var c = foo(1, 2), // here int implicitly converted to real
d = foo(1, [2, 3]); // something strange happens here.
writeln("c = ", c, " with type ", c.type : string);
writeln("d = ", d, " with type ", d.type : string);
produces the output
a = (num = 1.0, num2 = 2.0) with type S
b = (dom = {0..1}, num = 1.0, arr = 1.0 2.0) with type R
c = (num = 1.0, num2 = 2.0) with type S
d = (num = 1.0, num2 = 2.0) (num = 1.0, num2 = 3.0) with type [domain(1,int(64),false)] S
the first two variables a
and b
are the "trivial cases", everything goes as expected. Then things get interested, when I create c
, int
gets automatically converted to real
and the right record is contructed. Based on this, I would have expected a similar behavior for d
, but instead it seems that it automatically broadcasted the function call to each element of the array.
Hello everyone!
I faced a strange issue, reproduced in the following code:
proc main(): int
{
coforall loc in Locales do on loc {
coforall tid in 0..here.maxTaskPar-1 {
writeln("hello from task ", tid, " of locale ", loc.id);
while true {}
}
}
return 0;
}
I expect each thread of each locale to say hello to me before being infinitely blocked. However, only threads of locale 0 do this. As if the threads of other locales were not created. If I remove the while
statement, this is ok. If I add an explicit global barrier before the while
, that's also correct.
Can anyone explain me what's happening ?
Thank you in advance.
type
member attribute in a struct. How can I make such a struct on the Chapel side? (since type
is a keyword, extern record
isn't happy with it)
I'm running Chapel on a 2-socket AMD Epyc 7502. Each socket has 32 cores, i.e. 64 total, but for some reason qthreads only starts 32 shepherds and prints the following warning when I try to force 64 threads: "warning: QTHREADS: Reduced numThreadsPerLocale=64 to 32 to prevent oversubscription of the system."lscpu
shows the following:
CPU(s): 64
On-line CPU(s) list: 0-63
Thread(s) per core: 1
Core(s) per socket: 32
Socket(s): 2
NUMA node(s): 2
Do you have any suggestions how to debug this behavior?
var d: domain(1) = {0..19};
var arr: [d] int = 1;
// do something that would have the effect of having done 'var d: domain(1) dmapped Block(boundingBox={0..19}) = {0..19}' at the start instead to distribute array
// I want to do this but in a single 2d array rather than an array of arrays
var d: domain(1) dmapped Block(boundingBox={0..19}) = {0..19};
var arr: [d] [0..19] int;
If I have a distributed array such as:
const box = {0 ..# 20};
const dom = box dmapped Block(box, Locales);
var arr : [dom] int;
what would be the simplest way to get C pointers to all subDomains? I.e. I can do something like this:
arrPtrs : [0 ..# numLocales] c_ptr(int);
coforall loc in Locales do on loc {
arrPtrs[loc.id] = c_ptrTo(arr[arr.localSubdomain().low]);
}
but is there a better way that avoids remote task spawns?
Found a way, but it's relying on some implementation details...
var arrPtrs : [0 ..# numLocales] c_ptr(arr.eltType);
for loc in Locales do {
arrPtrs[loc.id] = arr.locArr[loc.id].myElems._value.data:c_void_ptr:c_ptr(arr.eltType);
}
This generates a few remote cache-get
s and get_nb
s, but no remote tasks are spawned, yay!
A question: what are the chances of RVO firing when returning a tuple? I.e. something like this
proc shouldRVO() {
var A : [1 .. 10] int;
const B = otherComputation();
return (A, B);
}
Is there a way to force A
to not be copied? I tried doing Memory.Initialization.moveToValue(A)
, but it gave me a segfault :/
A
and B
are local variables, they should logically be copied out since they’ll be de-allocated at the end of the routine. The compiler then might have a chance of optimizing the pattern by “stealing” the array memory back to the callsite rather than copying and de-allocating it, but I don’t happen to know offhand how well that works in the presence of tuples today. You could probably get a sense of how well or poorly this works by tracking the memory allocations across the call to see whether an array’s worth of value was allocated/deallocated? Or @mppf may happen to know (as he did most of the work on this optimization).
use Map;
record A {
param a: int;
}
class AbstractB {
proc getA(): A {
halt("Virtual Method");
return new A(1);
}
}
class B: AbstractB {
var class_a: A;
override proc getA(): A {
return this.class_a;
}
}
var m = new map(string, shared AbstractB);
m.add("t1", new shared B(new A(3)));
writeln(m.getValue("t1").getA());
So, in a function, I need to get an object of class B
and extract class A
from it. The abstract class is needed to be able to store it into a map. class A
unfortunately needs to have multiple param
fields in it. The getA
function will obviously error at compile with a conflicting return type error since A is a generic type and different values of a
will sort of be a new type in itself. How would I go about writing getA
so it returns appropriately?
This is not really a question or request, more of a grumble: I wanted to define a procedure over an array of tuples, where one of the tuple components is of a generic type. I believe this should be done as follows:
proc f(a: [] (?t, int)) { }
// example instantiation for tuple of (real, int)
var realArr = { (3.0, 1) };
f( realArr );
When I compile the above code with Chapel 1.27, I get an error message I can easily understand:
genericTupleArray.chpl:1: In function 'f':
genericTupleArray.chpl:1: error: Query expressions are not currently supported in this context
genericTupleArray.chpl:1: called as f(a: [domain(1,int(64),false)] (real(64),int(64)))
note: generic instantiations are underlined in the above callstack
However, if I actually try to refer to type t
anywhere in the procedure -- e.g. var big: max(t);
-- I get a more confusing compiler message:
genericTupleArray.chpl:1: In function 'f':
genericTupleArray.chpl:2: error: 't' used before defined
genericTupleArray.chpl:1: note: defined here
Obviously, the second compile error was the one I actually saw first, and it confused me for a long while until I deleted all uses of t
from the body of the procedure.
The first compiler message seems to suggest that query expressions may eventually be supported for arrays of composite type. Is there an open GitHub issue that relates to this feature?
I was going to suggest a workaround for this in case you hadn’t already found one, but am finding other reasons to grumble instead. Specifically, I wanted to be able to write:
proc f(a: [] ?et) where isTupleType(et) && et.size == 2 && et(1) == int {
type t = et(0);
}
but it looks as though this form of indexing into tuple types is not supported (or it’s too late for me to get the invocation right).