@@ -653,4 +653,100 @@ module ConcatenateMsg
653653 return new MsgTuple(repMsg, MsgType.NORMAL);
654654 }
655655 registerFunction(" concatenateUniquely" , concatenateUniqueStrMsg, getModuleName());
656+
657+ proc concatenateUniqueStrMsg2 (cmd: string , msgArgs: borrowed MessageArgs, st: borrowed SymTab): MsgTuple throws {
658+ param pn = Reflection.getRoutineName();
659+
660+ var repMsg: string ;
661+ var names = msgArgs.get(" names" ).toScalarList(string );
662+ var n = names.size;
663+
664+
665+ cmLogger.debug(getModuleName(), getRoutineName(), getLineNumber(),
666+ " concatenate unique strings from %i arrays: %?" .format(n, names));
667+
668+ // Each locale gets its own set
669+ var localeSets = makeDistArray(numLocales , set(string ));
670+
671+ // Initialize sets
672+ coforall loc in Locales do on loc {
673+ localeSets[ here .id] = new set(string );
674+ }
675+
676+ var stringsInLocale: [ PrivateSpace] innerArray(string );
677+
678+ // Collect all unique strings from each input SegmentedString
679+ for i in 0 ..#names.size {
680+ var rawName = names[ i] ;
681+ var (strName, _) = rawName.splitMsgToTuple(' +' , 2 );
682+ try {
683+ var segString = getSegString(strName, st);
684+ cmLogger.debug(getModuleName(), getRoutineName(), getLineNumber(),
685+ " Processing SegString: %s " .format(strName));
686+
687+ // Grab the strings by locale and throw them in the sets.
688+ var stringArrays = balancedSegStringRetrieval(segString);
689+ coforall loc in Locales do on loc {
690+ ref myStrings = stringArrays[ here .id] .Arr;
691+ var locSet = new set(string );
692+
693+ // Reduce to unique strings within this locale
694+ forall str in myStrings with (+ reduce locSet) {
695+ locSet.add(str);
696+ }
697+
698+ // Throw it in my locale's set
699+ localeSets[ here .id] |= locSet;
700+
701+ // Convert to innerArray
702+ if i == names.size - 1 {
703+ stringsInLocale[ here .id] = new innerArray({0 ..#localeSets[ here .id] .size}, string );
704+ stringsInLocale[ here .id] .Arr = localeSets[ here .id] .toArray();
705+ }
706+ }
707+
708+ } catch e: Error {
709+ throw getErrorWithContext(
710+ msg= " lookup for %s failed" .format(rawName),
711+ lineNumber= getLineNumber(),
712+ routineName= getRoutineName(),
713+ moduleName= getModuleName(),
714+ errorClass= " UnknownSymbolError" );
715+ }
716+ }
717+
718+ // Repartition the strings by their hash
719+ var distributedStrings = repartitionByHashArray(string , stringsInLocale);
720+
721+ coforall loc in Locales do on loc {
722+
723+ ref myStrings = distributedStrings[ here .id] .Arr;
724+ var strSet = new set(string );
725+
726+ // Perform another reduction by uniqueness on the strings in this set
727+ forall str in myStrings with (+ reduce strSet) {
728+ strSet.add(str);
729+ }
730+
731+ // This is maybe a little unusual. I tried just overwriting myStrings directly
732+ // But I think that caused some memory error for some reason.
733+ // I think because the domain didn't match...?
734+ distributedStrings[ here .id] = new innerArray({0 ..#strSet.size}, string );
735+ ref myStrings2 = distributedStrings[ here .id] .Arr;
736+ myStrings2 = strSet.toArray();
737+
738+ }
739+
740+ // Convert back from innerArray(string) to SegString
741+ var retString = segStringFromInnerArray(distributedStrings, st);
742+
743+ // Store the result in the symbol table and return
744+ repMsg = " created " + st.attrib(retString.name) + " +created bytes.size %?" .format(retString.nBytes);
745+
746+ cmLogger.debug(getModuleName(), getRoutineName(), getLineNumber(),
747+ " Created unique concatenated SegmentedString: %s " .format(st.attrib(retString.name)));
748+
749+ return new MsgTuple(repMsg, MsgType.NORMAL);
750+ }
751+ registerFunction(" concatenateUniquely2" , concatenateUniqueStrMsg2, getModuleName());
656752}
0 commit comments