It might be nicer to factor out the message:

          var t = g.mapReduceTriplets(et => {
            val msg = et.srcAttr
              .ebeMultiply(et.dstAttr)
              .mapMultiply(et.attr / et.srcAttr.dotProduct(et.dstAttr))
            Iterator((et.srcId, msg), (et.dstId, msg))
          }, (a: RealVector, b: RealVector) => a.add(b))