QTSServerPrefs::QTSServerPrefs(XMLPrefsParser* inPrefsSource, Bool16 inWriteMissingPrefs)
:   QTSSPrefs(inPrefsSource, NULL, QTSSDictionaryMap::GetMap(QTSSDictionaryMap::kPrefsDictIndex), false),
    fSessionTimeoutInSecs(0),
    fMaximumConnections(0),
    fMaxBandwidthInKBits(0),
    fBreakOnAssert(false),
    fAutoRestart(false),
    fErrorRollIntervalInDays(0),
    fErrorLogBytes(0),
    fErrorLogVerbosity(0),
    fScreenLoggingEnabled(true),
    fErrorLogEnabled(false),
    fCMSPort(0),

    fAutoStart(false),
    fEnableMSGDebugPrintfs(false),
    fEnableCMSServerInfo(true),
    fNumThreads(0),
    fNumMsgThreads(0),
#if __MacOSX__
    fEnableMonitorStatsFile(false),
#else
    fEnableMonitorStatsFile(false),
#endif 
    fStatsFileIntervalSeconds(10),
    fCloseLogsOnWrite(false),
	fMonitorLANPort(0),
	fMonitorWANPort(0),
	fAllowGuestAuthorizeDefault(true)
{
    SetupAttributes();
    RereadServerPreferences(inWriteMissingPrefs);
}
QTSServerPrefs::QTSServerPrefs(XMLPrefsParser* inPrefsSource, Bool16 inWriteMissingPrefs)
:   QTSSPrefs(inPrefsSource, NULL, QTSSDictionaryMap::GetMap(QTSSDictionaryMap::kPrefsDictIndex), false),
    fConnectionTimeoutInSecs(0),
    fRTSPTimeoutString(fRTSPTimeoutBuf, 0),

    fCMSPort(0),
    fMaximumConnections(0),
    fMaxBandwidthInKBits(0),
    fBreakOnAssert(false),
    fAutoRestart(false),
    fTBUpdateTimeInSecs(0),
    fABUpdateTimeInSecs(0),
    fLocalCameraPort(80),
    fErrorRollIntervalInDays(0),
    fErrorLogBytes(0),
    fErrorLogVerbosity(0),
    fScreenLoggingEnabled(true),
    fErrorLogEnabled(false),
    fMinTCPBufferSizeInBytes(0),
    fMaxTCPBufferSizeInBytes(0),
    fTCPSecondsToBuffer(0),

    fAuthScheme(qtssAuthDigest),
    fNumThreads(0),
    fNumRTSPThreads(0),

    fCloseLogsOnWrite(false)
{
    SetupAttributes();
    RereadServerPreferences(inWriteMissingPrefs);
}
Exemple #3
0
QTSServerPrefs::QTSServerPrefs(XMLPrefsParser* inPrefsSource, Bool16 inWriteMissingPrefs)
:   QTSSPrefs(inPrefsSource, NULL, QTSSDictionaryMap::GetMap(QTSSDictionaryMap::kPrefsDictIndex), false),
    fRTSPTimeoutInSecs(0),
    fRTSPTimeoutString(fRTSPTimeoutBuf, 0),
    fSessionTimeoutInSecs(0),
    fRTPTimeoutInSecs(0),
    fMaximumConnections(0),
    fMaxBandwidthInKBits(0),
    fBreakOnAssert(false),
    fAutoRestart(false),
    fTBUpdateTimeInSecs(0),
    fABUpdateTimeInSecs(0),
    fSafePlayDurationInSecs(0),
    fErrorRollIntervalInDays(0),
    fErrorLogBytes(0),
    fErrorLogVerbosity(0),
    fScreenLoggingEnabled(true),
    fErrorLogEnabled(false),
    fMinTCPBufferSizeInBytes(0),
    fMaxTCPBufferSizeInBytes(0),
    fTCPSecondsToBuffer(0),
    fCMSPort(0),
    fAppendSrcAddrInTransport(false),
    fSmallWindowSizeInK(0),
	fMediumWindowSizeInK(0),
    fLargeWindowSizeInK(0),
    fWindowSizeThreshold(0),
	fWindowSizeMaxThreshold(0),
    fMaxRetransDelayInMsec(0),
    fIsAckLoggingEnabled(false),
    fSendIntervalInMsec(0),
    fMaxSendAheadTimeInSecs(0),
    fAuthScheme(qtssAuthDigest),
    fAutoStart(false),
    fEnableMSGDebugPrintfs(false),
    fEnableCMSServerInfo(true),
    fNumThreads(0),
    fNumMsgThreads(0),
#if __MacOSX__
    fEnableMonitorStatsFile(false),
#else
    fEnableMonitorStatsFile(false),
#endif 
    fStatsFileIntervalSeconds(10),
	fOverbufferRate(0.0),
    fCloseLogsOnWrite(false),
    fDisableThinning(false),
	fMonitorLANPort(0),
	fMonitorWANPort(0),
	fAllowGuestAuthorizeDefault(true)
{
    SetupAttributes();
    RereadServerPreferences(inWriteMissingPrefs);
}
QTSServerPrefs::QTSServerPrefs(XMLPrefsParser* inPrefsSource, Bool16 inWriteMissingPrefs)
	: QTSSPrefs(inPrefsSource, NULL, QTSSDictionaryMap::GetMap(QTSSDictionaryMap::kPrefsDictIndex), false),
	fConnectionTimeoutInSecs(0),
	fErrorRollIntervalInDays(0),
	fErrorLogBytes(0),
	fErrorLogVerbosity(0),
	fScreenLoggingEnabled(true),
	fErrorLogEnabled(false),
	fNumThreads(0),
	fNumBlockingThreads(0),
	fCloseLogsOnWrite(false)
{
	SetupAttributes();
	RereadServerPreferences(inWriteMissingPrefs);
}
Exemple #5
0
QTSServerPrefs::QTSServerPrefs(XMLPrefsParser* inPrefsSource, Bool16 inWriteMissingPrefs)
:   QTSSPrefs(inPrefsSource, NULL, QTSSDictionaryMap::GetMap(QTSSDictionaryMap::kPrefsDictIndex), false),
    fConnectionTimeoutInSecs(0),
    fRTSPTimeoutString(fRTSPTimeoutBuf, 0),

    fCMSPort(0),
    fMaximumConnections(0),
    fMaxBandwidthInKBits(0),
    fBreakOnAssert(false),
    fAutoRestart(false),
    fTBUpdateTimeInSecs(0),
    fABUpdateTimeInSecs(0),
    fLocalCameraPort(80),
    fErrorRollIntervalInDays(0),
    fErrorLogBytes(0),
    fErrorLogVerbosity(0),
    fScreenLoggingEnabled(true),
    fErrorLogEnabled(false),
    fDropAllPacketsTimeInMsec(0),
    fDropAllVideoPacketsTimeInMsec(0),
    fThinAllTheWayTimeInMsec(0),
    fAlwaysThinTimeInMsec(0),
    fStartThinningTimeInMsec(0),
    fStartThickingTimeInMsec(0),
    fThickAllTheWayTimeInMsec(0),
    fQualityCheckIntervalInMsec(0),
    fMinTCPBufferSizeInBytes(0),
    fMaxTCPBufferSizeInBytes(0),
    fTCPSecondsToBuffer(0),
    fDoReportHTTPConnectionAddress(false),
    fAppendSrcAddrInTransport(false),
    fSmallWindowSizeInK(0),
	fMediumWindowSizeInK(0),
    fLargeWindowSizeInK(0),
    fWindowSizeThreshold(0),
	fWindowSizeMaxThreshold(0),
    fMaxRetransDelayInMsec(0),
    fIsAckLoggingEnabled(false),
    fRTCPPollIntervalInMsec(0),
    fRTCPSocketRcvBufSizeInK(0),
    fIsSlowStartEnabled(false),
    fSendIntervalInMsec(0),
    fMaxSendAheadTimeInSecs(0),
    fauto_delete_sdp_files(false),
    fAuthScheme(qtssAuthDigest),
    fsdp_file_delete_interval_seconds(10),
    fAutoStart(false),
    fEnableRTSPErrMsg(false),
    fEnableRTSPDebugPrintfs(false),
    fEnableRTSPServerInfo(true),
    fNumThreads(0),
    fNumRTSPThreads(0),
#if __MacOSX__
    fEnableMonitorStatsFile(false),
#else
    fEnableMonitorStatsFile(false),
#endif 
    fStatsFileIntervalSeconds(10),
	fOverbufferRate(0.0),
    fCloseLogsOnWrite(false),
    fDisableThinning(false),
	//
	fDefaultStreamQuality(0),
	fAllowGuestAuthorizeDefault(true)
{
    SetupAttributes();
    RereadServerPreferences(inWriteMissingPrefs);
}
QTSServerPrefs::QTSServerPrefs(XMLPrefsParser* inPrefsSource, Bool16 inWriteMissingPrefs)
:   QTSSPrefs(inPrefsSource, NULL, QTSSDictionaryMap::GetMap(QTSSDictionaryMap::kPrefsDictIndex), false),
    fRTSPTimeoutInSecs(0),
    fRTSPTimeoutString(fRTSPTimeoutBuf, 0),
    fRealRTSPTimeoutInSecs(0),
    fRTPTimeoutInSecs(0),
    fMaximumConnections(0),
    fMaxBandwidthInKBits(0),   
    fDropAllPacketsTimeInMsec(0),
    fDropAllVideoPacketsTimeInMsec(0),
    fThinAllTheWayTimeInMsec(0),
    fAlwaysThinTimeInMsec(0),
    fStartThinningTimeInMsec(0),
    fStartThickingTimeInMsec(0),
    fThickAllTheWayTimeInMsec(0),
    fQualityCheckIntervalInMsec(0),
    /*此处缺少fMinTCPBufferSizeInBytes,fMaxTCPBufferSizeInBytes,fTCPSecondsToBuffer*/
	fDoReportHTTPConnectionAddress(false),
	fAppendSrcAddrInTransport(false),
	fBreakOnAssert(false),
	fAutoRestart(false),
	fTBUpdateTimeInSecs(0),
	fABUpdateTimeInSecs(0),
	fSafePlayDurationInSecs(0),
    fErrorLogEnabled(false),
	fScreenLoggingEnabled(true),
	fErrorLogBytes(0),
	fErrorRollIntervalInDays(0),
	fErrorLogVerbosity(0),//当前错误日志的级别
    fMaxRetransDelayInMsec(0),
    fIsAckLoggingEnabled(false),
    fRTCPPollIntervalInMsec(0),
    fRTCPSocketRcvBufSizeInK(0), 
    fSendIntervalInMsec(0),
    fMaxSendAheadTimeInSecs(0),
    fIsSlowStartEnabled(false),
    fAutoStart(false),
    fReliableUDP(true),/* 可用RUDP方式传输 */
    fReliableUDPPrintfs(false),
    fEnableRTSPErrMsg(false),
    fEnableRTSPDebugPrintfs(false),
    fEnableRTSPServerInfo(true),
    fNumThreads(0),
#if __MacOSX__
    fEnableMonitorStatsFile(false),
#else
    fEnableMonitorStatsFile(false),
#endif 
    fStatsFileIntervalSeconds(10),
	fOverbufferRate(0.0),
	fSmallWindowSizeInK(0),
	fMediumWindowSizeInK(0),
	fLargeWindowSizeInK(0),
	fWindowSizeThreshold(0),
	fWindowSizeMaxThreshold(0),
    fEnablePacketHeaderPrintfs(false),   
    fPacketHeaderPrintfOptions(kRTPALL | kRTCPSR | kRTCPRR | kRTCPAPP | kRTCPACK),
    fCloseLogsOnWrite(false),
    fDisableThinning(false),
	fauto_delete_sdp_files(false),  
	fsdp_file_delete_interval_seconds(10),/* 检查sdp文件间隔10s */
	fAuthScheme(qtssAuthDigest) /* 默认digest认证级别 */
{
    SetupAttributes();
    RereadServerPreferences(inWriteMissingPrefs);
}
Exemple #7
0
int main(int argc, char **argv) {
	struct opts Options;
	int i;
	time_t CurrentTime;
	clock_t TotalClock = clock();
	
	/* Apply Mondriaan options. */
	SetDefaultOptions(&Options);
	
	if (!SetOptionsFromFile(&Options, "Mondriaan.defaults")) {
		fprintf(stderr, "main(): warning, cannot set options from 'Mondriaan.defaults', using default options!\n");
	}
	
	if (!ParseCommandLineOptions(&Options, argc, argv)) {
		fprintf(stderr, "main(): invalid command line parameters!\n");
		exit(EXIT_FAILURE);
	}
	
	if (!ApplyOptions(&Options)) {
		fprintf(stderr, "main(): could not apply given options!\n");
		exit(EXIT_FAILURE);
	}
	
	if (NumMatrices <= 0 || Matrices == NULL) {
		fprintf(stderr, "main(): Invalid number of supplied matrices or samples!\n");
		exit(EXIT_FAILURE);
	}
	
	/* Start profiling ... */
	fprintf(stderr, "Profiling Mondriaan for %d matrices, %d samples, %s processors, and %f imbalance.\n", NumMatrices, NumSamples, argv[1], Options.eps);
	
	for (i = 0; i < NumMatrices*NumNumProcs; ++i) {
		int j;
		
		fprintf(stderr, "[% 4d/%d] (% 4ld) %s ", i + 1, NumMatrices*NumNumProcs, Matrices[i].P, Matrices[i].File);
		fflush(stderr);
		
		if (!SetupAttributes(&Matrices[i])) {
			fprintf(stderr, "main(): Cannot setup attributes!\n");
			exit(EXIT_FAILURE);
		}
		
		Options.P = Matrices[i].P;
		
		/* Take the requested number of samples. */
		for (j = 0; j < NumSamples; ++j) {
			struct sparsematrix A;
			long int *UAssign, *VAssign, Symmetric;
			FILE *File;
			long l;
			int k;
			clock_t Clock;
			
			double Duration;
			long MaxNz, MinNz;
			long MaxComU, MaxComV, ComVolU, ComVolV;
			
			fprintf(stderr, ".");
			fflush(stderr);
			
			/* Read matrix from disk. */
			File = fopen(Matrices[i].File, "r");
			
			if (!File) {
				fprintf(stderr, "main(): Could not open '%s' for reading!\n", Matrices[i].File);
				exit(EXIT_FAILURE);
			}
				
			if (!MMReadSparseMatrix(File, &A)) {
				fprintf(stderr, "main(): Could not read matrix!\n");
				exit(EXIT_FAILURE);
			}
			
			fclose(File);
			
			/* Remove double zeroes. */
			if (!SparseMatrixRemoveDuplicates(&A)) exit(EXIT_FAILURE);
			
			/* Check symmetry. */
			if (A.m == A.n && (A.MMTypeCode[3] == 'S' || A.MMTypeCode[3] == 'K' || A.MMTypeCode[3] == 'H')) Symmetric = TRUE;
			else Symmetric = FALSE;
			
			if (Symmetric)
			{
				if (Options.SymmetricMatrix_UseSingleEntry == SingleEntNo) SparseMatrixSymmetric2Full(&A);
				else if (Options.SymmetricMatrix_SingleEntryType == ETypeRandom) SparseMatrixSymmetricLower2Random(&A);
			}
			
			/* Add dummies if requested. */
			if (A.m == A.n && Options.SquareMatrix_DistributeVectorsEqual == EqVecYes && Options.SquareMatrix_DistributeVectorsEqual_AddDummies == DumYes) AddDummiesToSparseMatrix(&A);
			
			/* Initialise processor array. */
			A.NrProcs = Options.P;
			A.Pstart = (long *)malloc((A.NrProcs + 1)*sizeof(long));
			
			if (A.Pstart == NULL) {
				fprintf(stderr, "main(): Cannot allocate processor array!\n");
				exit(EXIT_FAILURE);
			}
			
			A.Pstart[0] = 0;
			
			for (k = 1; k <= A.NrProcs; ++k) {
				A.Pstart[k] = A.NrNzElts;
			}
		
			/* Distribute the processors among the matrix entries. */
			SetRandomSeed(Options.Seed = 137*j + 12345);
			
			/* ==== Start Mondriaan */
			Clock = clock();
			
			if (!DistributeMatrixMondriaan(&A, Options.P, Options.eps, &Options, NULL)) {
				fprintf(stderr, "main(): Unable to distribute matrix!\n");
				exit(EXIT_FAILURE);
			}
			
			/* Remove dummies. */
			if (A.m == A.n && Options.SquareMatrix_DistributeVectorsEqual == EqVecYes && Options.SquareMatrix_DistributeVectorsEqual_AddDummies == DumYes) RemoveDummiesFromSparseMatrix(&A);
			
			/* Convert randomly represented matrix to lower triangular form. */
			if (Symmetric && Options.SymmetricMatrix_UseSingleEntry == SingleEntYes && Options.SymmetricMatrix_SingleEntryType == ETypeRandom) SparseMatrixSymmetricRandom2Lower(&A);
			
			/* Distribute vectors. */
			UAssign = (long int *)malloc(A.m*sizeof(long int));
			VAssign = (long int *)malloc(A.n*sizeof(long int));
			
			if (UAssign == NULL || VAssign == NULL) {
				fprintf(stderr, "main(): Cannot allocate vertex assign arrays!\n");
				exit(EXIT_FAILURE);
			}
			
			/* Convert symmetrically partitioned matrix to full form. */
			if (Symmetric && Options.SymmetricMatrix_UseSingleEntry == SingleEntYes) SparseMatrixSymmetric2Full(&A);
			
			if (A.m == A.n && Options.SquareMatrix_DistributeVectorsEqual == EqVecYes) {
				if (Symmetric && Options.SymmetricMatrix_UseSingleEntry == SingleEntYes) {
					MaxComV = DistributeVec(&A, VAssign, ROW, &Options);
					
					if (MaxComV < 0) {
						fprintf(stderr, "main(): Unable to distribute vector!\n");
						exit(EXIT_FAILURE);
					}
					
					for (k = 0; k < A.m; k++) {
						UAssign[k] = VAssign[k];
					}
						
					MaxComU = MaxComV;
				}
				else {
					MaxComU = DistributeVecOrigEq(&A, UAssign, VAssign, &Options);
					
					if (MaxComU < 0) {
						fprintf(stderr, "main(): Unable to distribute vector!\n");
						exit(EXIT_FAILURE);
					}
					
					MaxComV = 0;
				}
			}
			else {
				MaxComV = DistributeVec(&A, VAssign, ROW, &Options);
				MaxComU = DistributeVec(&A, UAssign, COL, &Options);
				
				if (MaxComV < 0 || MaxComU < 0) {
					fprintf(stderr, "main(): Unable to distribute vector!\n");
					exit(EXIT_FAILURE);
				}
			}
			
			/* ==== Stop Mondriaan */
			/* Calculate duration. */
			Duration = (double)(clock() - Clock)/(double)CLOCKS_PER_SEC;
			
			/* Determine minimum and maximum number of assigned nonzeroes. */
			MaxNz = MinNz = A.Pstart[1] - A.Pstart[0];
			
			for (k = 1; k < A.NrProcs; ++k) {
				l = A.Pstart[k + 1] - A.Pstart[k];
				
				if (l > MaxNz) MaxNz = l;
				if (l < MinNz) MinNz = l;
			}
			
			/* Calculate communication volume. */
			if (!CalcCom(&A, VAssign, ROW, &ComVolV, &l, &l, &l, &l) ||
			    !CalcCom(&A, UAssign, COL, &ComVolU, &l, &l, &l, &l)) {
				fprintf(stderr, "main(): Unable to calculate communication volume!\n");
				exit(EXIT_FAILURE);
			}
			
			/* Store attributes. */
			Matrices[i].NumNz = A.NrNzElts;
			Matrices[i].Rows = A.m;
			Matrices[i].Cols = A.n;
			
			Matrices[i].Attributes[0].Data[j] = Duration;
			Matrices[i].Attributes[1].Data[j] = (double)(Options.P*MaxNz - A.NrNzElts)/(double)A.NrNzElts;
			Matrices[i].Attributes[2].Data[j] = (double)(MaxComV + MaxComU);
			Matrices[i].Attributes[3].Data[j] = (double)(ComVolV + ComVolU);
			
			/* Free memory. */
			MMDeleteSparseMatrix(&A);
			free(UAssign);
			free(VAssign);
		}
		
		/* Average attributes. */
		if (!AverageAndFreeAttributes(&Matrices[i])) {
			fprintf(stderr, "main(): Cannot setup attributes!\n");
			exit(EXIT_FAILURE);
		}
		
		fprintf(stderr, "\n");
	}
	
	/* Write accumulated data to stdout. */
	fprintf(stderr, "Finished profiling, writing data ...\n");
	
	printf("%% Profiled Mondriaan for %d matrices, %d samples, and %f imbalance.\n", NumMatrices, NumSamples, Options.eps);
	printf("\\documentclass[a4paper, 10pt]{article}\n\n");
	printf("\\usepackage{lscape}\n");
	printf("\\usepackage{longtable}\n\n");
	printf("\\author{\\texttt{Profile.c}}\n");
	CurrentTime = time(NULL);
	printf("\\date{%s}\n", asctime(localtime(&CurrentTime)));
	printf("\\title{Profiling Mondriaan %s with %d %s}\n\n", MONDRIAANVERSION, NumMatrices, NumMatrices > 1 ? "matrices" : "matrix");
	printf("\\begin{document}\n\n");
	
	printf("\\maketitle\n\n");
	
	printf("\\section{Results}\n\n");
	printf("Used Mondriaan version %s to distribute %d matrices (listed in table \\ref{MondriaanMatrices}) over %d processors with maximum imbalance %f, taking the average of %d samples. The used options can be found in table \\ref{MondriaanSettings} en the numerical results in table \\ref{MondriaanResults}.\n", MONDRIAANVERSION, NumMatrices, Options.P, Options.eps, NumSamples);
	printf("This took %.1f minutes in total.\n\n", (double)(clock() - TotalClock)/(60.0*(double)CLOCKS_PER_SEC));
	
	/* Export options. */
	printf("\\begin{table}\n");
	printf("\\caption{Mondriaan configuration.}\n");
	printf("\\label{MondriaanSettings}\n");
	printf("\\begin{center}\n");
	
	if (!ExportOptionsToLaTeX(stdout, &Options)) {
		fprintf(stderr, "main(): Unable to create option table!\n");
		exit(EXIT_FAILURE);
	}
	
	printf("\\end{center}\n");
	printf("\\end{table}\n\n");
	
	/* Export list of test matrices. */
	printf("\\begin{table}\n");
	printf("\\caption{%d tested matrices.}\n", NumMatrices);
	printf("\\label{MondriaanMatrices}\n");
	printf("\\begin{center}\n");
	printf("\\begin{tabular}{l|lll}\nFile & $\\mathit{nz}$ & $m$ & $n$ \\\\\n\\hline\n");
	
	for (i = 0; i < NumMatrices*NumNumProcs; i += NumNumProcs) {
		printf("\\verb|%s| & %ld & %ld & %ld \\\\\n", Matrices[i].File, Matrices[i].NumNz, Matrices[i].Rows, Matrices[i].Cols);
	}
	
	printf("\\hline\n");
	
	printf("\\end{tabular}\n");
	printf("\\end{center}\n");
	printf("\\end{table}\n\n");
	
	/* Export test data. */
	printf("\\begin{landscape}\n");
	printf("\\begin{longtable}{lrrrrr}");
	printf("\\caption[Profile results]{Profile results for %d matrices.}\n", NumMatrices);
	printf("\\label{MondriaanResults} \\\\\n\n");
	
	printf("\\multicolumn{1}{c}{File} & \\multicolumn{1}{c}{$p$} & \\multicolumn{1}{c}{Time (s)} & \\multicolumn{1}{c}{$\\varepsilon$} & \\multicolumn{1}{c}{Max. com.} & \\multicolumn{1}{c}{Com. vol.} \\\\ \\hline\n");
	printf("\\endfirsthead\n\n");
	
	printf("\\multicolumn{6}{c}{\\tablename\\ \\thetable{} -- continued from previous page.} \\\\\n");
	printf("\\multicolumn{1}{c}{File} & \\multicolumn{1}{c}{$p$} & \\multicolumn{1}{c}{Time (s)} & \\multicolumn{1}{c}{$\\varepsilon$} & \\multicolumn{1}{c}{Max. com.} & \\multicolumn{1}{c}{Com. vol.} \\\\ \\hline\n");
	printf("\\endhead\n\n");
	
	printf("\\multicolumn{6}{c}{Continued on next page.} \\\\\n");
	printf("\\endfoot\n\n");
	
	printf("\\hline\n\\endlastfoot\n\n");
	
	for (i = 0; i < NumMatrices*NumNumProcs; i += NumNumProcs) {
		int j;
		
		for (j = 0; j < NumNumProcs; ++j) {
			char Tmp[256];
			const struct sMatrixData *Mat = &Matrices[i + j];
			
			if (j == 0) printf("\\verb|%s| & %ld", Mat->File, Mat->P);
			else printf(" & %ld", Mat->P);
			
			/*
			int k;
			for (k = 0; k < NUM_ATTRIBUTES; ++k) {
				char Tmp[256];
				
				DoubleToLaTeX(Tmp, Mat->Attributes[k].Average, 3);
				printf(" & $%s \\pm ", Tmp);
				DoubleToLaTeX(Tmp, sqrt(Mat->Attributes[k].Variance), 1);
				printf("%s$", Tmp);
			}
			*/
			
			DoubleToLaTeX(Tmp, Mat->Attributes[0].Average, 3);
			printf(" & $%s \\pm ", Tmp);
			DoubleToLaTeX(Tmp, sqrt(Mat->Attributes[0].Variance), 1);
			printf("%s$", Tmp);
			
			DoubleToLaTeX(Tmp, Mat->Attributes[1].Average, 3);
			printf(" & $%s$", Tmp);
			
			printf(" & $%ld \\pm %ld$", (long)Mat->Attributes[2].Average, (long)sqrt(Mat->Attributes[2].Variance));
			printf(" & $%ld \\pm %ld$", (long)Mat->Attributes[3].Average, (long)sqrt(Mat->Attributes[3].Variance));
			
			printf(" \\\\\n");
		}
		printf("\\hline\n");
	}
	
	printf("\n\\end{longtable}\n");
	printf("\\end{landscape}\n\n");
	
	printf("\\end{document}\n\n");
	
	/* Append raw data. */
	printf("Raw data:\n");
	
	for (i = 0; i < NumMatrices*NumNumProcs; ++i) {
		int j;
		
		printf("%s\t%ld\t%ld\t%ld\t%ld\t", Matrices[i].File, Matrices[i].NumNz, Matrices[i].Rows, Matrices[i].Cols, Matrices[i].P);
		
		for (j = 0; j < NUM_ATTRIBUTES - 1; ++j) printf("%e\t%e\t", Matrices[i].Attributes[j].Average, sqrt(Matrices[i].Attributes[j].Variance));
		printf("%e\t%e\n", Matrices[i].Attributes[j].Average, sqrt(Matrices[i].Attributes[j].Variance));
	}
	printf("\n");
	
	free(Matrices);

	fprintf(stderr, "Done!\n");
	
	exit(EXIT_SUCCESS);
}