chapel icon indicating copy to clipboard operation
chapel copied to clipboard

[Bug]: Cannot min reduce between arrays

Open mppf opened this issue 7 months ago • 1 comments

Summary of Problem

Description: I'd like to min reduce arrays of integers (so that the result is an array of minimums in each position). I am led to think this is possible because I can + reduce arrays to get an array of totals in each position.

Additionally, my attempt to define a custom reduction for this does not work, because the result is always an array of 0s.

Is this issue currently blocking your progress? No

Steps to Reproduce

Source Code:

var TupA = ([2, 3, 9, 1, 7, 4],
            [4, 2, 2, 9, 2, 4],
            [0, 5, 8, 3, 6, 1]);
var Expect= [0, 2, 2, 1, 2, 1];

var State:[TupA[0].domain] int = max(int);

//forall i in 0..<TupA.size with (min reduce State) { 
//   error: 'max(type t)' is not defined for t=[domain(1,int(64),one)] int(64)

forall i in 0..<TupA.size with (ArrayMinReduceOp reduce State) {
  State reduce= TupA[i];
}

writeln(State);

assert(&& reduce (State == Expect));

class ArrayMinReduceOp: ReduceScanOp {
  /* the type of the elements to be reduced -- expecting [] int */
  type eltType;

  /* task-private accumulator/reduction state */
  var value: eltType;

  /* identity w.r.t. the reduction operation */
  proc identity {
    var ret: eltType;
    ret = max(ret.eltType);
    return ret;
  }

  /* accumulate a single element onto the accumulator */
  proc accumulate(elm)  {
    foreach (vElt, aElt) in zip(value, elm) {
      vElt = min(vElt, aElt);
    }
  }

  /* accumulate a single element onto the state */
  proc accumulateOntoState(ref state, elm)  {
    foreach (sElt, aElt) in zip(state, elm) {
      sElt = min(sElt, aElt);
    }
  }

  // Note: 'this' can be accessed by multiple calls to combine()
  // concurrently. The Chapel implementation serializes such calls
  // with a lock on 'this'.
  // 'other' will not be accessed concurrently.
  /* combine the accumulations in 'this' and 'other' */
  proc combine(other: borrowed ArrayMinReduceOp(?)) {
    foreach (vElt, aElt) in zip(value, other.value) {
      vElt = min(vElt, aElt);
    }
  }

  /* Convert the accumulation into the value of the reduction
     that is reported to the user. */
  proc generate()    do return value;

  /* produce a new instance of this class */
  proc clone()       do return new unmanaged ArrayMinReduceOp(eltType=eltType);
}

Associated Future Test(s): TODO

mppf avatar Jul 26 '24 22:07 mppf