Exemple #1
0
static int localToRemoteCallback( const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags statusFlags, void *userData )
{
  callbackData *data = (callbackData*)userData;
  SAMPLE *out = (SAMPLE*)outputBuffer;
  SAMPLE *in = (SAMPLE*)inputBuffer;
  (void) timeInfo; /* Prevent unused variable warnings. */
  (void) statusFlags;
  (void) userData;
  SAMPLE downsampled[320];
  unsigned char compressed[6];
  vector<bool> dataBits;
  vector<bool> transcodedBits;

  if( inputBuffer == NULL )
  {
    for( int i=0; i<framesPerBuffer; i++ ) { *out++ = 0; }
  }
  else
  {
    // downsample 1280 samples to 320 samples by taking every 4th sample
    Downsample::Perform(in, downsampled, 1280, 4);

    // compress 320 samples to 6 bytes (48 bits)
    codec2_encode(data->codec2, compressed, downsampled);

    // add the bufferCounter to the dataBits
    bitset<5> bC ( (unsigned long) data->bufferCounter );
    for(int i=0;i<5;i++) { dataBits.push_back(bC[i]);}

    // increment the Buffer Counter used for synchronization
    data->bufferCounter = (data->bufferCounter + 1) % 32;

    // convert and push unsigned chars onto dataBits
    Convert::UnsignedCharToBits(compressed, dataBits, 6);

    // record bits for testing
    data->recordedBits.push_back(dataBits);


    // transcode via IncDec algorithm.
    Transcode::Perform(dataBits, transcodedBits);

    // prep the transmitter
    data->transmitter->setBits(transcodedBits);

    // transmit
    data->transmitter->emitSound(out);
  }

  return paContinue;
}
int main(int argc, char** argv)
{
    if(argc != 4){
        std::cout << "Error! Three arguments m, n and p are needed!" << std::endl;
		return 1;
    }
	
    int m = atoi(argv[1]);
    int n = atoi(argv[2]);
    int p = atoi(argv[3]);    

	
    double elapseTime, elapseTime_single; 

    int myrank, numprocs;

    MPI_Status status;
  
	
    MPI_Init(&argc, &argv);  // 并行开始
	//std::cout << "Start to computing..." << std::endl;
  
	MPI_Comm_size(MPI_COMM_WORLD, &numprocs);  // 获取进程数
    MPI_Comm_rank(MPI_COMM_WORLD, &myrank);  // 获取本进城ID号
 
    if(numprocs < 2){
        std::cout << "Error! There must be more than two processors." << std::endl;
		return 1;
    }
    
    int bm = m / numprocs;
    int bn = n / numprocs;
     
	SCMatrix A(1), B(1), C(1), C_true(1);
	SCMatrix bA(bm,p), bB_send(bn,p), bB_recv(bn,p), bC(bm, bn), bC_send(bm, n);
 	  
    if(myrank == 0){
		SCMatrix A1(m,p), B1(n,p), C1(m,n), C_true1(m,n);

		A = A1; B = B1; C = C1; C_true = C_true1;

		A.init_with_RV();
		B.init_with_RV();    
    }
    MPI_Barrier(MPI_COMM_WORLD);
	//A.print(); B.print();
    
	
    // start to timing
    clock_t start_time = clock();    

    //clock_t t_temp_start = clock();
    MPI_Scatter(&A, bm * p, MPI_DOUBLE, &bA, bm * p, MPI_DOUBLE, 0, MPI_COMM_WORLD);
    MPI_Scatter(&B, bn * p, MPI_DOUBLE, &bB_recv, bn * p, MPI_DOUBLE, 0, MPI_COMM_WORLD);

	int sendTo = (myrank + 1) % numprocs;
	int recvFrom = (myrank - 1 + numprocs) % numprocs;
		
	int circle = 0;
	
	bB_send = bB_recv;
	do{
		bC = bA * bB_recv.transpose();
		
		int blocks_col = (myrank - circle + numprocs) % numprocs;
		for(int i=0; i<bm; i++){
			for(int j=0; j<bn; j++){
				bC_send(i, blocks_col*bn + j) = bC(i, j);
			}
		}

		if(myrank % 2 == 0){
			bB_send = bB_recv;
			MPI_Ssend(&bB_send, bn*p, MPI_DOUBLE, sendTo, circle, MPI_COMM_WORLD);
			MPI_Recv(&bB_recv, bn*p, MPI_DOUBLE, recvFrom, circle, MPI_COMM_WORLD, &status);
		}else{
			MPI_Recv(&bB_recv, bn*p, MPI_DOUBLE, recvFrom, circle, MPI_COMM_WORLD, &status);
			MPI_Ssend(&bB_send, bn*p, MPI_DOUBLE, sendTo, circle, MPI_COMM_WORLD);
			bB_send = bB_recv;
		}
		
		circle++;
    }while(circle < numprocs);

	MPI_Barrier(MPI_COMM_WORLD);
	
	MPI_Gather(&bC_send, bm * n, MPI_DOUBLE, &C, bm * n, MPI_DOUBLE, 0, MPI_COMM_WORLD);
	
    if(myrank == 0){
		int remainAStartId = bm * numprocs;
		int remainBStartId = bn * numprocs;
		
		for(int i=remainAStartId; i<m; i++){
			for(int j=0; j<n; j++){
				double temp=0;
				for(int k=0; k<p; k++){
					temp += A(i,k) * B(j,k);
				}
				C(i,j) = temp;
			}
		}
		
		for(int i=0; i<remainAStartId; i++){
			for(int j=remainBStartId; j<n; j++){
				double temp = 0;
				for(int k=0; k<p; k++){
					temp += A(i,k)*B(j,k);
				}
				C(i,j) = temp;
			}
		}
    }
    
    // end timing
    clock_t end_time = clock();	

    elapseTime = (double)(end_time-start_time) / CLOCKS_PER_SEC;  

    if(myrank == 0){
		//std::cout << "[P_0] m = " << m << ", np = " << numprocs << ", time cost: " << elapseTime  << std::endl;
	    std::cout << "[P_0] Totally cost " << elapseTime << " seconds in parallel procedure." << std::endl;
        
		start_time = clock();
		C_true = A * B.transpose();
        end_time = clock();

		elapseTime_single = double(end_time-start_time) / CLOCKS_PER_SEC;
		std::cout << "[P_0] Totally cost " << elapseTime_single << " seconds with one processor." << std::endl;

        bool b = (C==C_true);
        if(b){
            std::cout << "[P_0] Congradulations! The two results are equal." << std::endl;
        }else{
            std::cout << "[P_0] Bad news! The two results do not match." << std::endl;
			A.print();
			B.print();
			C.print();
			C_true.print();
       }
    }
	
     
    MPI_Finalize(); // 并行结束

    return 0;
}