Пример #1
0
void doBoss(int size, int matrSize, int initStyle){
	double* matr1 = NULL;
	double* matr2 = NULL;
	double* bufferMatr = NULL;
	double* recvBuffer = NULL;
	double* matrErg = NULL;
	
	int i = 1;
	int j = 0;
	int h = 0;

	int workerSize = size -1;
	int receiveBufferSize = 0;
	int recvElem = 0;

	int rows = matrSize;
	int workerRows = 0;
	int workerRowDiff = 0;
	int offset = 0;
	int bufferMatrSize = 0;

	struct timeval start,end;
	long runtime; //runtime in us;
	float runtimeSec; //runtime in sec;
	float flops;

	MPI_Status status; 	//recv status;
	int recvSize;		//number of received entries;

	matr1 = (double*)malloc(matrSize*matrSize*sizeof(double));
	matr2 = (double*)malloc(matrSize*matrSize*sizeof(double));

	receiveBufferSize = matrSize;

	if(workerSize & 0x01 && workerSize > 1){ //odd amount of worker
		receiveBufferSize*=((matrSize/workerSize)+1);
	}else{
		receiveBufferSize*=(matrSize/workerSize);
	}

	recvBuffer = (double*)malloc(receiveBufferSize*sizeof(double));

	matrErg = (double*)malloc(matrSize*matrSize*sizeof(double));

	if(initStyle == INIT_STYLE_RANDOM){
		initMatrixRandom(matr1,matrSize,TRUE);
		initMatrixRandom(matr2,matrSize,TRUE);
	}else{
		initMatrix(matr1,matrSize,TRUE);	 // matr1[i,j] = i + j;
		initMatrix(matr2,matrSize,FALSE);	 // matr2[i,j] = i * j;
	}

	matr2 = reorderMatrix(matr2,matrSize);

	initMatrixRandom(matrErg,matrSize,FALSE); //matrErg = 0.0;

	#if DEBUG == TRUE
		printf("Matr1\n");
		plot(matr1,matrSize);
		printf("Matr2\n");
		plot(matr2,matrSize);
	#endif

	gettimeofday(&start,NULL);

	//send Matrices to the worker-nodes
	for(i = 1;i < size;i++){
		MPI_Send(matr1, matrSize*matrSize, MPI_DOUBLE, i, 1, MPI_COMM_WORLD);
		MPI_Send(matr2, matrSize*matrSize, MPI_DOUBLE, i, 2, MPI_COMM_WORLD);
	} 

	//check if there something left to do for the boss
	if(matrSize % workerSize > 0){
		for(i = 1; i <= workerSize; i++){
			if(workerSize & 0x01 && workerSize > 1){ //odd amount of worker
				workerRows=((matrSize/workerSize)+1);
			}else{
				workerRows=(matrSize/workerSize);
			}

			workerRowDiff = matrSize - i * workerRows;

			if(workerRowDiff < 0){
				workerRows = workerRows + workerRowDiff;
			}
			
			//initial Value for rows = matrSize
			//if rows > 0 => there are work to do
			rows = rows - workerRows;
		}
		
		#if DEBUG == TRUE
		printf(" Boss should calculate %d rows \n",rows);
		#endif

		if(rows > 0){
			offset = (matrSize - rows)*matrSize;
			bufferMatrSize = matrSize*rows;
			bufferMatr = (double*)malloc(bufferMatrSize*sizeof(double));
			for(i = 0;i < rows; i++){//rows of the result-matrix
				for(j = 0; j < matrSize; j++){//colums of the result-matrix
					for(h = 0; h < matrSize; h++){
						*(bufferMatr+j+i*matrSize)+=(*(matr1+h+offset+i*matrSize))*(*(matr2+j*matrSize+h));
					}
				}
			}
		}
	}

	//gather Results from worker-nodes
	for(i = 1; i < size; i++){
		MPI_Recv(recvBuffer,receiveBufferSize,MPI_DOUBLE,i,0,MPI_COMM_WORLD,&status);
		MPI_Get_count(&status,MPI_DOUBLE,&recvSize);
				
		for(j = 0; j < recvSize; j++){
			*(matrErg+recvElem+j)= *(recvBuffer+j);
		}

		#if DEBUG == TRUE
		printf("Received elements %d current amount of elements %d\n",recvSize,recvElem);
		#endif

		recvElem += recvSize;
	}

	if(rows > 0){
		for(i = 0; i < bufferMatrSize;i++){
			*(matrErg+recvElem+i)= *(bufferMatr+i);
		}
	}	

	gettimeofday(&end,NULL);
	
	#if DEBUG == TRUE
		printf("Result\n");
		plot(matrErg,matrSize);
	#endif

	runtime = calcRuntime(&start,&end);
	runtimeSec = (float)runtime/1e6;
	flops = (2*size*size)/(runtimeSec); //??

	printf("#runtime[us] runtime[sec] flop size\n");
	printf("%ld %f %f %d\n",runtime,runtimeSec,flops,matrSize);
	
	if(matr1 != NULL){	
		#if DEBUG == TRUE
		printf("Release memory for matr1\n");
		#endif	
		free(matr1);
	}

	if(matr2 != NULL){
		#if DEBUG == TRUE
		printf("Release memory for matr2\n");
		#endif
		free(matr2);
	}
	
	if(matrErg != NULL){
		#if DEBUG == TRUE
		printf("Release memory for matrErg\n");
		#endif
		free(matrErg);
	}
	
	if(recvBuffer != NULL){
		#if DEBUG == TRUE
		printf("Release memory for recvBuffer\n");
		#endif 
		free(recvBuffer);
	}

	if(bufferMatr != NULL){
		#if DEBUG == TRUE
			printf("Release memory for bufferMatr\n");
		#endif
		free(bufferMatr);
	}
}
Пример #2
0
void calculateNeighbours(int* iv_id, int* im_pos, int* im_nbs, double* iv_ss, int* iv_type, int* nP, int* pP, double* phiP)
{
	//Initialise input variables
	int* v_id = iv_id;
	int* m_pos = im_pos;
	int* m_nbs = im_nbs;
	int* v_type = iv_type;
	double* v_ss = iv_ss;
	int n = *nP;
	int p = *pP;
	double phi = *phiP;

	//Initialise temporary variables
	bool clsenb = false;
	int d = 0;
	int itmp = 0;
	double dtmp = 0;
	int* col = new int[n];
	int* new_order = new int[n];
	int* id_order = new int[n];
	int* v_id_copy = new int[n];
	int* m_pos_copy = new int[p*n];	
	int* m_nbs_tmp = new int[2*n];
	double* v_tmp = new double[n];

	//initialise new arrrays as required.
	for(int i = 0; i < n; i++) {
		m_nbs_tmp[2*i] = 0;
		m_nbs_tmp[2*i + 1] = 0;
		v_tmp[i] = 0;
	}

	//	***********************************************************
	//	--Outer Loop: for dimension d, get left and right neighbours:
	//  ***********************************************************
	//	  start with column 1 (zero indexed in C)
		for(d = 0; d < p; d++)
		{

	//		--get the order of this column (1. copying contents of column to feed into mergesort).
	//		-- (2. Create order, returned in 'new_order')
			for(int i = 0; i < n; i++) {
				col[i] = m_pos[d*n + i];
			}
			morder(col, n, new_order);


	//		--Perform re-ordering of 'm_nbs' and 'v_id' based on this order.
	//		--Need inverse of v_id for returning results - returned in 'id_order'
			reorderMatrix(m_pos, m_pos_copy, new_order, n, p);
			reorderVec(v_id, v_id_copy, new_order, n);
			morder(v_id, n, id_order);

	//		*********************************************************
	//		--Inner Loop: This is the actual data generation: the 'Get Neighbours' part of the script.
	//		*********************************************************
			for(int i = 0; i < n-1; i++) {

		//		--Insert above and below neighbours from the current order into m_nbs output.
				m_nbs_tmp[i] = v_id[i+1];
				m_nbs_tmp[n + i+1] = v_id[i];

		//		--Calculate metrics by assessing the entire row (1:p)
				for(int c = 0; c < p; c++) {

					//Get position of neighbour in dimension c. By looking at Right neighbour @ n+1, and left
					// neighbour @ n, we can re-use a single distance value, as the only difference will be the sign.
					// we're not concerned with the sign. itmp = distance. Define nb as close:= abs(dist) < 1.
					
					itmp = m_pos[i+1 + c*n] - m_pos[i + c*n];
					((itmp > 1) || (itmp < -1)) ? clsenb = false : clsenb = true;

			//		.....For 'Right' Neighbour................
					if (!clsenb) {
						m_nbs_tmp[i] = 0;
					}
			//		Add square distance to sum of sqs.
					v_tmp[i] += itmp*itmp;

			//		.....Repeat for 'Left' Neighbour............
					if (!clsenb) {
						m_nbs_tmp[n + i+1] = 0;
					}
					v_tmp[i+1] += itmp*itmp;	
				}

	//		*********************************************************		
	//		--End of inner loop
	//		*********************************************************
			}


	//		--Calculate root sum of squared distance and add to root sum of square distance from other
	//		  dimensional orderings. First and last entry only have one neighbour, so to avoid changing the
	//		  denominator later on, we double these. Minimum value to add is 1 to avoid DIV/0 Errors.
			for(int i = 1; i < n-1; i++)
			{
				dtmp = v_tmp[id_order[i]];
				if (dtmp < 1) {
					v_ss[i] +=1;
				}
				else {
					v_ss[i] += sqrt(dtmp);
				}
			}
	//		(first and last - separately to avoid p*n 'if' comparisons in the for loop.)
			dtmp = v_tmp[id_order[0]];
			(dtmp < 1) ? v_ss[0] += 2 : v_ss[0] += 2*sqrt(dtmp);
			dtmp = v_tmp[id_order[n-1]];
			(dtmp < 1) ? v_ss[n-1] += 2 : v_ss[n-1] += 2*sqrt(dtmp);

	//		Clear sum of squares array to start from scratch for next dim.
			for(int i = 1; i <n; i++) {
				v_tmp[i] = 0;
			}

	//		Input neighbours into output array. Need to reorder based on original id now.
			for(int i = 0; i < n; i++)
			{
				m_nbs[2*d*n + i] = m_nbs_tmp[id_order[i]];
				m_nbs[(2*d+1)*n + i] = m_nbs_tmp[id_order[i] + n];
			}
	
	//	*********************************************************		
	//	--End of outer loop
	//	*********************************************************
		}
		
	
	//	*****Final operation: Density Calculation.***************
	//	--Compute density = p/n. If density > phi, then point is interior; type = 1.
		
		for(int i = 0; i < n; i++)
		{
			if (p/v_ss[i] > phi) {
				v_type[i] = 1;
			}
			else {
				v_type[i] = 0;
			}
		}

	delete[] col;
	delete[] new_order;
	delete[] id_order;
	delete[] v_id_copy;
	delete[] m_pos_copy;
	delete[] m_nbs_tmp;
	delete[] v_tmp;
	return;
}