/// <summary> /// Read data from partial distance matrices. Here the assumption is that per node parallelism /// is same as for the program that generated these matrices. Also the total number of nodes /// are assumed to be both same in number and same in physically. /// </summary> /// <param name="path">Local path where partial matrices are stored</param> /// <param name="prefix">Name prefix of partial matrix files</param> /// <param name="ext">File extension of partial matrix files</param> /// <param name="totalThreads">Number of threads per process times number of processes</param> public static void ReadDataFromFiles(string path, string prefix, string ext) { int totalThreads = PWCUtility.MPI_Size * PWCUtility.ThreadCount; // Divide the total number of points among total thread count Range[] threadRanges = RangePartitioner.Partition(PWCUtility.PointCount_Global, totalThreads); PWCUtility.StartPointperThread = new int[PWCUtility.ThreadCount]; PWCUtility.PointsperThread = new int[PWCUtility.ThreadCount]; for (int i = 0; i < PWCUtility.ThreadCount; i++) { PWCUtility.StartPointperThread[i] = threadRanges[i].StartIndex; PWCUtility.PointsperThread[i] = threadRanges[i].Length; } // Each process handles more than one thread. So set the process ranges accordingly Range[] processRanges = new Range[PWCUtility.MPI_Size]; int start, end; // At each iteration i is set to a multiple of PWCUtility.ThreadCount, i.e. i % PWCUtility.ThreadCount is 0 for (int i = 0; i < totalThreads;) { start = threadRanges[i].StartIndex; end = threadRanges[i + PWCUtility.ThreadCount - 1].EndIndex; processRanges[i / PWCUtility.ThreadCount] = new Range(start, end); i += PWCUtility.ThreadCount; } // The range of data points handled by this process Range processRange = processRanges[PWCUtility.MPI_Rank]; PWCUtility.PointCount_Process = processRange.Length; PWCUtility.PointStart_Process = processRange.StartIndex; // Find the largest number of points handled by a process PWCUtility.PointCount_Largest = int.MinValue; foreach (Range r in processRanges) { PWCUtility.PointCount_Largest = Math.Max(r.Length, PWCUtility.PointCount_Largest); } // Create a reader to read only the number of rows handled by this process. Number of cols is // equal to the total number of datapoints. MatrixBinaryReader reader = new MatrixBinaryReader(processRange.Length, PWCUtility.PointCount_Global); start = PWCUtility.MPI_Rank * PWCUtility.ThreadCount; end = start + PWCUtility.ThreadCount - 1; // todo: saliya - fix Read methods for other types #if USE_UINT16 PWCUtility.PointDistances = reader.ReadUInt16(fname, processRange.StartIndex, processRange.Length); #elif USE_INT16 PWCUtility.PointDistances = reader.ReadInt16(path, prefix, ext, start, end, threadRanges); #else PWCUtility.PointDistances = reader.ReadDouble(fname, processRange.StartIndex, processRange.Length); #endif }
// read data from file to memory // set starting position and end number for data points assigned to each thread. // These are in startindex and lenindex respectively // Return data stored as // Distance [ClusterCenter,ClusterIndex] with all ClusterIndex<=ClusterCenter stored in order for each ClusterCenter. // Diagonal values are stored (as zero) // Total space m(m+1)/2 if lower triangular store (checkerboard =1) public static void ReadDataFromFile(string fname) { // First divide points among processes Range[] processRanges = RangePartitioner.Partition(PWCUtility.PointCount_Global, PWCUtility.MPI_Size); Range processRange = processRanges[PWCUtility.MPI_Rank]; PWCUtility.PointCount_Process = processRange.Length; PWCUtility.PointStart_Process = processRange.StartIndex; PWCUtility.PointCount_Largest = int.MinValue; foreach (Range r in processRanges) { PWCUtility.PointCount_Largest = Math.Max(r.Length, PWCUtility.PointCount_Largest); } // Now divide points among threads Range[] threadRanges = RangePartitioner.Partition(processRange, PWCUtility.ThreadCount); PWCUtility.StartPointperThread = new int[PWCUtility.ThreadCount]; PWCUtility.PointsperThread = new int[PWCUtility.ThreadCount]; for (int i = 0; i < PWCUtility.ThreadCount; i++) { PWCUtility.StartPointperThread[i] = threadRanges[i].StartIndex; PWCUtility.PointsperThread[i] = threadRanges[i].Length; } MatrixBinaryReader reader = new MatrixBinaryReader(PWCUtility.PointCount_Global, PWCUtility.PointCount_Global); #if USE_UINT16 PWCUtility.PointDistances = reader.ReadUInt16(fname, processRange.StartIndex, processRange.Length); #elif USE_INT16 PWCUtility.PointDistances = reader.ReadInt16(fname, processRange.StartIndex, processRange.Length); #else PWCUtility.PointDistances = reader.ReadDouble(fname, processRange.StartIndex, processRange.Length); #endif } // End routine controlling reading of data
// Read Distance Data public static void ReadDataFromFile(string fname) { if ((SALSAUtility.DebugPrintOption > 0) && (SALSAUtility.MPI_Rank == 0)) { SALSAUtility.SALSAPrint(1, "Starting to read data: " + " Distance Cut " + SALSAUtility.DistanceCut.ToString("F3")); } double countremoveddistances = 0.0; double counttotaldistances = 0.0; SALSAUtility.StoredDistanceOption = Math.Max(2, SALSAUtility.StoredDistanceOption); if (SALSAUtility.PointCount_Global == SALSAUtility.NumberOriginalPoints) { SALSAUtility.DiskDistanceOption = Math.Max(2, SALSAUtility.DiskDistanceOption); } // Remove unsupported options if (SALSAUtility.DiskDistanceOption == 3) { SALSAUtility.StoredDistanceOption = 3; } if (SALSAUtility.StoredDistanceOption == 3) { SALSAUtility.CalcFixedCrossFixed = false; } // Set sizes of matrix on disk int rowcount = SALSAUtility.PointCount_Global; int colcount = SALSAUtility.PointCount_Global; if (SALSAUtility.DiskDistanceOption == 1) { rowcount = SALSAUtility.NumberOriginalPoints; colcount = SALSAUtility.NumberOriginalPoints; } if (SALSAUtility.DiskDistanceOption == 3) { rowcount = SALSAUtility.NumberVariedPoints; } // MatrixTextReader reader = new MatrixTextReader(rowcount,colcount); var reader = new MatrixBinaryReader(rowcount, colcount); bool Oneread = true; if (SALSAUtility.StoredDistanceOption != SALSAUtility.DiskDistanceOption) { Oneread = false; } if (SALSAUtility.Usedreordered) { Oneread = false; } if (Oneread) { #if USE_UINT16 SALSAUtility.PointDistances = reader.ReadUInt16(fname, SALSAUtility.PointStart_Process, SALSAUtility.PointCount_Process); #elif USE_INT16 SALSAUtility.PointDistances = reader.ReadInt16(fname, SALSAUtility.PointStart_Process, SALSAUtility.PointCount_Process); #else SALSAUtility.PointDistances = reader.ReadDouble(fname, SALSAUtility.PointStart_Process, SALSAUtility.PointCount_Process); #endif int numberofcolumns = SALSAUtility.PointCount_Global; for (int GlobalPointIndex = SALSAUtility.PointStart_Process; GlobalPointIndex < SALSAUtility.PointStart_Process + SALSAUtility.PointCount_Process; GlobalPointIndex++) { int rowindex = GlobalPointIndex; if (SALSAUtility.StoredDistanceOption == 2) { rowindex = rowindex - SALSAUtility.PointStart_Process; } if (SALSAUtility.StoredDistanceOption == 3) { int originalpoint = SALSAUtility.UsedPointtoOriginalPointMap[rowindex]; int variedpoint = SALSAUtility.OriginalPointDisposition[originalpoint] - SALSAUtility.SALSASHIFT; if (variedpoint < 0) { Exception e = SALSAUtility.SALSAError(" Illegal Distance Request Used Point " + rowindex.ToString() + " Original " + originalpoint.ToString()); throw (e); } rowindex = variedpoint - SALSAUtility.VariedPointStart_Process; } for (int columnindex = 0; columnindex < numberofcolumns; columnindex++) { TDistance Temp = SALSAUtility.PointDistances[rowindex][columnindex]; counttotaldistances = counttotaldistances + 1.0; if (SALSAUtility.DistanceCut > 0.0) { double distancevalue = (SALSAUtility.PointDistances[rowindex][columnindex] / (TDistance.MaxValue * 1.0)); if (distancevalue > SALSAUtility.DistanceCut) { SALSAUtility.PointDistances[rowindex][columnindex] = TDistance.MaxValue; countremoveddistances = countremoveddistances + 1.0; } } } } } else { int colsread = SALSAUtility.PointCount_Global; if (SALSAUtility.DiskDistanceOption == 1) { colsread = SALSAUtility.NumberOriginalPoints; } if (SALSAUtility.StoredDistanceOption == 2) { SALSAUtility.PointDistances = new TDistance[SALSAUtility.PointCount_Process][]; } if (SALSAUtility.StoredDistanceOption == 3) { SALSAUtility.PointDistances = new TDistance[SALSAUtility.VariedPointCount_Process][]; } for (int GlobalPointIndex = SALSAUtility.PointStart_Process; GlobalPointIndex < SALSAUtility.PointStart_Process + SALSAUtility.PointCount_Process; GlobalPointIndex++) { int rowtostore = GlobalPointIndex; if (SALSAUtility.StoredDistanceOption == 2) { rowtostore = GlobalPointIndex - SALSAUtility.PointStart_Process; } if (SALSAUtility.StoredDistanceOption == 3) { int OriginalIndex = SALSAUtility.UsedPointtoOriginalPointMap[GlobalPointIndex]; rowtostore = SALSAUtility.OriginalPointDisposition[OriginalIndex] - SALSAUtility.SALSASHIFT; if (rowtostore < 0) { continue; } rowtostore = rowtostore - SALSAUtility.VariedPointStart_Process; } int rowtoread = -1; if (SALSAUtility.DiskDistanceOption == 1) { rowtoread = SALSAUtility.UsedPointtoOriginalPointMap[GlobalPointIndex]; } if (SALSAUtility.DiskDistanceOption == 2) { rowtoread = SALSAUtility.ActualtoNaiveUsedOrder[GlobalPointIndex]; } if (SALSAUtility.DiskDistanceOption == 3) { int OriginalIndex = SALSAUtility.UsedPointtoOriginalPointMap[GlobalPointIndex]; rowtoread = SALSAUtility.OriginalPointDisposition[OriginalIndex] - SALSAUtility.SALSASHIFT; if (rowtoread < 0) { continue; } rowtoread = SALSAUtility.ActualtoNaiveUsedOrder[rowtoread]; } SALSAUtility.PointDistances[rowtostore] = new TDistance[colcount]; #if USE_UINT16 buffer = reader.ReadUInt16(fname, rowtoread, 1); #elif USE_INT16 buffer = reader.ReadInt16(fname, rowtoread, 1); #else buffer = reader.ReadDouble(fname, rowtoread, 1); #endif // Store buffer in PointDistances for (int colIndex = 0; colIndex < colsread; colIndex++) { int coltostore = colIndex; if (SALSAUtility.DiskDistanceOption == 1) { coltostore = SALSAUtility.OriginalPointtoUsedPointMap[colIndex]; if (coltostore < 0) { continue; } } else if (SALSAUtility.DiskDistanceOption > 1) { coltostore = SALSAUtility.NaivetoActualUsedOrder[colIndex]; } SALSAUtility.PointDistances[rowtostore][coltostore] = buffer[0][colIndex]; counttotaldistances = counttotaldistances + 1.0; if (SALSAUtility.DistanceCut > 0.0) { double distancevalue = (SALSAUtility.PointDistances[rowtostore][coltostore] / (TDistance.MaxValue * 1.0)); if (distancevalue > SALSAUtility.DistanceCut) { SALSAUtility.PointDistances[rowtostore][coltostore] = TDistance.MaxValue; countremoveddistances = countremoveddistances + 1.0; } } } } } SALSAUtility.StartSubTimer(SALSAUtility.MPIREDUCETiming); counttotaldistances = SALSAUtility.MPI_communicator.Allreduce(counttotaldistances, Operation <double> .Add); countremoveddistances = SALSAUtility.MPI_communicator.Allreduce(countremoveddistances, Operation <double> .Add); SALSAUtility.StopSubTimer(SALSAUtility.MPIREDUCETiming); double fractionleft = 1.0 - countremoveddistances / counttotaldistances; if ((SALSAUtility.DebugPrintOption > 0) && (SALSAUtility.MPI_Rank == 0)) { SALSAUtility.SALSAPrint(1, "Total Distances " + counttotaldistances.ToString("F0") + " Distances Removed on Input " + countremoveddistances.ToString("F0") + " Fraction Left " + fractionleft.ToString("F5")); } }