Esempio n. 1
0
int main(int argc, char *argv[])
{
  int code = 0, i, j, n, initialruns, scheduledjobs,eig=0;
  powerbag **ppbag = NULL, *pbag;
  double *matcopy = NULL, *scratch = NULL;
  double scale = 1.0;
  int quantity = 1, numworkers = 1, theworker; 
  char gotone;

  pthread_t *pthethread1;
  pthread_mutex_t output;
  pthread_mutex_t *psynchro_array;

  //new variables
  int read_n;
  double* read_matrix;

  if(argc < 2){ 
    printf(" usage: rpower filename [-s scale] [-q quantity] [-w workers] [-e eigenvalues]\n");
    code = 1; goto BACK;
  }

  sigset(SIGINT, &handlesigint);



  for(j = 2; j < argc; j++){
    if (0 == strcmp(argv[j],"-s")){
      j += 1;
      scale = atof(argv[j]);
    }
    else if (0 == strcmp(argv[j],"-q")){
      j += 1;
      quantity = atoi(argv[j]);
    }
    else if (0 == strcmp(argv[j],"-w")){
      j += 1;
      numworkers = atoi(argv[j]);
    }
    else if (0 == strcmp(argv[j],"-e")){
      j += 1;
      eig = atoi(argv[j]);
    }
    else{
      printf("bad option %s\n", argv[j]); code = 1; goto BACK;
    }
  }

  printf("will use scale %g and quantity %d: %d workers\n", scale, quantity,
	 numworkers);

  if( numworkers > quantity ){
    numworkers = quantity; printf(" --> reset workers to %d\n", numworkers);
  }

  deadstatus = (char *) calloc(numworkers, sizeof(char));

  pthread_mutex_init(&output, NULL); /** common to everybody **/


  psynchro_array = (pthread_mutex_t *)calloc(numworkers, sizeof(pthread_mutex_t));
  if(!psynchro_array){
    printf("could not create mutex array\n"); code = NOMEMORY; goto BACK;
  }

  for(j = 0; j < numworkers; j++)
    pthread_mutex_init(&psynchro_array[j], NULL);

  ppbag = (powerbag **)calloc(numworkers, sizeof(powerbag *));
  if(!ppbag){
    printf("could not create bag array\n"); code = NOMEMORY; goto BACK;
  }
  numworkersproxy = numworkers;
  ppbagproxy = ppbag;

  pthethread1 = (pthread_t *)calloc(numworkers, sizeof(pthread_t));
  if(!pthethread1){
    printf("could not create thread array\n"); code = NOMEMORY; goto BACK;
  }

  //read code once
  if(code=PWRread(argv[1],&read_n,&read_matrix)) goto BACK;

  for(j = 0; j < numworkers; j++){
    //if((code = PWRreadnload_new(argv[1], 0, ppbag + j)))
    //  goto BACK;  
      /** inefficient: we should read the data once, and then
		      copy **/
    PWRallocateNload(read_n,j,read_matrix, ppbag + j,eig);
    pbag = ppbag[j];
    pbag->psynchro = &psynchro_array[j];
    pbag->poutputmutex = &output;
    pbag->command = STANDBY;
    pbag->status = PREANYTHING;
    //pbag->ID = j;

    n = pbag->n;

  /** now, allocate an extra matrix and a vector to use in 
      perturbation**/
    /** should really do it in the power code since we are putting them in
	the bag **/
    /*pbag->matcopy = (double *)calloc(n*n, sizeof(double));
    pbag->scratch = (double *)calloc(n, sizeof(double));
    if((!pbag->matcopy) || (!pbag->scratch)){
      printf("no memory for matrices at %d\n", j); code = NOMEMORY; goto BACK;
    }*/
  /** and copy matrix **/
    for(i = 0; i < n*n; i++)
      pbag->matcopy[i] = pbag->matrix[i];

    printf("about to launch thread for worker %d\n", j);

    pthread_create(&pthethread1[j], NULL, &PWR_wrapper, (void *) pbag);
  }

  initialruns = numworkers;
  if (initialruns > quantity) initialruns = quantity;

  for(theworker = 0; theworker < initialruns; theworker++){
    pbag = ppbag[theworker];
    /*    if((code = cheap_rank1perturb(n, pbag->scratch, pbag->matcopy, pbag->matrix, scale)))
	  goto BACK;*/

    pthread_mutex_lock(&output);
    printf("*****master:  worker %d will run experiment %d\n", theworker, j);
    pthread_mutex_unlock(&output);

    /** tell the worker to work **/
    pthread_mutex_lock(&psynchro_array[theworker]);
    pbag->command = WORK;
    pbag->status = WORKING;
    pbag->jobnumber = theworker;
    pbag->itercount = 0;
    pthread_mutex_unlock(&psynchro_array[theworker]);

  }
  scheduledjobs = activeworkers = initialruns;

  while(activeworkers > 0){
    /** check the workers' status **/
    gotone = 0;
    for(theworker = 0; theworker < numworkers; theworker++){

      pthread_mutex_lock(&psynchro_array[theworker]);
      pbag = ppbag[theworker];
      if(pbag->status == DONEWITHWORK){

	pthread_mutex_lock(&output);
	printf("master:  worker %d is done with job %d\n", pbag->ID, pbag->jobnumber);
	printf(" top eigenvalue estimate: %.12e\n", pbag->topeigvalue);
	pthread_mutex_unlock(&output);

	if(scheduledjobs >= quantity){
	  /** tell worker to quit **/
	  pthread_mutex_lock(&output);
	  printf("master: telling worker %d to quit\n", pbag->ID);
	  pthread_mutex_unlock(&output);
	  pbag->command = QUIT;
	  pbag->status = QUIT;
	  --activeworkers;
	}
	else {
	  gotone = 1;
	}
      }
      else if(pbag->status == PREANYTHING){
	pthread_mutex_lock(&output);
	printf("master:  worker %d is available\n", theworker);
	pthread_mutex_unlock(&output);
	gotone = 1;
      }
      else if( (pbag->status == WORKING) && (pbag->itercount > 100000)){
	pbag->command = INTERRUPT;
	pthread_mutex_lock(&output);
	printf("master: telling worker %d to interrupt\n", pbag->ID);
	pthread_mutex_unlock(&output);
      }
      else if(deadstatus[theworker]){
	pthread_mutex_lock(&output);
	printf("master: telling worker %d to quit\n", pbag->ID);
	pthread_mutex_unlock(&output);
	pbag->command = QUIT;
	pbag->status = QUIT;
	--activeworkers;
	/** and let's make sure we don't do it again **/
	deadstatus[theworker] = 0;
      }
      pthread_mutex_unlock(&psynchro_array[theworker]);
      if(gotone) break;
      usleep(10000);
      
    }
    /** at this point we have run through all workers **/

    if(gotone){
    /** if we are here, "theworker" can work **/
      pbag = ppbag[theworker];
      if((code = cheap_rank1perturb(n, pbag->scratch, pbag->matcopy, pbag->matrix, scale)))
	goto BACK;

      pthread_mutex_lock(&output);
      printf("master:  worker %d will run experiment %d\n", theworker, scheduledjobs);
      pthread_mutex_unlock(&output);


      /** tell the worker to work **/
      pthread_mutex_lock(&psynchro_array[theworker]);
      pbag->command = WORK;
      pbag->status = WORKING;
      pbag->itercount = 0;
      pbag->jobnumber = scheduledjobs;
      pthread_mutex_unlock(&psynchro_array[theworker]);

      ++scheduledjobs;
    }
  }



  /*  pthread_mutex_lock(&psynchro_array[theworker]);
  pbag->command = QUIT;
  pthread_mutex_unlock(&psynchro_array[theworker]);*/

  pthread_mutex_lock(&output);
  printf("master:  done with loop\n");
  pthread_mutex_unlock(&output);

  /** actually this is bad -- should wait for the threads to be done --
      but how **/
  for(j = 0; j < numworkers; j++){
    pthread_join(pthethread1[j], NULL);
    pthread_mutex_lock(&output);
    printf("master: joined with thread %d\n", j);
    pthread_mutex_unlock(&output);
    pbag = ppbag[j];
    PWRfreespace(&pbag);
  }
  free(ppbag);
	 
BACK:
  if(matcopy) free(matcopy);
  if(scratch) free(scratch);
  return code;
}
Esempio n. 2
0
void PWRpoweralg_new(powerbag *pbag)
{
  int n, ID;
  double *vector, *newvector, *matrix;  
  int k, waitcount, retcode;
  double error, tolerance,tempsum;
  char letsgo = 0, interrupting, forcedquit = 0;

  ID = pbag->ID;
  n = pbag->n;

  pthread_mutex_lock(pbag->poutputmutex);
  printf("ID %d starts\n", pbag->ID);
  pthread_mutex_unlock(pbag->poutputmutex);


  vector = pbag->vector;
  newvector = pbag->newvector;
  matrix = pbag->matrix;
  tolerance = 1e-20; /** excessive **/
  /*  if (tolerance < 1e-7) tolerance = 1e-7;*/

  for(;;){
    pthread_mutex_lock(pbag->poutputmutex);
    printf(" ID %d in big loop\n", pbag->ID);
    pthread_mutex_unlock(pbag->poutputmutex);

    letsgo = 0;
    waitcount = 0;
    while(letsgo == 0){
      /** wait until WORK signal **/
      usleep(10000);

      pthread_mutex_lock(pbag->psynchro);
      if(pbag->command == WORK){
	letsgo = 1;
      }
      else if(pbag->command == QUIT)
	letsgo = 2;
      pthread_mutex_unlock(pbag->psynchro);

      if (letsgo == 2) 
	goto DONE;

      if(0 == waitcount%20){
	pthread_mutex_lock(pbag->poutputmutex);
	printf("ID %d bag %p: wait %d for signal; right now have %d\n", pbag->ID, (void *) pbag, waitcount, pbag->command);
	pthread_mutex_unlock(pbag->poutputmutex);

      }
      ++waitcount;

    }

    pthread_mutex_lock(pbag->poutputmutex);
    printf("ID %d: got signal to start working\n", pbag->ID);
    pthread_mutex_unlock(pbag->poutputmutex);

    /** let's do the perturbation here **/
    if((retcode = cheap_rank1perturb(n, pbag->scratch, pbag->matcopy, pbag->matrix, 10.0)))
      goto DONE;

    /** initialize vector to random**/
    for(k = 0; k < n; k++) 
      pbag->W0[k] = rand()/((double) RAND_MAX);
      
    for(k = 0; k < n*n; k++) 
      pbag->Qprime[k] = pbag->matrix[k];    
    
    //for each eigenvalue
    for(int i=0;i<pbag->eigvaluecount;i++){
      tempsum=0;
      //assign vector to W0
        for(int cnter = 0; cnter < n; cnter++) 
          pbag->vector[cnter] = pbag->W0[cnter];
      
    for(k = 0; ; k++){

      /*      PWRshowvector(n, vector);*/
      PWRpoweriteration(ID, k, n, vector, newvector, matrix, &pbag->topeigvalue, &error, pbag->poutputmutex);
      if(error < tolerance){
	pthread_mutex_lock(pbag->poutputmutex);
	printf(" ID %d converged to tolerance %g! on job %d at iteration %d\n", ID, tolerance,
	       pbag->jobnumber, k); 
	printf(" ID %d top eigenvalue  %g!\n", ID, pbag->topeigvalue);
	pthread_mutex_unlock(pbag->poutputmutex);

	break;
      }
      pbag->itercount = k;  /** well, in this case we don't really need k **/
      if(0 == k%1000){
	pthread_mutex_lock(pbag->psynchro);

	interrupting = 0;
	if(pbag->command == INTERRUPT || pbag->command == QUIT){
	  pthread_mutex_lock(pbag->poutputmutex);
	  printf(" ID %d interrupting after %d iterations\n", pbag->ID, k);
	  pthread_mutex_unlock(pbag->poutputmutex);

	  interrupting = 1;
	}

	pthread_mutex_unlock(pbag->psynchro);

	if(interrupting)
	  break; /** takes you outside of for loop **/
      }
    } //end of for(k = 0; ; k++)
    
    for(int cnt1 = 0; cnt1 < n; cnt1++)
      for(int cnt2 = 0; cnt2 < n; cnt2++){
        //Qprime creation
        pbag->matrix[cnt1*n + cnt2]+= - pbag->topeigvalue * pbag->vector[cnt1]*pbag->vector[cnt2];        
      }
      
    //w^T * W0
      for(int cnt2 = 0; cnt2 < n; cnt2++)
          tempsum+=pbag->vector[cnt2] * pbag->W0[cnt2];

      for(int cnt2 = 0; cnt2 < n; cnt2++)
       pbag->W0[cnt2] -= tempsum * pbag->vector[cnt2];
       
      pbag->vectortopeigvalue[i] = pbag->topeigvalue;
    }//end of //for each eigenvalue
    
    /** first, let's check if we have been told to quit **/
    pthread_mutex_lock(pbag->psynchro);
    if(pbag->command == QUIT)
      forcedquit = 1;
    pthread_mutex_unlock(pbag->psynchro);

    if(forcedquit)
      break;

    pthread_mutex_lock(pbag->psynchro);
    pbag->status = DONEWITHWORK;
    pbag->command = STANDBY;
    pthread_mutex_unlock(pbag->psynchro);
  }

 DONE:
  pthread_mutex_lock(pbag->poutputmutex);
  printf(" ID %d quitting\n", pbag->ID);
  pthread_mutex_unlock(pbag->poutputmutex);
  
}
Esempio n. 3
0
int main(int argc, char *argv[])
{
  int code = 0, i, j, n;
  powerbag *pbag = NULL;
  double *matcopy = NULL, *scratch = NULL;
  double scale = 1.0;
  int quantity = 1;

  pthread_t thethread1;

  if(argc < 2){ 
    printf(" usage: rpower filename [-s scale] [-q quantity]\n");
    code = 1; goto BACK;
  }

  for(j = 2; j < argc; j++){
    if (0 == strcmp(argv[j],"-s")){
      j += 1;
      scale = atof(argv[j]);
    }
    else if (0 == strcmp(argv[j],"-q")){
      j += 1;
      quantity = atoi(argv[j]);
    }
    else{
      printf("bad option %s\n", argv[j]); code = 1; goto BACK;
    }
  }


  printf("will use scale %g and quantity %d\n", scale, quantity);

  /*  if((code = PWRreadnload(argv[1], &n, &vector, &newvector, &matrix))) 
      goto BACK; */

  if((code = PWRreadnload_new(argv[1], 0, &pbag)))
    goto BACK;

  n = pbag->n;

  /** now, allocate an extra matrix and a vector to use in 
      perturbation **/
  matcopy = (double *)calloc(n*n, sizeof(double));
  scratch = (double *)calloc(n, sizeof(double));
  if((!matcopy) || (!scratch)){
    printf("no memory\n"); code = NOMEMORY; goto BACK;
  }
  /** and copy matrix **/
  for(i = 0; i < n*n; i++)
    matcopy[i] = pbag->matrix[i];

  printf("about to launch thread\n");

  pbag->status = WORKING;  /** is this right??? **/

  if((code = cheap_rank1perturb(n, scratch, matcopy, pbag->matrix, scale)))
    goto BACK;
  pthread_create(&thethread1, NULL, &PWR_wrapper, (void *) pbag);


  /*  PWR_wrapper((void *) pbag);*/

  /*  for(j = 0; j < quantity; j++){
    printf("\n************Experiment %d\n", j);

    PWR_wrapper((void *) pbag);

    printf("top eigenvalue estimate: %.12e\n", pbag->topeigvalue);
  }
  */

  for(;;){
    if(pbag->status == WAITING){
      printf("master:  worker is done\n");
      break;
    }
  }
      
  PWRfreespace(&pbag);

	 
BACK:
  if(matcopy) free(matcopy);
  if(scratch) free(scratch);
  return code;
}