Exemple #1
0
        public void ApplyToVector <I>(IList <I> input, IList <I[]> output, IPartitioning outputPartitioning)
        {
            using (new FuncTrace()) {
                Debug.Assert(DestGlobalId.Length == MappingIndex.Length);
                Debug.Assert(OldGlobalId.Length == MappingIndex.Length);
                int oldJ = DestGlobalId.Length;

                if (input.Count != oldJ)
                {
                    throw new ArgumentException("Mismatch between input vector length and current data length.");
                }
                if (output.Count != outputPartitioning.LocalLength)
                {
                    throw new ArgumentException("Length mismatch of output list and output partition.");
                }

                int j0Dest = outputPartitioning.i0;

                // keys: processors which should receive data from this processor
                Dictionary <int, ApplyToVector_Helper <I> > AllSendData = new Dictionary <int, ApplyToVector_Helper <I> >();

                for (int j = 0; j < oldJ; j++)
                {
                    I data_j = input[j];

                    foreach (int jDest in TargetIdx[j])
                    {
                        if (outputPartitioning.IsInLocalRange(jDest))
                        {
                            I[] destCollection = output[jDest - j0Dest];
                            ArrayTools.AddToArray(data_j, ref destCollection);
                            output[jDest - j0Dest] = destCollection;
                        }
                        else
                        {
                            int targProc = outputPartitioning.FindProcess(jDest);

                            ApplyToVector_Helper <I> dataTargPrc;
                            if (!AllSendData.TryGetValue(targProc, out dataTargPrc))
                            {
                                dataTargPrc = new ApplyToVector_Helper <I>();
                                AllSendData.Add(targProc, dataTargPrc);
                            }

                            dataTargPrc.TargetIndices.Add(jDest);
                            dataTargPrc.Items.Add(data_j);
                        }
                    }
                }

                var AllRcvData = SerialisationMessenger.ExchangeData(AllSendData, outputPartitioning.MPI_Comm);

                foreach (var kv in AllRcvData)
                {
                    int rcvProc = kv.Key;
                    j0Dest = outputPartitioning.GetI0Offest(rcvProc);

                    var TIdxs = kv.Value.TargetIndices;
                    var TVals = kv.Value.Items;
                    Debug.Assert(TIdxs.Count == TVals.Count);
                    int L = TIdxs.Count;

                    for (int l = 0; l < L; l++)
                    {
                        int idx = TIdxs[l] - j0Dest;
                        Debug.Assert(outputPartitioning.IsInLocalRange(idx));

                        I[] destCollection = output[idx];
                        ArrayTools.AddToArray(TVals[idx], ref destCollection);
                        output[idx] = destCollection;
                    }
                }
            }
        }
Exemple #2
0
        /// <summary>
        /// Resorts a vector according to this permutation, i.e. the
        /// <em>j</em>-th item of the input vector is copied to the
        /// <see cref="Values"/>[j]-th entry of the output vector.
        /// </summary>
        /// <param name="input">
        /// Input vector, length must be equal to the length of this permutation, unchanged on exit.
        /// </param>
        /// <param name="output">
        /// On exit, <paramref name="output"/>[<see cref="Values"/>[j]] = <paramref name="input"/>[j]
        /// </param>
        public void ApplyToVector <I>(IList <I> input, IList <I> output, IPartitioning outputPartitioning)
        {
            using (new FuncTrace()) {
                if (input.Count != this.LocalLength)
                {
                    throw new ArgumentException("wrong size of input vector.");
                }
                if (output.Count != outputPartitioning.LocalLength)
                {
                    throw new ArgumentException("wrong size of output vector.");
                }

                long[] TargetInd = this.Values;
                // keys: processors which should receive data from this processor
                Dictionary <int, ApplyToVector_Helper <I> > sendData =
                    new Dictionary <int, ApplyToVector_Helper <I> >();

                int out_myI0   = outputPartitioning.i0;
                int out_nextI0 = out_myI0 + outputPartitioning.LocalLength;
                int J          = this.Partitioning.LocalLength;

                for (int j = 0; j < J; j++)
                {
                    if (out_myI0 <= TargetInd[j] && TargetInd[j] < out_nextI0)
                    {
                        // target index located on this processor
                        output[(int)(TargetInd[j] - out_myI0)] = input[j];
                    }
                    else
                    {
                        // target index located on other processor

                        int TargProc = outputPartitioning.FindProcess(TargetInd[j]);

                        ApplyToVector_Helper <I> sendData_TargProc = null;
                        if (!sendData.TryGetValue(TargProc, out sendData_TargProc))
                        {
                            sendData_TargProc = new ApplyToVector_Helper <I>();
                            sendData.Add(TargProc, sendData_TargProc);
                        }

                        sendData_TargProc.Items.Add(input[j]);
                        sendData_TargProc.TargetIndices.Add(TargetInd[j]);
                    }
                }

                var rcvData = SerialisationMessenger.ExchangeData(
                    sendData, MPI.Wrappers.csMPI.Raw._COMM.WORLD);

                foreach (var rcvPkt in rcvData.Values)
                {
                    int K = rcvPkt.Items.Count;
                    Debug.Assert(rcvPkt.Items.Count == rcvPkt.TargetIndices.Count);

                    for (int k = 0; k < K; k++)
                    {
                        int locIdx = (int)(rcvPkt.TargetIndices[k]) - out_myI0;
                        output[locIdx] = rcvPkt.Items[k];
                    }
                }
            }
        }