Beispiel #1
0
/* TODO update description */
int PHS(void *out, size_t outlen, const void *in, size_t inlen, const void *salt, size_t saltlen, unsigned int t_cost, unsigned int m_cost) {
	phs_ctx_t ctx;

	/* *********** initialization steps *********** */

	// derive state size from somewhere
	ctx.state_bytes = pow(2, m_cost+8);       /* we use at least 256 byte as the state */
	ctx.state_words = ctx.state_bytes >> 2;   /* we operate on 32-bit words */
	ctx.inner_rounds = m_cost >> 4;           /* number of times the whole state is overwritten */
	if (ctx.inner_rounds < 2) {               /* use at least two inner rounds! */
		ctx.inner_rounds = 2;
	}
	ctx.outer_rounds = t_cost;                /* number of times we rehash */
	if (ctx.outer_rounds == 0) {              /* use at least one outer round! */
		ctx.outer_rounds = 1;
	}

	/* allocate memory for the full state (32-bit counter + state) and rehashing */
	Dprintf("DEBUG: Allocating %"PRIu64" bytes of memory for prefixed state buffer...\n", (ctx.state_words + 1) * sizeof(uint32_t));
	ctx.stateprefix = (uint32_t *) calloc(ctx.state_words + 1, sizeof(uint32_t));
	Dprintf("DEBUG: Allocating %"PRIu64" bytes of memory for rehashing buffer...\n", ((PHS_REHASH_SIZE/4) + 1) * sizeof(uint32_t));
	ctx.rehashprefix = (uint32_t *) calloc((PHS_REHASH_SIZE/4), sizeof(uint32_t));

	/* set the ctx.state and ctx.rehash pointers to the non-prefixed buffer */
	ctx.state = ctx.stateprefix + 1;
	ctx.rehash = ctx.rehashprefix + 1;

	/* initialize state from pw and salt */
	Dprintf("DEBUG: initializing state with password and salt...\n");
	phs_init(&ctx, salt, in, inlen);

	/* **** end of initialization **** */
	Dprintf("Info : we could wipe the pw and salt now...\n");

	/* *********** Begin DEBUG-only statistics *********** */
#ifdef PHC_DEBUG_STATISTICS
	/* allocate space and clear counter values */
	for (int i = 0; i < PHS_F_COUNT; i++) {
		cnt_idx[i] = 0;
	}
	/* allocate and clear memory for address counters */
	cnt_tgt_addr = (uint64_t*) calloc(ctx.state_words, sizeof(uint64_t));
#endif	
	/* *********** End DEBUG-only statistics *********** */
	
	/* *********** time wasting computation steps *********** */
	for (uint32_t i = 0; i < ctx.outer_rounds; i++) {
		Dprintf("DEBUG: executing outer round: %" PRIu32 " \n", i);
		/* perform multiple calls to function F and scramble the bits in the state */
		phs_upd_state(&ctx);
		/* re-distribute entropy */
		phs_upd_entropy(&ctx);
	}

	/* generate 'outlen' bytes of output and store it in 'out' */
	phs_gen_output(&ctx, outlen, out);

	/* Clean up the memory we allocated */
	Dprintf("DEBUG: freeing state...\n");
	free(ctx.stateprefix);
	Dprintf("DEBUG: freeing rehash...\n");
	free(ctx.rehashprefix);

	/* *********** Begin DEBUG-only statistics *********** */
#ifdef PHC_DEBUG_STATISTICS
	printf("********* Statistics **********\n");
	double rounds = ctx.inner_rounds * ctx.state_words * ctx.outer_rounds;
	printf("Function calls:\n");
	for (int i = 0; i < PHS_F_COUNT; i++) {
		double usage = (cnt_idx[i] / rounds) * 100;
		printf("F[%d]: %07.4lf%% (%" PRIu64 ")\n", i, usage, cnt_idx[i]);
	}
	printf("State usage as [tgt] addresses: \n");
	for (int i = 0; i < ctx.state_words; i++) {
		double tgt_usage = (cnt_tgt_addr[i] / rounds) * 100;
		printf("[%08.6lf%%] ", tgt_usage);
		if (i % 8 == 7) {
			printf("\n");
		}
	}
	printf("Memory used: %" PRIu32 " byte, functions called: %0.0lf\n", ctx.state_bytes, rounds);

	free(cnt_tgt_addr);
#endif	
	/* *********** End DEBUG-only statistics *********** */
	
	return 0;
}
Beispiel #2
0
//---------------------------------------------------------------------------
// mpi_slaving:
//---------------------------------------------------------------------------
int mpi_slaving()
{
    // Declare local variables
    MPI_Datatype MPI_SLAVEINF;	/* Dataype for MPI communications       */
    slaveinfo sl_info;		/* Information structure for slaves     */
    MPI_Status *status;		/* Recv status handler                  */
    int used_size;		/* # of processors used                 */

    long sfN;			/* # of pixels in subfield              */
    float *data = NULL;		/* subfield data burst                  */
    float *winH = NULL;		/* apodisation window for SR calc.      */
    float *winF = NULL;		/* apodisation window for phase rec.    */
    float *mask = NULL;		/* DiffLim Mask                         */
    float *pc = NULL;		/* Phase Consistency                    */

    /* for reallocation: needs to be NULL   */
    int *shifts = NULL;		/* shifts for KT Cross Spectra          */
    /* for reallocation: needs to be NULL   */
    int maxk;			/* number of shifts                     */

    // Triple correlation part
    long *index = NULL;		/* index list for bispectrum vectors    */
    long bs_cnt;		/* # of vectors used                    */
    float *bsc = NULL;		/* complex non-red/red bispectrum       */
    float *wc = NULL;		/* complex non-red/red bs weights       */
    float *p1 = NULL;		/* phase matrix for iterativ reconstr.  */
    float *aphs = NULL;		/* average of low frequencies           */

    // General part
    float *phs = NULL;		/* Phase of reconstructed image         */
    float *amp = NULL;		/* Amplitude of reconstructed image     */
    int c = GO;			/* helpers                              */
    long i;



    // set up status variable for sends and receives
    status = (MPI_Status *) malloc(sizeof(MPI_Status));

    // Set Slaveinfo datatype for MPI sends and receives
    mpi_setslavetype(&MPI_SLAVEINF);

    // Receive number of jobs ...
    MPI_Bcast(&used_size, 1, MPI_INT, 0, MPI_COMM_WORLD);

    // ...and if used_size = NOGO, we are quitting the slave!
    if (used_size == NOGO) {
		// free memory
		MPI_Type_free(&MPI_SLAVEINF);
		free(status);
		// returning NOGO quits the slaves in entry.c
		return NOGO;
    }
    // ...and decide if I am needed
    if (used_size > proc_id) {
	// work until TAG says NOGO
		while (GO) {
			// Receive the data information
			MPI_Recv(&sl_info, 1, MPI_SLAVEINF, 0, MPI_ANY_TAG, MPI_COMM_WORLD, status);

			// Break if shutdown signal was sent
			if (status->MPI_TAG == NOGO)
				break;

			if (status->MPI_TAG == TC) {
			/* First time allocation of memory */
				if (c) {
					// find number of pixels in subfield
					sfN = sl_info.sfsizex * sl_info.sfsizey;
					// allocate memory for data
					data = (float *) malloc(sfN * sl_info.nrofframes * sizeof(float));
					winH = (float *) malloc(sfN * sizeof(float));
					winF = (float *) malloc(sfN * sizeof(float));
					pc = (float *) malloc(sfN * sizeof(float));

					/* Initialise hamming window, fractional hamming & mask */
					hanming(winH, sl_info.sfsizex, sl_info.sfsizey, 0.5);
					frachamming(winF, sl_info.sfsizex, sl_info.sfsizey, sl_info.limApod, 0, NULL);
					// mask is no longer used...
					mask = ellmask(sl_info.sfsizex, sl_info.sfsizey, NULL, sl_info.rad_x, sl_info.rad_y);

					// allocate appropriate memory
					index = bs_init(&bs_cnt, sl_info);

					bsc = (float *) malloc(2 * bs_cnt * sizeof(float));
					wc = (float *) malloc(bs_cnt * sizeof(float));

					// Allocate memory for reconstructed amplitudes & phases
					amp = (float *) malloc(sfN * sizeof(float));
					phs = (float *) malloc(2 * sfN * sizeof(float));
					p1 = (float *) malloc(2 * sfN * sizeof(float));

					// set flag so as to not allocate new memory later
					c = NOGO;
				}
			// initialise amps, phases & phase consistency to zero
				memset(bsc, 0.0, 2 * bs_cnt * sizeof(float));
				memset(wc, 0.0, bs_cnt * sizeof(float));
				memset(amp, 0.0, sfN * sizeof(float));
				memset(phs, 0.0, 2 * sfN * sizeof(float));
				memset(p1, 0.0, 2 * sfN * sizeof(float));
				memset(pc, 0.0, sfN * sizeof(float));

				// finally receive the data
				MPI_Recv(data, sfN * sl_info.nrofframes, MPI_FLOAT, 0, MPI_ANY_TAG, MPI_COMM_WORLD, status);

				// compute mean of burst
				//mean(data, sl_info.sfsizex, sl_info.sfsizey, sl_info.nrofframes, temp);

				/* compute the position of the 'good' average phase parts
				 	 3 is an argument here because we deleted:
				   ((int) (alpha[0] * i_rad) > 3 ?
					(int) (alpha[0] * i_rad) : 3),  	*/
				init_shift(sl_info.sfsizex / 2, sl_info.sfsizey / 2, 3, &maxk, &shifts);

				// create bi-spectrum/weights in non-redundant matrix
				aphs = bs_ave(data, winF, sl_info, index, bs_cnt, bsc, wc, amp, maxk, shifts);

				// set snr-threshold
				bs_snrt(wc, bs_cnt, &sl_info);

				// phase reconstruction
				//   init phase matrices
				phs_init(phs, p1, pc, sl_info, maxk, shifts, aphs);

				//   recursive approach
				rpr(phs, p1, pc, index, bs_cnt, bsc, wc, sl_info);

				//   iterative approach
				for (i = 0; i < sl_info.max_it; i++) {
					iwlspr(phs, p1, pc, bsc, wc, index, bs_cnt, sl_info, maxk);
					if (chkphase(sl_info, phs) < 1.0e-5)
						break;
				}

				// Send back info, so master knows, which subfield burst this was
				// MPI_TAG will indicate whether we are at the end of the process
				MPI_Send(&sl_info, 1, MPI_SLAVEINF, 0, NOGO, MPI_COMM_WORLD);

				// Send back processed data
				MPI_Send(amp, sfN, MPI_FLOAT, 0, NOGO, MPI_COMM_WORLD);
				// send back phase
				MPI_Send(phs, 2 * sfN, MPI_FLOAT, 0, NOGO, MPI_COMM_WORLD);

				// free some memory
				free(shifts);
				shifts = NULL;
				free(aphs);
				aphs = NULL;
			}
		}

		// free memory
		if (data != NULL)
			free(data);
		if (winH != NULL)
			free(winH);
		if (winF != NULL)
			free(winF);
		if (mask != NULL)
			free(mask);
		if (pc != NULL)
			free(pc);
		if (shifts != NULL)
			free(shifts);
		if (amp != NULL)
			free(amp);
		if (phs != NULL)
			free(phs);
		if (index != NULL)
			free(index);
		if (p1 != NULL)
			free(p1);
		if (bsc != NULL)
			free(bsc);
		if (wc != NULL)
			free(wc);
		
		free(status);
		MPI_Type_free(&MPI_SLAVEINF);
		// idle until new data or shutdown Broadcast is sent
		return GO;
    }
    else {
		// free memory
		free(status);
		MPI_Type_free(&MPI_SLAVEINF);
		// idle until new data or shutdown Broadcast is sent
		return GO;
    }
}