Я пишу часть программного обеспечения для параллельных вычислений.Программное обеспечение полностью универсально, и поэтому мне нужен класс для переноса последовательностей.
Прямо сейчас я испытываю странное поведение в моей карте-функции.Функция карты принимает в качестве входных данных объект-функцию, который может выводить тип, отличный от входного аргумента.
Взгляните на следующий код:
class SeqMPJ[T](indexedSeq: IndexedSeq[T]) {
val seq = indexedSeq.view //Lazy
val freeRanks = MPJEnv.getFreeRanks(seq.size)
//Get n free ranks
val commGroup = MPI.COMM_WORLD.group.Incl(freeRanks.toArray)
//Communicator for this sequence
val comm = MPI.COMM_WORLD.Create(commGroup)
val opIndex = globalRank % seq.size
var operand: Any = seq(opIndex)
if (!isOnline)
error("Cannot use MPJ-abstractions outside parallelize body...")
//Only works for p=n now
def mapMPJ[U](f: (T) => U): SeqMPJView[U] = {
if (freeRanks.contains(globalRank)) { //Process is part of this operation
operand = f(operand.asInstanceOf[T])
}
return new SeqMPJView(operand.asInstanceOf[U], comm, freeRanks)
}
...
Обратите внимание, что в функции mapMPJ[U](f: (T) => U):SeqMPJView[U]
функция f имеет тип ввода T и тип вывода U. Это означает, что после применения f к переменной «операнд» операнд имеет тип U, однако это происходит внутриесли-блок.Другими словами, в зависимости от состояния, операнд имеет тип U или T. Теперь, когда я приводил к U, это всегда успешно.Даже когда условие в блоке if не выполняется.Насколько я понимаю, программа должна завершиться с ошибкой при приведении operand.asInstanceOf [U], если программа не входит в блок if.
Пример использования в этом умножении матрицы:
val M = 2
val N = 2
val A = Array(
Array(1.0, 2.0),
Array(3.0, 4.0))
val B = Array(
Array(1.0, 2.0),
Array(3.0, 4.0))
val Bt = B.transpose
/*
* DNS using underlying MPI
*/
parallelize(args) {
for (i <- 0 until M; j <- 0 until N)
A(i) zip Bt(j) mapMPJ { case (a, b) => a * b } reduceMPJ (_ + _)
if (globalRank == 0)
println("CHECK RESULT:\n" + Matrix(A) * Matrix(B))
}
Программа отлично компилируется и запускается с использованием новейшей среды IDE eclipse scala.Я не пробовал другие компиляторы, но, возможно, я слепой, но я потратил так много времени, поэтому надеюсь на некоторую помощь:)
edit
Естьнеявное преобразование из Array в seqMPJ, FYI.