nd4j-parameter-server-parent/nd4j-parameter-server-node/src/main/java/org/nd4j/parameterserver/distributed/messages/intercom/DistributedSgDotMessage.java
@Override
    public void processMessage() {
        // this only picks up new training round
        //log.info("sI_{} Processing DistributedSgDotMessage taskId: {}", transport.getShardIndex(), getTaskId());

        SkipGramRequestMessage sgrm = new SkipGramRequestMessage(w1, w2, rowsB, codes, negSamples, alpha, 119);
        if (negSamples > 0) {
            // unfortunately we have to get copy of negSamples here
            int negatives[] = Arrays.copyOfRange(rowsB, codes.length, rowsB.length);
            sgrm.setNegatives(negatives);
        }
        sgrm.setTaskId(this.taskId);
        sgrm.setOriginatorId(this.getOriginatorId());



        // FIXME: get rid of THAT
        SkipGramTrainer sgt = (SkipGramTrainer) trainer;
        sgt.pickTraining(sgrm);

        //TODO: make this thing a single op, even specialOp is ok
        // we calculate dot for all involved rows

        int resultLength = codes.length + (negSamples > 0 ? (negSamples + 1) : 0);

        INDArray result = Nd4j.createUninitialized(resultLength, 1);
        int e = 0;
        for (; e < codes.length; e++) {
            double dot = Nd4j.getBlasWrapper().dot(storage.getArray(WordVectorStorage.SYN_0).getRow(w2),
                            storage.getArray(WordVectorStorage.SYN_1).getRow(rowsB[e]));
            result.putScalar(e, dot);
        }

        // negSampling round
        for (; e < resultLength; e++) {
            double dot = Nd4j.getBlasWrapper().dot(storage.getArray(WordVectorStorage.SYN_0).getRow(w2),
                            storage.getArray(WordVectorStorage.SYN_1_NEGATIVE).getRow(rowsB[e]));
            result.putScalar(e, dot);
        }

        if (voidConfiguration.getExecutionMode() == ExecutionMode.AVERAGING) {
            // just local bypass
            DotAggregation dot = new DotAggregation(taskId, (short) 1, shardIndex, result);
            dot.setTargetId((short) -1);
            dot.setOriginatorId(getOriginatorId());
            transport.putMessage(dot);
        } else if (voidConfiguration.getExecutionMode() == ExecutionMode.SHARDED) {
            // send this message to everyone
            DotAggregation dot = new DotAggregation(taskId, (short) voidConfiguration.getNumberOfShards(), shardIndex,
                            result);
            dot.setTargetId((short) -1);
            dot.setOriginatorId(getOriginatorId());
            transport.sendMessage(dot);
        }
    }
@Override
    public void processMessage() {
        // this only picks up new training round
        //log.info("sI_{} Processing DistributedSgDotMessage taskId: {}", transport.getShardIndex(), getTaskId());

        SkipGramRequestMessage sgrm = new SkipGramRequestMessage(w1, w2, rowsB, codes, negSamples, alpha, 119);
        if (negSamples > 0) {
            // unfortunately we have to get copy of negSamples here
            int negatives[] = Arrays.copyOfRange(rowsB, codes.length, rowsB.length);
            sgrm.setNegatives(negatives);
        }
        sgrm.setTaskId(this.taskId);
        sgrm.setOriginatorId(this.getOriginatorId());



        // FIXME: get rid of THAT
        SkipGramTrainer sgt = (SkipGramTrainer) trainer;
        sgt.pickTraining(sgrm);

        //TODO: make this thing a single op, even specialOp is ok
        // we calculate dot for all involved rows

        int resultLength = codes.length + (negSamples > 0 ? (negSamples + 1) : 0);

        INDArray result = Nd4j.createUninitialized(resultLength, 1);
        int e = 0;
        for (; e < codes.length; e++) {
            double dot = Nd4j.getBlasWrapper().dot(storage.getArray(WordVectorStorage.SYN_0).getRow(w2),
                            storage.getArray(WordVectorStorage.SYN_1).getRow(rowsB[e]));
            result.putScalar(e, dot);
        }

        // negSampling round
        for (; e < resultLength; e++) {
            double dot = Nd4j.getBlasWrapper().dot(storage.getArray(WordVectorStorage.SYN_0).getRow(w2),
                            storage.getArray(WordVectorStorage.SYN_1_NEGATIVE).getRow(rowsB[e]));
            result.putScalar(e, dot);
        }

        if (voidConfiguration.getExecutionMode() == ExecutionMode.AVERAGING) {
            // just local bypass
            DotAggregation dot = new DotAggregation(taskId, (short) 1, shardIndex, result);
            dot.setTargetId((short) -1);
            dot.setOriginatorId(getOriginatorId());
            transport.putMessage(dot);
        } else if (voidConfiguration.getExecutionMode() == ExecutionMode.SHARDED) {
            // send this message to everyone
            DotAggregation dot = new DotAggregation(taskId, (short) voidConfiguration.getNumberOfShards(), shardIndex,
                            result);
            dot.setTargetId((short) -1);
            dot.setOriginatorId(getOriginatorId());
            transport.sendMessage(dot);
        }
    }
This method calculates dot of gives rows