Exemplo n.º 1
0
        private void init(IPartitioning p, cl_program program)
        {
            clscale     = cl.CreateKernel(program, "scale");
            clacc       = cl.CreateKernel(program, "acc");
            clmew       = cl.CreateKernel(program, "mew");
            cldnrm2     = cl.CreateKernel(program, "dnrm2");
            clinnerprod = cl.CreateKernel(program, "innerprod");

            size       = p.LocalLength;
            globalsize = size;
            int m = globalsize % localsize;

            if (m > 0)
            {
                globalsize += localsize - m;
            }

            globalsizehalf = globalsize / 2;
            m = globalsizehalf % localsize;
            if (m > 0)
            {
                globalsizehalf += localsize - m;
            }

            groups = globalsizehalf / localsize;
        }
Exemplo n.º 2
0
        public Worker(
            WorkerSettings settings,
            RpcClientFactory rpcClientFactory,
            IMapping <TKey, TValueIn> mappingPhase,
            IReducing <TKey, TValueIn, TValueOut> reducingPhase,
            IPartitioning <TKey, TValueIn> partitioningPhase)
        {
            _settings          = settings;
            _mappingPhase      = mappingPhase;
            _reducingPhase     = reducingPhase;
            _partitioningPhase = partitioningPhase;
            _workerInfoDto     = new()
            {
                WorkerUuid = settings.WorkerUuid
            };
            _channel         = rpcClientFactory.CreateRpcChannel();
            _heartBeatTicker = new()
            {
                Interval = TimeSpan.FromSeconds(4).TotalMilliseconds
            };
            StartHeartbeat();
        }

        public void Dispose()
        {
            _heartBeatTicker.Dispose();
            _channel.Dispose();
        }
Exemplo n.º 3
0
 /// <summary>
 /// Create OpenCL vector
 /// </summary>
 /// <param name="p">Parition</param>
 /// <param name="device">Device</param>
 public clVector(IPartitioning p, clDevice device)
     : base(p)
 {
     h_data      = new double[p.LocalLength];
     this.device = device;
     init(p, device.vectorProgram);
 }
Exemplo n.º 4
0
 /// <summary>
 /// Create OpenCL vector with external memory
 /// </summary>
 /// <param name="p">Parition</param>
 /// <param name="content">Memory for this vector</param>
 /// <param name="device">Device</param>
 public clVector(IPartitioning p, double[] content, clDevice device)
     : base(p)
 {
     h_data      = content;
     this.device = device;
     init(p, device.vectorProgram);
 }
Exemplo n.º 5
0
 static public bool IsLocallyEqual(this IPartitioning t, IPartitioning o)
 {
     if (t == null && o == null)
     {
         return(true);
     }
     if (o == null)
     {
         return(false);
     }
     if (t == null)
     {
         return(false);
     }
     if (object.ReferenceEquals(t, o))
     {
         return(true);
     }
     if (o.LocalLength != t.LocalLength)
     {
         return(false);
     }
     if (o.iE - o.i0 != t.iE)
     {
         return(false);
     }
     return(true);
 }
Exemplo n.º 6
0
        /// <summary>
        /// see <see cref="MatrixBase.CreateVec"/>
        /// </summary>
        protected override VectorBase CreateVec <T>(T a, IPartitioning len, out bool CopyIsShallow)
        {
            if (a.Count != len.LocalLength)
            {
                throw new ArgumentException("count of a must be at least 'len'!", "len");
            }
            if (len.MPI_Comm != this.ColPartition.MPI_Comm)
            {
                throw new ArgumentException();
            }


            IPartitioning part_a = len;

            double[] _a_stor = a as double[]; // try to do a shallow copy and save mem. and time
            if (_a_stor == null)
            {
                // shallow copy didn't worked
                _a_stor       = ArrayTools.List2Array <double>(a, 0, len.LocalLength);
                CopyIsShallow = false;
            }
            else
            {
                CopyIsShallow = true;
            }
            return(new MtVector(part_a, _a_stor));
        }
Exemplo n.º 7
0
 /// <summary>
 /// .
 /// </summary>
 /// <param name="P">
 /// <see cref="Part"/>
 /// </param>
 protected VectorBase(IPartitioning P)
 {
     if (P.IsMutable)
     {
         throw new NotSupportedException(P.GetType().Name + " is marked as mutable partitioning.");
     }
     m_Part = P;
 }
Exemplo n.º 8
0
 /// <summary>
 /// see <see cref="Device.CreateVector(IPartitioning)"/>;
 /// </summary>
 public override VectorBase CreateVector(IPartitioning p)
 {
     if (p.IsMutable)
     {
         throw new NotSupportedException();
     }
     return(new RefVector(p));
 }
Exemplo n.º 9
0
 /// <summary>
 /// checks whether <paramref name="i"/> is within the local range of the
 /// partition <paramref name="p"/> - if not, an exception is thrown.
 /// </summary>
 /// <param name="i"></param>
 /// <param name="p"></param>
 void TestIndex(int i, IPartitioning p)
 {
     i -= (int)p.i0;
     if (i < 0 || i >= p.LocalLength)
     {
         throw new IndexOutOfRangeException("row/col index out of range.");
     }
 }
Exemplo n.º 10
0
 /// <summary>
 /// constructor which uses memory that is allocated elsewhere
 /// </summary>
 /// <param name="P"></param>
 /// <param name="content">
 /// used to initialize <see cref="Storage"/>
 /// </param>
 public MtVector(IPartitioning P, double[] content)
     : base(P)
 {
     if (P.LocalLength > content.Length)
     {
         throw new ArgumentException("vector content must match local length of partition", "content");
     }
     m_Storage = content;
 }
Exemplo n.º 11
0
 /// <summary>
 /// Throws an exception, if <see cref="IsInLocalRange(int)"/>(<paramref name="i"/>) evaluates to false;
 /// </summary>
 /// <param name="i"></param>
 static public void TestIfInLocalRange(this IPartitioning p, int i)
 {
     if (!p.IsInLocalRange(i))
     {
         int i0 = p.i0;
         int iE = p.iE;
         throw new ArgumentOutOfRangeException("i", "index is not within local range of partition: expecting " + i0 + " <= i < " + iE + ", but got i = " + i + ";");
     }
 }
Exemplo n.º 12
0
 /// <summary>
 /// constructor which uses memory that is allocated elsewhere
 /// </summary>
 /// <param name="P"></param>
 /// <param name="content">
 /// used to initialize <see cref="h_data"/>
 /// </param>
 /// <param name="env"></param>
 public CudaVector(IPartitioning P, double[] content, CudaEnviroment env) : base(P)
 {
     if (P.LocalLength > content.Length)
     {
         throw new ArgumentException("vector content must match local length of partition", "content");
     }
     h_data = content;
     ConstructorCommon(env);
 }
Exemplo n.º 13
0
 public Mapper(
     IMapping <TKey, TValue> mappingPhase,
     IPartitioning <TKey, TValue> partitioningPhase,
     RpcMapReduceService.RpcMapReduceServiceClient rpcClient,
     WorkerSettings settings)
 {
     _mappingPhase      = mappingPhase;
     _partitioningPhase = partitioningPhase;
     _settings          = settings;
     _rpcClient         = rpcClient;
 }
Exemplo n.º 14
0
        /// <summary>
        /// constructs and initializes a new HYPRE_IJVector object
        /// </summary>
        /// <param name="partition">distribution of the vector over MPI processes</param>
        public IJVector(IPartitioning partition)
        {
            if (partition.IsMutable)
            {
                throw new NotSupportedException();
            }

            if (partition.TotalLength > (int.MaxValue - 2))
            {
                throw new ApplicationException("unable to create HYPRE vector: no. of matrix rows is larger than HYPRE index type (32 bit signed int);");
            }

            m_VectorPartition = partition;

            int      jLower  = (int)partition.i0;
            int      jUpper  = (int)partition.i0 + partition.LocalLength - 1;
            MPI_Comm comm    = csMPI.Raw._COMM.WORLD;
            int      Nupdate = partition.LocalLength;

            // create object
            HypreException.Check(Wrappers.IJVector.Create(comm, jLower, jUpper, out m_IJVector));
            HypreException.Check(Wrappers.IJVector.SetObjectType(m_IJVector, Wrappers.Constants.HYPRE_PARCSR));
            HypreException.Check(Wrappers.IJVector.Initialize(m_IJVector));

            // set values
            int nvalues = Math.Min(1024, Nupdate);

            int[]    indices = new int[nvalues];
            double[] values  = new double[nvalues];
            int      i0      = (int)m_VectorPartition.i0;

            for (int i = 0; i < Nupdate; i += nvalues)
            {
                if (i + nvalues > Nupdate)
                {
                    nvalues = Nupdate - i;
                }

                for (int ii = 0; ii < nvalues; ii++)
                {
                    indices[ii] = i + ii + i0;
                    //if (vec == null)
                    //    values[ii] = mapping[i_ii];
                    //else
                    //    values[ii] = vec[i_ii];
                }

                HypreException.Check(Wrappers.IJVector.SetValues(m_IJVector, nvalues, indices, values));
            }

            // assable
            HypreException.Check(Wrappers.IJVector.Assemble(m_IJVector));
            HypreException.Check(Wrappers.IJVector.GetObject(m_IJVector, out ParCRS_vector));
        }
Exemplo n.º 15
0
 public static void GetI0(ref int _ref, out int i0, out int ierr)
 {
     ierr = 0;
     i0   = -1;
     try {
         IPartitioning p = (IPartitioning)Infrastructure.GetObject(_ref);
         i0 = (int)p.i0;
     } catch (Exception e) {
         ierr = Infrastructure.ErrorHandler(e);
     }
 }
Exemplo n.º 16
0
 public static void GetLocLen(ref int _ref, out int LocLen, out int ierr)
 {
     ierr   = 0;
     LocLen = -1;
     try {
         IPartitioning p = (IPartitioning)Infrastructure.GetObject(_ref);
         LocLen = (int)p.LocalLength;
     } catch (Exception e) {
         ierr = Infrastructure.ErrorHandler(e);
     }
 }
Exemplo n.º 17
0
 public static void GetMPIsize(ref int _ref, out int MPIsize, out int ierr)
 {
     ierr    = 0;
     MPIsize = -1;
     try {
         IPartitioning p = (IPartitioning)Infrastructure.GetObject(_ref);
         MPIsize = (int)p.Size;
     } catch (Exception e) {
         ierr = Infrastructure.ErrorHandler(e);
     }
 }
Exemplo n.º 18
0
        /// <summary>
        /// first indices for each process; size is equal to number of processors (<see cref="IPartitioning.MpiSize"/> plus 1;
        /// first entry is always 0, last entry is equal to <see cref="m_TotalLength"/>;
        /// </summary>
        static public int[] GetI0s(this IPartitioning p)
        {
            int sz = p.MpiSize;

            int[] R = new int[sz + 1];
            for (int i = 0; i < sz; i++)
            {
                R[i] = p.GetI0Offest(i);
            }
            R[sz] = p.TotalLength;
            return(R);
        }
Exemplo n.º 19
0
        /// <summary>
        /// Create vector for this device
        /// </summary>
        /// <param name="p">Parition</param>
        /// <returns>The vector</returns>
        public override VectorBase CreateVector(IPartitioning p)
        {
            if (p.IsMutable)
            {
                throw new NotSupportedException();
            }
            if (disposed)
            {
                throw new ApplicationException("object is disposed.");
            }

            return(new clVector(p, this));
        }
Exemplo n.º 20
0
        /// <summary>
        /// Equality of partitioning.
        /// </summary>
        static public bool EqualsPartition(this IPartitioning t, IPartitioning o)
        {
            if (t == null && o == null)
            {
                return(true);
            }
            if (o == null)
            {
                return(false);
            }
            if (t == null)
            {
                return(false);
            }
            if (object.ReferenceEquals(t, o))
            {
                return(true);
            }

            if (o.MPI_Comm != t.MPI_Comm)
            {
                return(false);
            }

            if (o.MpiSize != t.MpiSize)
            {
                return(false);
            }
            if (o.MpiRank != t.MpiRank)
            {
                return(false);
            }
            if (o.TotalLength != t.TotalLength)
            {
                return(false);
            }
            if (o.i0 != t.i0)
            {
                return(false);
            }
            if (o.LocalLength != t.LocalLength)
            {
                return(false);
            }
            //if (o.IsMutuable != t.IsMutuable)
            //    return false;

            return(true);
        }
Exemplo n.º 21
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="spatialOp"></param>
        /// <param name="fields"></param>
        /// <param name="matrix"></param>
        /// <param name="affineOffset"></param>
        /// <param name="OnlyAffine">
        /// if true, only the <paramref name="affineOffset"/>
        /// is computed and <paramref name="matrix"/> is null on exit.
        /// </param>
        public static void ComputeMatrix(SpatialOperator spatialOp, CoordinateMapping fields, bool OnlyAffine, out MsrMatrix matrix, out double[] affineOffset)
        {
            // Check operator and arguments
            if (!spatialOp.IsCommited)
            {
                throw new ArgumentException("operator must be committed first.", "spatialOp");
            }
            if (spatialOp.ContainsNonlinear)
            {
                throw new ArgumentException("spatial differential operator cannot contain nonlinear components for implicit euler.", "spatialOp");
            }
            if (!spatialOp.ContainsLinear())
            {
                throw new ArgumentException("spatial differential operator seems to contain no components.", "spatialOp");
            }
            if (spatialOp.DomainVar.Count != spatialOp.CodomainVar.Count)
            {
                throw new ArgumentException("spatial differential operator must have the same number of domain and codomain variables.", "spatialOp");
            }
            if (fields.Fields.Count != spatialOp.CodomainVar.Count)
            {
                throw new ArgumentException("the number of fields in the coordinate mapping must be equal to the number of domain/codomain variables of the spatial differential operator", "fields");
            }

            // Assemble matrix and affine offset
            IPartitioning matrixPartition = fields;


            if (!OnlyAffine)
            {
                matrix = new MsrMatrix(matrixPartition);
            }
            else
            {
                matrix = null;
            }
            affineOffset = new double[fields.LocalLength];

            var b = spatialOp.GetMatrixBuilder(fields, null, fields);

            if (OnlyAffine)
            {
                b.ComputeAffine(affineOffset);
            }
            else
            {
                b.ComputeMatrix(matrix, affineOffset);
            }
        }
Exemplo n.º 22
0
 /// <summary>
 /// see <see cref="Device.CreateVector{T}(IPartitioning,T,out bool)"/>;
 /// </summary>
 public override VectorBase CreateVector <T>(IPartitioning p, T content, out bool shallowInit)
 {
     double[] vals = null;
     if (typeof(T).Equals(typeof(double[])))
     {
         shallowInit = true;
         vals        = content as double[];
     }
     else
     {
         shallowInit = false;
         vals        = content.ToArray();
     }
     return(new RefVector(p, vals));
 }
Exemplo n.º 23
0
        /// <summary>
        /// see <see cref="MatrixBase.CreateVec{T}(T,IPartitioning,out bool)"/>
        /// </summary>
        protected override VectorBase CreateVec <T>(T a, IPartitioning len, out bool CopyIsShallow)
        {
            if (a.Count != len.LocalLength)
            {
                throw new ArgumentException("count of a must be at least 'len'!", "len");
            }
            if (len.MPI_Comm != this.ColPartition.MPI_Comm)
            {
                throw new ArgumentException();
            }


            IPartitioning part_a = len;

            double[] _a_stor = ArrayTools.List2Array <double>(a, 0, len.LocalLength);
            CopyIsShallow = false;
            return(new clVector(part_a, _a_stor, device));
        }
Exemplo n.º 24
0
        /// <summary>
        /// constructor
        /// </summary>
        protected MatrixBase(MsrMatrix M)
        {
            ilPSP.MPICollectiveWatchDog.Watch();
            if (M.RowPartitioning.IsMutable)
            {
                throw new NotSupportedException();
            }
            if (M.ColPartition.IsMutable)
            {
                throw new NotSupportedException();
            }
            m_CellSize = 1; // ggT(M.RowPartitioning.BlockSize, M.ColPartition.BlockSize);


            m_ColPart = M.ColPartition;
            m_RowPart = M.RowPartitioning;

            //if (M.ColPerBlock != M.RowsPerBlock)
            //    throw new ApplicationException("not supported.");
        }
Exemplo n.º 25
0
        /// <summary>
        /// ctor. The size of the block-diagonals is determined by the block
        /// size (see <see cref="Partitioning.BlockSize"/>) of the row and
        /// column mapping (<paramref name="_RowPartition"/>,
        /// <paramref name="ColPart"/>).
        /// </summary>
        public BlockDiagonalMatrix(IPartitioning _RowPartition, IPartitioning ColPart, int RowBlkSz, int ColBlkSz)
        {
            if (_RowPartition.MPI_Comm != ColPart.MPI_Comm)
            {
                throw new ArgumentException();
            }
            m_RowPart        = _RowPartition;
            m_ColumnPart     = ColPart;
            NoOfRowsPerBlock = RowBlkSz;
            NoOfColsPerBlock = ColBlkSz;

            if (_RowPartition.LocalLength % NoOfRowsPerBlock != 0)
            {
                throw new ArgumentException();
            }
            if (ColPart.LocalLength % NoOfRowsPerBlock != 0)
            {
                throw new ArgumentException();
            }


            Blox = new double[m_RowPart.LocalLength / NoOfRowsPerBlock, NoOfRowsPerBlock, NoOfColsPerBlock];
        }
Exemplo n.º 26
0
        /// <summary>
        /// Create vector for this device
        /// </summary>
        /// <typeparam name="T">Type for data storage</typeparam>
        /// <param name="p">Partition</param>
        /// <param name="content">Data storage</param>
        /// <param name="shallowInit">Data is copied or referenced</param>
        /// <returns>The vector</returns>
        public override VectorBase CreateVector <T>(IPartitioning p, T content, out bool shallowInit)
        {
            if (p.IsMutable)
            {
                throw new NotSupportedException();
            }
            if (disposed)
            {
                throw new ApplicationException("object is disposed.");
            }

            double[] vals = null;
            if (typeof(T).Equals(typeof(double[])))
            {
                shallowInit = true;
                vals        = content as double[];
            }
            else
            {
                shallowInit = false;
                vals        = content.ToArray();
            }
            return(new clVector(p, vals, this));
        }
Exemplo n.º 27
0
            public void Update(int RowIndex, FormatBase m_LocalMtx, IDictionary <int, External> ExtMatrix, IPartitioning rowPart, int Col0)
            {
                rowPart.TestIfInLocalRange(RowIndex);
                int _row = rowPart.TransformIndexToLocal(RowIndex);

                if (!_1stUse || row != _row)
                {
                    m_LocalMtx.GetAllOccupiedColumns(_row, ref ColIndices, ref PointersIntoVal, ref Values, out UsedLen);
                    row     = _row;
                    _1stUse = true;

                    // find Min And Max Col;
                    MinCol = int.MinValue;
                    MaxCol = int.MaxValue;
                    for (int i = 0; i < UsedLen; i++)
                    {
                        MinCol = Math.Max(MinCol, ColIndices[i]);
                        MaxCol = Math.Max(MaxCol, ColIndices[i]);
                    }

                    // filter double values;
                    if (m_LocalMtx is CCBCSR || m_LocalMtx is ELLPACKlike)
                    {
                        // these matrices may have unused 'dummy' entries (to fill up memory)

                        for (int i = 0; i < UsedLen; i++)
                        {
                            int MtxCol = ColIndices[i];
                            if (Array.IndexOf <int>(ColIndices, MtxCol, 0, i) >= 0)
                            {
                                // found a dummy

                                UsedLen++;
                                for (int ii = i; ii < UsedLen; ii++)
                                {
                                    ColIndices[ii]      = ColIndices[ii + 1];
                                    PointersIntoVal[ii] = PointersIntoVal[ii + 1];
                                    Values[ii]          = Values[ii + 1];
                                }
                            }
                        }
                    }

                    if (OwnerProcRank == null || OwnerProcRank.Length < UsedLen)
                    {
                        OwnerProcRank = new int[UsedLen];
                    }
                    int rnk = rowPart.MpiRank;
                    for (int i = 0; i < UsedLen; i++)
                    {
                        OwnerProcRank[i] = rnk;
                    }

                    // transform column indices to global indices (for local matrix)...
                    for (int i = 0; i < UsedLen; i++)
                    {
                        ColIndices[i] += Col0;
                    }

                    // find entries in external cells
                    foreach (KeyValuePair <int, External> sdfjbh in ExtMatrix)
                    {
                        rnk = sdfjbh.Key;
                        External extm = sdfjbh.Value;

                        int k = Array.IndexOf <int>(extm.rowInd, row);
                        if (k >= 0)
                        {
                            // need to look into this external matrix

                            int rSt = extm.RowStart[k];
                            int rEn = extm.RowStart[k + 1];

                            for (int i = rSt; i < rEn; i++)
                            {
                                // resize arrays ...
                                if (UsedLen > PointersIntoVal.Length - 10)
                                {
                                    Array.Resize(ref PointersIntoVal, PointersIntoVal.Length + 10);
                                }
                                if (UsedLen > ColIndices.Length - 10)
                                {
                                    Array.Resize(ref ColIndices, ColIndices.Length + 10);
                                }
                                if (UsedLen > Values.Length - 10)
                                {
                                    Array.Resize(ref Values, Values.Length + 10);
                                }
                                if (UsedLen > OwnerProcRank.Length - 10)
                                {
                                    Array.Resize(ref Values, OwnerProcRank.Length + 10);
                                }

                                // record entry of external matrix
                                OwnerProcRank[UsedLen]   = rnk;
                                PointersIntoVal[UsedLen] = i;
                                Values[UsedLen]          = extm.Val[i];
                                ColIndices[UsedLen]      = extm.GlobalColInd[i];
                            }
                        }
                    }
                }
            }
Exemplo n.º 28
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;
                    }
                }
            }
        }
Exemplo n.º 29
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="TargetMappingIndex"></param>
        /// <param name="outputPartitioning">
        /// Partitioning of the new grid, resp the return array.
        /// </param>
        /// <returns>
        /// - 1st index: cell index in new grid, correlates with <paramref name="outputPartitioning"/>.
        /// - 2nd index: enumeration over cells (in the old grid) which are combined in the new grid.
        ///   For cells with refinement, always one entry, for cells which are coarsened a greater number of entries.
        ///   If null, the cell is not changed.
        /// - content: Subdivision leaf index, correlates with 2nd index of <see cref="KrefS_SubdivLeaves"/>, can be used as an input to <see cref="GetSubdivBasisTransform(int, int, int)"/>.
        /// </returns>
        public int[][] GetTargetMappingIndex(IPartitioning outputPartitioning)
        {
            using (new FuncTrace()) {
                Debug.Assert(DestGlobalId.Length == MappingIndex.Length);
                Debug.Assert(OldGlobalId.Length == MappingIndex.Length);
                int oldJ = DestGlobalId.Length;

                // Caching
                // =======

                if (m_TargetMappingIndex != null)
                {
                    // caching
                    if (m_TargetMappingIndex.Length != outputPartitioning.LocalLength)
                    {
                        throw new ArgumentException("Length mismatch of output list and output partition.");
                    }

                    return(m_TargetMappingIndex);
                }

                // local evaluation, prepare communication
                // =======================================

                m_TargetMappingIndex = new int[outputPartitioning.LocalLength][];

                int j0Dest = outputPartitioning.i0;

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

                for (int j = 0; j < oldJ; j++)
                {
                    int[] MappingIndex_j = MappingIndex[j];
                    if (MappingIndex_j != null)
                    {
                        Debug.Assert(TargetIdx[j].Length == MappingIndex_j.Length);
                        int L = MappingIndex_j.Length;

                        for (int l = 0; l < L; l++)
                        {
                            int jDest  = TargetIdx[j][l];
                            int MapIdx = MappingIndex_j[l];

                            if (outputPartitioning.IsInLocalRange(jDest))
                            {
                                int[] destCollection = m_TargetMappingIndex[jDest - j0Dest];
                                ArrayTools.AddToArray(MapIdx, ref destCollection);
                                m_TargetMappingIndex[jDest - j0Dest] = destCollection;
                            }
                            else
                            {
                                int targProc = outputPartitioning.FindProcess(jDest);

                                GetTargetMapping_Helper dataTargPrc;
                                if (!AllSendData.TryGetValue(targProc, out dataTargPrc))
                                {
                                    dataTargPrc = new GetTargetMapping_Helper();
                                    AllSendData.Add(targProc, dataTargPrc);
                                }

                                dataTargPrc.TargetIndices.Add(jDest);
                                dataTargPrc.Items.Add(MapIdx);
                            }
                        }
                    }
                    else
                    {
                        Debug.Assert(TargetIdx[j].Length == 1);
                    }
                }

                // communication
                // =============

                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));

                        int[] destCollection = m_TargetMappingIndex[idx];
                        ArrayTools.AddToArray(TVals[idx], ref destCollection);
                        m_TargetMappingIndex[idx] = destCollection;
                    }
                }

                // return
                // ======

                return(m_TargetMappingIndex);
            }
        }
Exemplo n.º 30
0
 /// <summary>
 /// Subtracts <see cref="IPartitioning.i0"/> from <paramref name="iGlob"/>.
 /// </summary>
 static public int TransformIndexToLocal(this IPartitioning p, int iGlob)
 {
     return(iGlob - p.i0);
 }