Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
    Sayan-Chaudhuri
    @Sayan-Chaudhuri
    I would like to know why the Chapel backend was written in C and not C++. With C++ we can also leverage the power of C as well as enjoy new features which can come handy.
    4 replies
    rupipal
    @rupipal
    Hi

    I'm trying to install Chapel on Linux Debian 11 following this https://chapel-lang.org/docs/usingchapel/building.html#using-chapel-in-other-sessions LLVM -11 seems to be properly installed. However, I get this, make
    Making the compiler...

    Error: CHPL_LLVM=system but could not find an installed LLVM with one of the supported versions: 11
    /home/rupinder/Downloads/chapel-1.25.0/make/Makefile.base:102: error running util/printchplenv -- please see error above. Stop.
    make[1]:
    [Makefile:79: compiler] Error 2
    make: * [Makefile:59: comprt] Error 2

    22 replies
    rupipal
    @rupipal
    Hi that got fixed with CHPL_LLVM=bundled And the build seems to have completed successfully (took long). Intially, I'd only set --chpl-home=~/programs/chapel So, when the build completed with make and it tried to install as well, but unsuccessfully, I realized that the prefix is mandatory and duly wrote it in the configured-prefix file. And tried intall with make install, I have Making the compiler...
    make[2]: Nothing to be done for 'llvm'.
    * adt/ *
    * AST/ *
    * backend/ *
    * codegen/ *
    g++ -c -MMD -MP -O3 -I. -I../include/linux64 -I../include -I/home/rupinder/Downloads/chapel-1.25.0/third-party/llvm/install/linux64-x86_64-gnu/include -I../../build/compiler/linux64/gnu/x86_64/llvm-bundled/none -I../../runtime/include/encoding -I/home/rupinder/Downloads/chapel-1.25.0/third-party/utf8-decoder -I../next/include -DHAVE_LLVM -Wno-comment -DCOMPILER_SUBDIR=codegen -o ../../build/compiler/linux64/gnu/x86_64/llvm-bundled/none/codegen/cg-expr.o cg-expr.cpp
    cg-expr.cpp:46:10: fatal error: clang/CodeGen/CGFunctionInfo.h: No such file or directory
    46 | #include "clang/CodeGen/CGFunctionInfo.h"
    | ^~~~~~~~
    compilation terminated.
    make[3]: [../make/Makefile.compiler.foot:55: ../../build/compiler/linux64/gnu/x86_64/llvm-bundled/none/codegen/cg-expr.o] Error 1
    make[2]:
    [make/Makefile.compiler.foot:29: codegen.makedir] Error 2
    make[1]: [Makefile:80: compiler] Error 2
    make:
    [Makefile:59: comprt] Error 2
    8 replies
    Audrey MP
    @astatide
    Long time no see, Chaplains! Question(s) for you for an little project I'm working on: does the linear algebra module support operations on distributed arrays? I want to make use of... basically just the dot operation and some other stuff and It Seems Better to use the linear algebra module that exists rather than roll my own. But I want to seamlessly support switching my underlying data structures for the vectors/matrices from in-record arrays to slices of a distributed array (that way, I can still manipulate them at a high level but take advantage of much larger data sets if possible). My linalg needs are pretty simple; the most complex operation I'm doing is applying a rotation matrix, for instance, so I mostly just need the dot product.
    Audrey MP
    @astatide
    Having said that, I had already implemented a wrapper around basic array operations and was juuuust wondering how to properly vectorize the dot product between a matrix and a vector (if at all possible, to take advantage of any sort of under the hood compiler optimization that may be available; for instance, there's a one or two order of magnitude time difference between adding +1 to an array in a forall loop vs doing it as array[0..n] += 1, which I'm guessing is compiler/CPU related) before I even stumbled on the documentation for the linearAlgebra module (and genuinely wondered how I'd missed it before).
    Audrey MP
    @astatide
    Oh, since... they're just wrappers around the basic array functionality, I can just lazily steal the dot() function and run it. Ignore me.
    Brad Chamberlain
    @bradcray
    Easiest customer support case of the day! :D
    (Hi Audrey!)
    Audrey MP
    @astatide
    :D Hi Brad!
    If it makes you feel any better, I'll have questions regarding the optimal use of records in a multinode setup in a bit (whenever I get around to that part of the project) which might be more fun and less self answering.
    Audrey MP
    @astatide
    Related question: is there a way to overload an access operator? Such that if I have a record V, I can write a function so that V[i] is valid in some context?
    I feel like I'm being Very Bad at searching for the proper terms
    aha! Got it. Had to search for "indexing", not just index, then nab the clue from the "expressions" page about how indexing is done via an implicit call to a this method on the array. Right, I think I did this before, which is why I thought I could. For posterity, defining a V.this method worked.
    Tom Westerhout
    @twesterhout:matrix.org
    [m]

    Is there a way to declare an array of arrays instead of a 2D array? For example, I can do the following:

    var chunks = [
      [1, 2],
      [3, 4, 5],
      [6]
    ]

    and it works. But what is the type of chunks? E.g. the following does not work:

    var D1 : domain(1);
    var D2 : domain(1);
    var chunks : [D1] [D2] int = [
      [1, 2],
      [3, 4, 5],
      [6]
    ]

    So what's the proper syntax for the type in this case?

    1 reply
    Tom Westerhout
    @twesterhout:matrix.org
    [m]

    And another question. Suppose, I have a generic class like this:

    record Chunk {
      type eltType;
      var D: domain(1);
      var data: [D] eltType;
    
      proc init(array: [?X] ?t) {
        this.eltType = t;
        this.D = X;
        this.data = array;
      }
    }

    and I try to initialize it from an array:

    var x = new Chunk([1, 2, 3]);

    this fails with the following error:

    error: unresolved call 'Chunk.init(eltType=type int(64))'
    note: this candidate did not match: Chunk.init(array: [?X] ?t)
    note: because call uses named argument eltType
    note: but function contains no formal named eltType

    Through trial and error I figured that if I add another constructor:

    proc init(type eltType) {
      this.eltType = eltType;
    }

    it all magically starts to compile.
    Could someone, please, explain what's going on here? I'm confused...

    2 replies
    rjj
    @rjjesus:matrix.org
    [m]

    Hi all, I might be missing something very simple, but how can I have two arrays with different domains (same overall size, but possibly different dimensions) alias the same data? I.e., in C I could do something like

    #include <stdio.h>
    
    
    int main(void)
    {
      int a[10];
    
      int (*b)[5] = (int (*)[5])a;  // `b' aliases `a' as int [2][5]
      int (*c)[2] = (int (*)[2])a;  // `c' aliases `a' as int [5][2]
    
      for(int i = 0, k = 1; i < 2; i++)
        for(int j = 0; j < 5; j++, k++)
          b[i][j] = k;
    
      for(int i = 0, k = 1; i < 5; i++)
        for(int j = 0; j < 2; j++, k++)
          if(c[i][j] != k)
            puts("data does not match!");
    }

    is something similar to this possible in Chapel?

    4 replies
    Audrey MP
    @astatide
    Day 3, question 3: on namespaces. Is it yet possible to define a submodule outside of a main module? Particularly so that I can access it from other modules? Example:
    Say I have module A and a, defined in their own files. I wish to have a be available as a submodule within A so that I can access it as something like A.a from other code. I saw there's been a little discussion about something like this; does it exist yet?
    6 replies
    Tom Westerhout
    @twesterhout:matrix.org
    [m]

    Which environment variables does one have to set to enable PMI support in GASNet? If I set GASNET_IBV_SPAWNER=pmi (CHPL_COMM_SUBSTRATE is set to ibv), I get the following error message when trying to run the app:

    *** FATAL ERROR (int1.local.snellius.surf.nl:4144541): in gasneti_spawnerInit() at -1.25.0/third-party/gasnet/gasnet-src/gasnet_internal.c:2070: Requested spawner "PMI" is unknown or not supported in this build
    WARNING: Ignoring call to gasneti_print_backtrace_ifenabled before gasneti_backtrace_init

    So I should set some env variables and the recompile Chapel, but I can't quite figure out which...

    2 replies
    Ricardo Jesus
    @rjjesus:matrix.org
    [m]

    @bradcray: Thanks for the thorough explanation. In the end, I ended up doing something like this

    proc f() {
      var a: [0..<10] int = 0;
    
      inline proc b(i, j) ref return a[i*5+j];
    
      inline proc c(i, j) ref return a[i*2+j];
    
      var k = 1;
    
      for i in 0..<2 {
        for j in 0..<5 {
          b[i, j] = k;
          k += 1;
        }
      }
    
      k = 1;
    
      for i in 0..<5 {
        for j in 0..<2 {
          if c[i, j] != k then
            writeln("data does not match!");
          k += 1;
        }
      }
    }
    
    f();

    (i.e., using procedures to do the index arithmetic, creating ``fake views'' over the underlying data). It's not ideal but it works for me

    1 reply
    Ricardo Jesus
    @rjjesus:matrix.org
    [m]

    :point_up: Edit: @bradcray: Thanks for the thorough explanation. I ended up doing something like this

    proc f() {
      var a: [0..<10] int = 0;
    
      inline proc b(i, j) ref return a[i*5+j];
    
      inline proc c(i, j) ref return a[i*2+j];
    
      var k = 1;
    
      for i in 0..<2 {
        for j in 0..<5 {
          b[i, j] = k;
          k += 1;
        }
      }
    
      k = 1;
    
      for i in 0..<5 {
        for j in 0..<2 {
          if c[i, j] != k then
            writeln("data does not match!");
          k += 1;
        }
      }
    }
    
    f();

    (i.e., using procedures to do the index arithmetic, creating ``fake views'' over the underlying data). It's not ideal but it works for me

    Audrey MP
    @astatide
    Hello hello hello! "Oh, it's been a minute or two since Audrey asked a question she ends up answering herself later"; well, do I have news for you! So, I have a high level API in which I'm loading and storing vector-like data (for a 3 dimensional system, so real arrays of shape) on a record. This record is then stored in another record, which is then stored in a class. That class is then stored on an "integrator" type class, which does the dirty work of iterating through the records to get to the vector data, perform some operation, then update the vector on the record. tl;dr:
    record vector {
      var data: [real] = [0,0,0];
    }
    
    record inner {
      var vec1: vector;
      var vec2: vector;
    }
    
    record outer {
      var vecList: list(inner);
    }
    
    class OuterClass {
      var outerList: list(outer);
    }
    
    proc AddToVectors(a: vector) {
      a.data += 0.1;
    }
    
    proc integrate(sys: OuterClass) {
      for outer in sys.outerList {
        for inner in outer.vecList {
          AddToVectors(inner.vec1);
        }
      }
    }
    Audrey MP
    @astatide

    Now there's nothing stopping me from taking all the vectors that exist in inner records on outer records in the OuterClass object, storing them into an array of vectors, and then performing calculations on the vectors in that array, only updating the vectors in the inner records as necessary (for reporting or updating the master state of the system or whatever) if that provides a speed bump, and indeed, it's what I thought I might need to do (and am happy to do so!). My question is twofold-ish:

    1. Will there be any speed difference for a single node/locale run iterating through the array of vectors (or, if necessary, a [0..n,3] real array, going even lower level) vs. iterating through the vectors in the inners on the outers?
    2. If there is, is that due to the scattered nature of where the data is stored or because I'm likely to hit some sort of weird copy operations for the data due to the sort of class.record[..].record[..].vector data stack I have going on? Is there a way to mitigate this?

    I want to use a high level API as much as possible to keep things easy to read for people who aren't programmers OR super well versed in what I'm doing; I'm also going to be creating at least three integrator types: one that is Stupidly Serial and just does nothing clever and doesn't try to be parallel in any way, one that is single-node/locale but takes advantage of as many clever speed routines as possible, and one that is explicitly multi-node/locale and attempts to utilize parallel processing to maximize the amount of calculations that can be done (potentially sacrificing on-node calculation speed if it allows me to more trivially swap which node is doing calculations on a given set of vectors between integrator iterations). So given that,

    1. For Very Fucking Large OuterClass objects, defined as many many many outer records that each have many many many many inner records, would it be more performant to utilize the 'high level' API of the record structure, or would it behoove me to break all the vectors into a distributed array (or individual, on-node/locale arrays) and perform the operations then? Ignore, for a minute, any sync problems; assume that if I am able to send one set of outer records to locale A and another set to locale B that they're independent and don't care about each other.
    (This is not a work related project in any way but my code isn't yet ready to be public as I haven't finalized a lot of the structure around this sort of stuff and blah blah blah but it IS getting to where I'll make the code public and can just blankly share it).
    Audrey MP
    @astatide
    would it be more performant to utilize the 'high level' API of the record structure, or would it behoove me to break all the vectors into... <--- when I say 'more performant', in this case I mean if I have to swap which node/locale is performing operations on that vector.
    Brad Chamberlain
    @bradcray

    Hi Audrey — I’m just wise enough to know better than to try and predict what will perform better or worse, because there are enough variables between the architecture, back-end compiler, and Chapel itself for it to be a good bet to make. I think you are correct that memory layout is likely to make a bigger difference than your object structure based on my understanding of what you’re describing. Specifically, using records means using an “in-place” data structure, so you won’t chase pointers to get at nested records or anything like that. Records can be copied around for operations like assignments, but if you’re just traversing a data structure built up of records, or passing that data structure around, there shouldn’t be any real problem that I can anticipate.

    If your vectors really are as small as three elements, I’d strongly suggest representing them as tuples instead (e.g., 3*real) because those will also give you an “in-place” data structure rather than doing a ton of small allocations on the heap, and Chapel’s array machinery is heavyweight enough that I believe it’ll add more overhead than benefit.

    I think you’ll also run into challenges when you go to multi-locale because the lists are necessarily single-locale and 3-element vectors are too small to distribute, so I anticipate that you’re going to want to change your lists at one level into arrays, and if they’re all different sizes, a classic pattern for doing this is to store the array and its domain as fields of your records/classes.

    Back on memory layout: Since tuples are allocated “in-place”, an impact is that is that an array of tuples will essentially create a dense buffer of tuples, so imagine [[t00 t01 t02] [t10 t11 t12] [t20 t21 t22]] laid out densely in memory. In contrast, an array of arrays will be more like an array whose buffer contains array descriptors, each of which points off to a separate buffer representing that array’s elements. So this may cause you to lean one way or the other in the decision about arrays of arrays (or arrays of lists) vs. 2D arrays. If you only want to distribute one of those levels in the hierarchy, I’d be inclined to use an array of arrays of tuples because I think it’ll more clearly delineate (to the compiler, to the reader) where things are local and where they are distributed.

    Hope these are helpful tips.

    7 replies
    Audrey MP
    @astatide
    Brad, thank you for that. Can't emphasize enough how helpful it is, particularly since 'understandability' is a major goal, in that it is primarily an educational tool, and a research tool second. So I'm fine with making explicit conversions into data types/structures that are more performant if/when necessary, but only very explicitly, only at the last minute, as necessary, and only when very clearly stated. So any data structure that lends itself well to being easy to delineate and understand is perfect.
    Oliver Alvarado Rodriguez
    @alvaradoo

    Hi all! I am currently building Chapel 1.25.0 on my Macbook Pro. And am running into the following error:

    ld: library not found for -llibxml2.tbd
    clang: error: linker command failed with exit code 1 (use -v to see invocation)
    make[2]: *** [/Users/alvaradoo/Research/chapel-1.25.0/bin/darwin-x86_64/chpl] Error 1
    make[1]: *** [compiler] Error 2
    make: *** [comprt] Error 2

    I tried searching for some fixes online, but have had no luck. I was hoping some other Macbook users could shed some light on how I can properly link or find this missing library. Thanks!

    Paul Cassella
    @cassella

    @alvaradoo I see this block in third-party/llvm/Makefile.include-bundled

    # remove -llibxml2.tbd which seems to appear on some Mac OS X versions
    # with LLVM 11.
    export LLVM_LLVM_LIBS=$(subst -llibxml2.tbd,,$(LLVM_LLVM_LIBS_TMP))

    Are you building with bundled llvm?

    Raghav Sharma
    @Mashijams
    @alvaradoo I guess issue is with chapel unable to find llvm compiler or something with command line tools installed on your Mac.
    Refer this issue : chapel-lang/chapel#18600 and see if it helps :)
    Oliver Alvarado Rodriguez
    @alvaradoo
    @cassella Yes, I am building with bundled llvm. Would I need to modify this file? @Mashijams I will take a look at this as well! Thank you to both of you :)
    9 replies
    Ricardo Jesus
    @rjjesus:matrix.org
    [m]

    @bradcray: Hi Brad, I thought I was quite happy with my previous solution---despite being a bit rudimentary, the fact that the notation resembled actual array notation made me feel OK with it. But after your message I decided to try to prototype a simple class to abstract the array view in a slightly more general way, which led me to this

    class SimpleArrayView {
      param rank;
      const shape;
      const arr;
      const dom;
    
      proc init(arr, shape) where isRectangularArr(arr) && arr.rank == 1 {
        const size = * reduce shape;
    
        if arr.size < size then
          halt("number of elements in the new shape " +
               "cannot exceed the size of the array");
    
        this.rank = shape.size;
        this.shape = shape;
        this.arr = arr._value;
    
        var dims: rank*range;
        for param i in 0..<rank do dims[i] = 0..<shape[i];
        this.dom = {(...dims)};
      }
    
      pragma "reference to const when const this"
      inline proc ref this(args: int ...rank) ref {
        var idx = 0;
        for param i in 0..#rank-1 do idx = (idx+args[i])*shape[i+1];
        idx += args[rank-1];
    
        return arr.dsiAccess(idx);
      }
    
      override proc writeThis(f) throws {
        //var tmpArr: [dom] arr.eltType;
        //for (i, x) in zip(0..<dom.size, tmpArr) do x = arr.dsiAccess(i);
        //f.write(tmpArr);
    
        f <~> shape <~> ": ";
        arr.dsiSerialWrite(f);
      }
    }

    It's not as general as your createReshapedArrayView (e.g. for simplicity I only create views over 1D arrays, and I fix the view's domain to be a "C-like domain", starting at 0 with stride 1), but it does seem to work for my simple case:

    proc g() {
      var a: [0..<12] int = 0;
    
      var b = new SimpleArrayView(a, (2, 6));
      const c = new SimpleArrayView(a, (6, 2));
    
      var k = 1;
    
      for i in 0..<2 {
        for j in 0..<6 {
          b[i, j] = k;
          k += 1;
        }
      }
    
      k = 1;
    
      for i in 0..<6 {
        for j in 0..<2 {
          if c[i, j] != k then
            writeln("data does not match!");
          k += 1;
        }
      }
    
      const d = new SimpleArrayView(a, (2, 2, 3));
    
      for (l, (i, j, k)) in zip(1..12, d.dom) do
        if d[i, j, k] != l then
          writeln("data does not match!");
    
      writeln(a);
      writeln(b);
      writeln(c);
      writeln(d);
    }
    
    g();

    Do you see anything blatantly wrong with this approach?

    Ricardo Jesus
    @rjjesus:matrix.org
    [m]

    :point_up: Edit: @bradcray: Hi Brad, I thought I was quite happy with my previous solution---despite being a bit rudimentary, the fact that the notation resembled actual array notation made me feel OK with it. But after your message I decided to try to prototype a simple class to abstract the array view in a slightly more general way, which led me to this

    class SimpleArrayView {
      param rank;
      const shape;
      const arr;
      const dom;
    
      proc init(arr, shape) where isRectangularArr(arr) && arr.rank == 1 {
        const size = * reduce shape;
    
        if arr.size < size then
          halt("number of elements in the view must not " +
               "exceed the size of the underlying array");
    
        this.rank = shape.size;
        this.shape = shape;
        this.arr = arr._value;
    
        var dims: rank*range;
        for param i in 0..<rank do dims[i] = 0..<shape[i];
        this.dom = {(...dims)};
      }
    
      pragma "reference to const when const this"
      inline proc ref this(args: int ...rank) ref {
        var idx = 0;
        for param i in 0..#rank-1 do idx = (idx+args[i])*shape[i+1];
        idx += args[rank-1];
    
        return arr.dsiAccess(idx);
      }
    
      override proc writeThis(f) throws {
        //var tmpArr: [dom] arr.eltType;
        //for (i, x) in zip(0..<dom.size, tmpArr) do x = arr.dsiAccess(i);
        //f.write(tmpArr);
    
        f <~> shape <~> ": ";
        arr.dsiSerialWrite(f);
      }
    }

    It's not as general as your createReshapedArrayView (e.g. for simplicity I only create views over 1D arrays, and I fix the view's domain to be a "C-like domain", starting at 0 with stride 1), but it does seem to work for my simple case:

    proc g() {
      var a: [0..<12] int = 0;
    
      var b = new SimpleArrayView(a, (2, 6));
      const c = new SimpleArrayView(a, (6, 2));
    
      var k = 1;
    
      for i in 0..<2 {
        for j in 0..<6 {
          b[i, j] = k;
          k += 1;
        }
      }
    
      k = 1;
    
      for i in 0..<6 {
        for j in 0..<2 {
          if c[i, j] != k then
            writeln("data does not match!");
          k += 1;
        }
      }
    
      const d = new SimpleArrayView(a, (2, 2, 3));
    
      for (l, (i, j, k)) in zip(1..12, d.dom) do
        if d[i, j, k] != l then
          writeln("data does not match!");
    
      writeln(a);
      writeln(b);
      writeln(c);
      writeln(d);
    }
    
    g();

    Do you see anything blatantly wrong with this approach?

    1 reply
    Oliver Alvarado Rodriguez
    @alvaradoo
    Also, this might be a silly question, but what is the difference between using llvm bundled and llvm system?
    Brad Chamberlain
    @bradcray
    @alvaradoo — If they’re the identical version, there’s no significant difference. The main reason to choose system would be to avoid the time required to build the bundled version. The main reason we supply bundled is for users who don’t have the ability to install an appropriate system version (due to permissions issues, which versions are supported on their system, etc.). Let us know if you were asking something more than that.
    1 reply
    Ricardo Jesus
    @rjjesus:matrix.org
    [m]
    @bradcray: Hi Brad, thank you very much for your feedback! I think the solution I have right now is good enough for me, but if I stumble upon some new use case that I struggle to implement I'll let you know
    Audrey MP
    @astatide

    Question! What is the current State of (the) Union data type? In addition, say that I want to create sets of pairwise functions where each function may have different parameters and/or a different method they're applying. Currently, I'm using classes (with a 'calculate' function) and I simply subclass / cast to the parent class as necessary. So:

    record A {
      var data: real = 0;
    }
    
    class functionWrapper {
      var setOfParameters: list(real);
      func calculate(a: A, b: A): A {
        return new A()
      }
    }
    
    class add: functionWrapper {
      override func calculate(a: A, b: A) {
        var rA = new A();
        rA.data = setOfParameters[0]*(a.data+b.data);
        return rA;
      }
    }
    
    func callFunction(calc: functionWrapper) {
      return calc(new A(), new B());
    }
    
    callFunction(add: functionWrapper)

    Another subclass of functionWrapper may have more than one parameter (hence the list) but they're (probably) always going to have the same signature (take in two of the same type of record, return a new one), and any given instance of add may have different values for setOfParameters as appropriate.

    This feels like a weird way to do it and I'm wondering if it's really Best; ultimately, I want to store whole sets of functions inside a hash table and pull them out as appropriate. I see that Chapel has some initial support for first-class functions; is it to the point where I can store them in an associative array AND is it efficient? In addition, is the above method less efficient? I feel like having to treat these functions as objects/classes means I bring in more overheard with memory management / borrowing / owning etc, but I'm not totally sure.

    Audrey MP
    @astatide
    So I guess the alternate would be:
    func add(a: A, b: B, setOfParameters: list(real)) {
        var rA = new A();
        rA.data = setOfParameters[0]*(a.data+b.data);
        return rA;
    }
    
    func callFunction(calc: func(A, A, list(real)) ) {
      return calc(new A(), new A(), new list([1]));
    }
    
    callFunction(add);
    Audrey MP
    @astatide

    I'd prefer something much more... functional programming like, where instead, I do something ala...

    func addFuncGenerator(i: real) {
      return lambda(a: A, b: B) { return i*(A.data+B.data); };
    }
    
    var funcSet: list(func(A, A));
    
    for i in 1..12 {
      funcSet.append(addFuncGenerator(i));
    }

    then simply utilize the list. Is that... doable?

    David Longnecker
    @dlongnecke-cray

    Hi Audrey, your approach above looks like the best one to take. Chapel doesn't support closures (yet), so there's no way to preserve that non-local variable "setOfParameters" and carry it around. Additionally, the current first-class-function (FCF) support does not work with generic types. FWIW, your functionWrapper class has about the same overhead as FCFs have today (they are implemented with classes internally). It might be possible to adopt an implementation in the future that reduces this overhead, but we're not there yet.

    I agree with you that ideally our first-class-function story should be able to support generators.

    2 replies
    Tom Westerhout
    @twesterhout:matrix.org
    [m]

    How does one specify types of 2D array arguments to functions?

    E.g. this works:

    proc foo(const ref xs) { ... }

    However, none of the following do:

    proc foo(const ref xs: [?D] uint) { ... } // this assumes xs is 1D
    proc foo(const ref xs: [?D1] [?D2] uint) { ... } // complains about query expressions not being supported in this context
    proc foo(const ref xs: [] [] uint) { ... } // complains about arguments being nil
    proc foo(const ref xs: [?D] [] uint) { ... } // same
    Lydia Duncan
    @lydia-duncan
    The three bottom ones are specifying arrays of arrays. I think what you want is the first one with a where clause that checks that the rank of the domain is 2?
    1 reply
    Tom Westerhout
    @twesterhout:matrix.org
    [m]

    A performance question: I have the following two lines:

      const D = {0 .. ranges.size - 1} dmapped Cyclic(startIdx=0);
      var chunks: [D] [LocaleSpace] list(uint(64));

    and for some reason they take more than 12 seconds to execute with 2 locales emulated on my laptop. ranges.size == 822. I must be doing something wrong, right?

    Oh yeah, and I've also set CHPL_RT_NUM_THREADS_PER_LOCALE=1
    Tom Westerhout
    @twesterhout:matrix.org
    [m]

    And related. In another part of my code I have the following:

      var ranges: list((uint(64), uint(64)));
      // building ranges on locale 0
      var distRanges = newCyclicArr({0.. ranges.size - 1}, (uint(64), uint(64)));
      distRanges = ranges;

    and again, the last two lines take ~0.15 s on two locales and less than a millisecond on one locale

    Brad Chamberlain
    @bradcray
    @twesterhout:matrix.org : Do you already have CHPL_RT_OVERSUBSCRIBED=yes set in your environment? If not, will you see what effect that has (no need to recompile, just re-run).
    6 replies
    Tom Westerhout
    @twesterhout:matrix.org
    [m]
    Okay, another question :) How does one profile Chapel programs? Using chplvis or are there other tools?
    2 replies
    Brad Chamberlain
    @bradcray
    There aren’t any great off-the-shelf solutions here. chplvis is useful for what it’s designed to do, but for many people doesn’t fill the need in terms of what they’d want for a gprof-like equivalent. I know some people have had some luck using standard HPC-ready profiling tools (like HPC Toolkit from Rice) with Chapel’s generated C code but don’t personally know best practices there. On our team, we mostly do things by instrumenting the code with timers to figure out where time is being spent. This is a place where we’d like a better solution, but haven’t had the time/resources to invest in it ourselves.
    1 reply
    Tom Westerhout
    @twesterhout:matrix.org
    [m]

    Compiling chplvis fails with the following error:

    MenuManager.cxx: In member function ‘void MenuManager::makeLocaleMenu()’:
    MenuManager.cxx:26:19: error: invalid ‘static_cast’ from type ‘std::__cxx11::basic_ostringstream<char>’ to type ‘std::ostringstream&’ {aka ‘std::__cxx11::basic_ostringstream<char>&’}
       26 | #define SSTR( x ) dynamic_cast< std::ostringstream & >( \
          |                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
       27 |                     ( std::ostringstream() << std::dec << x ) ).str()
          |                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    MenuManager.cxx:318:41: note: in expansion of macro ‘SSTR’
      318 |     std::string entryName = "Locale/" + SSTR(ix);
          |                                         ^~~~
    MenuManager.cxx: In member function ‘void MenuManager::makeTagsMenu()’:
    MenuManager.cxx:26:19: error: invalid ‘static_cast’ from type ‘std::__cxx11::basic_ostringstream<char>’ to type ‘std::ostringstream&’ {aka ‘std::__cxx11::basic_ostringstream<char>&’}
       26 | #define SSTR( x ) dynamic_cast< std::ostringstream & >( \
          |                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
       27 |                     ( std::ostringstream() << std::dec << x ) ).str()
          |                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    MenuManager.cxx:400:34: note: in expansion of macro ‘SSTR’
      400 |         menuName = "Tags/tag " + SSTR(ix) + " (" + tagName + ")";
          |                                  ^~~~
    make[1]: *** [Makefile:40: MenuManager.o] Error 1

    It doesn't look like something caused by a particular setup, but just a compilation error

    3 replies
    Yash Raj
    @tiger-yash
    Hey!
    I am beginning to familiarise and contribute to chapel, but even after proper set-up, on running start_test I am getting the following error :
    $CHPL_HOME/modules/standard/GMP.chpl:1330: error: Cannot use GMP with CHPL_GMP=none
    Please help!
    5 replies
    Brad Chamberlain
    @bradcray
    :+1: