Exemplo n.º 1
0
void LTSor::produceOutput() {

	// wait for the input producer to flag us.
	tuple* tmpFlag = make_tuple("s", SOR_FLAG);
	tuple* flag = get_tuple(tmpFlag, &ctx);

	// grab the solution tuple and copy it to the output
	tuple *templateSolutionTuple = make_tuple("s?", SOLUTION_VECTOR);
	tuple *solutionTuple = read_tuple(templateSolutionTuple, &ctx);
	memcpy(outputs[0],
		solutionTuple->elements[1].data.s.ptr,
		solutionTuple->elements[1].data.s.len);

	// remove the tuple synch lock from tuple space
	tuple *synchLock = make_tuple("s", SYNCH_LOCK);
	get_tuple(synchLock, &ctx);

	// clean-up
	destroy_tuple(tmpFlag);
	destroy_tuple(flag);
	destroy_tuple(templateSolutionTuple);
	destroy_tuple(solutionTuple);
	destroy_tuple(synchLock);

}
Exemplo n.º 2
0
void LTRandmat::produceOutput() {

	// tuple template
	tuple *recv = make_tuple("s??", "randmat done");

	// grab output pointer locally.
	IntMatrix output = (IntMatrix) outputs[0];

	// grab all of the mandelbrot computations from the workers,
	// in an unspecified order.
	int computations = RANDMAT_NR;
	while (computations > 0) {

		// get the tuple and copy it into the matrix.
		tuple* received = get_tuple(recv, &ctx);
		memcpy(
			&MATRIX_RECT_NC(output, received->elements[1].data.i, 0, RANDMAT_NC),
			received->elements[2].data.s.ptr,
			received->elements[2].data.s.len);
		computations--;
		destroy_tuple(received);

	}

	// get rid of randmat state from tuple space
	tuple *tmpInit = make_tuple("s?", "randmat state");
	destroy_tuple(get_tuple(tmpInit, &ctx));

	// destroy the template tuple
	destroy_tuple(recv);

}
Exemplo n.º 3
0
void LTRandmat::setup() {

    IntVector state = NEW_VECTOR_SZ(INT_TYPE, RANDMAT_NR);

    // generate first column values
    VECTOR(state, 0) = RAND_SEED % RAND_M;
    for (index_t row = 1; row < RANDMAT_NR; ++row) {
      VECTOR(state, row) = next(VECTOR(state, row - 1));
    }

    // generate the A and C values for the next(k) method.
    aPrime = RANDMAT_A;
    cPrime = 1;
    for (index_t i = 1; i < RANDMAT_NR; ++i) {
      cPrime = (cPrime + aPrime) % RAND_M;
      aPrime = (aPrime * RANDMAT_A) % RAND_M;
    }
    cPrime = (cPrime * RANDMAT_C) % RAND_M;

    // emit the state vector to the tuple space.
    tuple *init = make_tuple("ss", "randmat state", "");
    init->elements[1].data.s.len = sizeof(INT_TYPE) * RANDMAT_NR;
    init->elements[1].data.s.ptr = (char*) state;
    put_tuple(init, &ctx);
    destroy_tuple(init);

}
Exemplo n.º 4
0
void LTRandmat::work() {

	tuple *recv = make_tuple("s?", REQUEST);
	tuple *tmpInit = make_tuple("s?", "randmat state");
	tuple *init = NULL;
	IntVector initVector = NULL;
	
	// satisfy randmat requests.
	while (1) {

		// block until we receive a tuple.
		tuple* gotten = get_tuple(recv, &ctx);

		// grab a copy of the initializer, tuple if we haven't already
		if (!init) {
			init = read_tuple(tmpInit, &ctx);
			initVector = (IntVector) init->elements[1].data.s.ptr;
		}

		// copy over row co-ordinate of the computation; create
		// a buffer for the results of the computation.
		size_t row = gotten->elements[1].data.i;
		tuple *send = make_tuple("sis", "randmat done", row, "");
		IntVector buffer = (IntVector) NEW_VECTOR_SZ(INT_TYPE, RANDMAT_NC);
		send->elements[2].data.s.len = sizeof(INT_TYPE) * RANDMAT_NC;
		send->elements[2].data.s.ptr = (char*) buffer;

		// perform the actual computation for this row.
		buffer[0] = VECTOR(initVector, row);
		for (int x = 1; x < RANDMAT_NC; ++x) {
			buffer[x] = (aPrime * buffer[x-1] + cPrime) % RAND_M;
		}
	
		// send off the new tuple and purge local memory of the one we got
		put_tuple(send, &ctx);
		destroy_tuple(gotten);
		destroy_tuple(send);
		delete[] buffer;

	}

	// TODO destroy the template tuples; must send tuples for this
//	destroy_tuple(recv);

}
Exemplo n.º 5
0
void LTSor::consumeInput() {

	// create a tuple synch lock
	tuple *synchLock = make_tuple("s", SYNCH_LOCK);
	put_tuple(synchLock, &ctx);

	// Initialise. note that as these can run in processes, the
	// solution vector must live in tuple space to be communicated
	// between the workers. Setting the solution variable is LOCAL ONLY
	Matrix matrix = (Matrix) inputs[0];
	Vector target = (Vector) inputs[1];
	Vector solution = (Vector) outputs[0];
	for (index_t r = 0; r < SOR_N; ++r) {
		VECTOR(solution, r) = 1.0;
	}

	// put a tuple for the solution vector into tuple space
	tuple *solutionTuple = make_tuple("ss", SOLUTION_VECTOR);
	solutionTuple->elements[1].data.s.len = sizeof(solution);
	solutionTuple->elements[1].data.s.ptr = (char*) solution;

	// loop until we get the desired tolerance
	real maxDiff = (real)(2 * SOR_TOLERANCE);
	for (index_t t = 0; (t < SOR_MAX_ITERS) && (maxDiff >= SOR_TOLERANCE); t++) {

		maxDiff = 0.0;
		for (index_t r = 0; r < SOR_N; ++r) {

			// compute sum
			real sum = solutionSum(r);

			// calculate new solution
			real oldSolution = VECTOR(solution, r);
			VECTOR(solution, r) = (real)(
				(1.0 - SOR_OMEGA) * oldSolution +
				SOR_OMEGA * (VECTOR(target, r) - sum) / MATRIX_SQUARE_N(matrix, r, r, SOR_N)
			);

			// refresh the solution vector in tuple-space
			tuple *solutionBlank = make_tuple("s?", SOLUTION_VECTOR);
			get_tuple(solutionBlank, &ctx);
			put_tuple(solutionTuple, &ctx);
			destroy_tuple(solutionBlank);

			// compute difference
			real diff = (real) fabs((double)(oldSolution - VECTOR(solution, r)));
			if (diff > maxDiff) {
				maxDiff = diff;
			}
		}
	}

	// flag the output producer.
	put_tuple(make_tuple("s", SOR_FLAG), &ctx);

}
Exemplo n.º 6
0
void LTMandel::consumeInput() {

	// send off a mandelbrot request for each grid row.
	for (size_t y = 0; y < MANDEL_NR; ++y) {
		tuple *send = make_tuple("si", "mandel request");
		send->elements[1].data.i = y;
		put_tuple(send, &ctx);
		destroy_tuple(send);
	}
	
}
Exemplo n.º 7
0
void LTMandel::work() {

	tuple *recv = make_tuple("s?", "mandel request");
	
	// 2D delta between calculated points
	real dX = MANDEL_DX / (MANDEL_NC - 1);
	real dY = MANDEL_DY / (MANDEL_NR - 1);

	// satisfy mandelbrot requests.
	while (1) {

		// block until we receive a tuple.
		tuple* gotten = get_tuple(recv, &ctx);

		// copy over row co-ordinate of the computation; create
		// a buffer for the results of the computation.
		tuple *send = make_tuple("sis", "mandel done", gotten->elements[1].data.i, "");
		int* buffer = (int*) malloc(sizeof(int) * MANDEL_NC);
		send->elements[2].data.s.len = sizeof(int) * MANDEL_NC;
		send->elements[2].data.s.ptr = (char*) buffer;

		// perform the actual computation for this row.
		double rY = MANDEL_Y0 + dY * send->elements[1].data.i;
		double rX = MANDEL_X0;
		for (int x = 0; x < MANDEL_NC; ++x, rX += dX) {
			buffer[x] = mandelCalc(rX, rY);
		}
	
		// send off the new tuple and purge local memory of the one we gotten
		put_tuple(send, &ctx);
		destroy_tuple(gotten);
		destroy_tuple(send);

	}

	// TODO destroy the template tuples; must send tuples for this
//	destroy_tuple(send);
//	destroy_tuple(recv);

}
Exemplo n.º 8
0
void LTRandmat::consumeInput() {

	// create the first, seed column
	setup();

	// tuple template
	tuple *send = make_tuple("si", REQUEST, 0);

	// send off a request for each grid row.
	for (size_t y = 0; y < RANDMAT_NR; ++y) {
		send->elements[1].data.i = y;
		put_tuple(send, &ctx);
	}
	
	// destroy the template tuple
	destroy_tuple(send);

}
Exemplo n.º 9
0
real LTSor::solutionSum(index_t row) {

	// tuple template.
	tuple *send = make_tuple("sii", "sor request");

	// create an "rows reporting" tuple, so that we
	// know when the computation should end.
	tuple *rowsReporting = make_tuple("si", ROWS_DONE, 0);
	put_tuple(rowsReporting, &ctx);

	// create a sum tuple
	tuple *sumTuple = make_tuple("sd", SOLUTION_SUM, 0.0);
	put_tuple(sumTuple, &ctx);

	// split points, based on a cluster size of the square-root of the
	// number of elements in the solution vector.
	index_t skip = (size_t) sqrt((real) SOR_N);
	for (index_t pos = 0; pos < SOR_N; pos += skip) {
		send->elements[1].data.i = pos;
		send->elements[2].data.i = std::min(pos + skip, SOR_N);
		put_tuple(send, &ctx);
	}

	// wait for all the rows to be consumed
	rowsReporting->elements[1].data.i = SOR_N;
	get_tuple(rowsReporting, &ctx);

	// get the sum of the tuple-space op
	destroy_tuple(sumTuple);
	sumTuple = make_tuple("s?", SOLUTION_SUM);
	get_tuple(sumTuple, &ctx);

	// return the result
	return sumTuple->elements[1].data.d;

}
Exemplo n.º 10
0
/**
 * Put out requests to have FFT operations done, and measure how
 * long it takes to get the results back.
 */
int
main(int argc, char *argv[])
{
	struct tuple *s, *t, *u;
	int i, j, iters = 0;
	int r1[PARALLEL], r2[PARALLEL], r3[PARALLEL];
	double x[N], y[N], mult;
	struct timeval T0, T1;
	int rndsock;
	struct context ctx;

	if (get_server_portnumber(&ctx)) {
		if (argc < 3) {
			/* help message */
			fprintf(stderr,
				"Usage: %s <server> <portnumber>\n", argv[0]);
			exit(1);
		}
		strcpy(ctx.peername, argv[1]);
		ctx.portnumber = atoi(argv[2]);
	}

	rndsock = open("/dev/urandom", O_RDONLY);
	mult = 1.0 / pow(2.0, 31);
	for (i = 0; i < N; i++) {
		x[i] = mult * random_int();
		y[i] = mult * random_int();
	}

	s = make_tuple("siiis#s#", "fft",
		       0, 0, 0, x, N * sizeof(double), y, N * sizeof(double));

	t = make_tuple("siii??", "fft done", 0, 0, 0);

	gettimeofday(&T0, NULL);

	while (1) {

		for (j = 0; j < PARALLEL; j++) {
			r1[j] = random_int();
			r2[j] = random_int();
			r3[j] = random_int();
			s->elements[1].data.i = r1[j];
			s->elements[2].data.i = r2[j];
			s->elements[3].data.i = r3[j];
			if (put_tuple(s, &ctx)) {
				perror("put_tuple failed");
				exit(1);
			}
		}

		for (j = 0; j < PARALLEL; j++) {
			t->elements[1].data.i = r1[j];
			t->elements[2].data.i = r2[j];
			t->elements[3].data.i = r3[j];
			u = get_tuple(t, &ctx);
			if (u == NULL) {
				perror("get_tuple failed");
				exit(1);
			}
		}

		gettimeofday(&T1, NULL);
		iters += PARALLEL;
		printf("%f\n", TIMEVAL_DIFF(T0, T1) / iters);
	}

	close(rndsock);
	destroy_tuple(s);
	destroy_tuple(t);
	destroy_tuple(u);

	return 0;
}
Exemplo n.º 11
0
void LTSor::work() {

	// tuple templates
	tuple *synchLock = make_tuple("s", SYNCH_LOCK);
	tuple *recv = make_tuple("s??", "sor request");

	// grab pointers locally.
	Matrix matrix = (Matrix) inputs[0];

	while (1) {

		// block until we receieve a tuple.
		tuple* gotten = get_tuple(recv, &ctx);
		index_t row = gotten->elements[1].data.i;
		index_t start = gotten->elements[2].data.i;
		index_t stop = gotten->elements[3].data.i;

		// grab the solution tuple
		tuple *templateSolutionTuple = make_tuple("s?", SOLUTION_VECTOR);
		tuple *solutionTuple = read_tuple(templateSolutionTuple, &ctx);
		destroy_tuple(templateSolutionTuple);
		Vector solution = (Vector) solutionTuple->elements[1].data.s.ptr;

		// sum part of the matrix row with the corresponding elements
		// in the solution vector.
		real sum = 0.0;
		for (index_t col = start; col < stop; ++col) {
			if (col != row) {
				sum += MATRIX_SQUARE_N(matrix, row, col, SOR_N) * VECTOR(solution, col);
			}
		}

		// purge local memory of the tuple we received
		destroy_tuple(gotten);

		// Now, we combine the results from these elements with the "world".
		// enter the critical section
		get_tuple(synchLock, &ctx);

			// combine results with master copy (sum)
			tuple *tmpSum = make_tuple("s?", SOLUTION_SUM);
			tuple *tupleSum = get_tuple(tmpSum, &ctx);
			tmpSum->elements[1].data.d = sum + tupleSum->elements[1].data.d;
			put_tuple(tmpSum, &ctx);
			destroy_tuple(tmpSum);
			destroy_tuple(tupleSum);

			// record the number of rows reporting
			tuple *templateRowsReporting = make_tuple("s?", ROWS_DONE);
			tuple *rowsReporting = get_tuple(templateRowsReporting, &ctx);
			rowsReporting->elements[1].data.i += (stop - start);
			put_tuple(rowsReporting, &ctx);
			destroy_tuple(templateRowsReporting);
			destroy_tuple(rowsReporting);

		// leave the critical section
		put_tuple(synchLock, &ctx);

	}

}
Exemplo n.º 12
0
/**
 * Handle GETs and READs, both blocking and non-blocking.
 */
static void
handle_get_read(struct context *ctx,
		struct tuple *s, int remove, int blocking)
{
	struct ttuple *p;
	int clientnr = ctx - client_list;

#if 0
	GETLOG;
	LOGPRINTF("%s(%d) wants a tuple:", ctx->peername, ctx->id);
	LOGTUPLE(s);
	YIELDLOG;
#endif
	while (1) {
		status_list[clientnr]='a';
		GETACCESS;
		for (p = first_message; p != NULL; p = p->next) {
			if (tuples_match(p->tuple, s)) {
				if (remove) {
					remove_message_from_space(p);
				}
				YIELDACCESS;
				GETLOG;
				LOGPRINTF("%s(%d) %s a tuple:", ctx->peername, ctx->id, (remove)?"gets":"reads");
				LOGTUPLE(p->tuple);
				YIELDLOG;
				if (send_tuple(ctx, p->tuple)) {
					PRINTF("send_tuple failed\n");
					/* Assume the client died while blocked.
					 * If the tuple was removed, put it back.
					 * Otherwise just kill this thread.
					 */
					LOGPRINTF("send_tuple failed\n");
					LOGTUPLE(s);
					DBGPRINTF("remove=%d\n", remove);
					if (remove) {
						add_tuple_to_space(p->tuple);
						destroy_tuple(s);
						return;
					}
				}
				if (remove) {
					destroy_tuple(p->tuple);
				}
				destroy_tuple(s);
				return;
			}
		}

#if 0
		GETLOG;
		LOGPRINTF("Socket %d couldn't find a match for ", ctx->sock);
		LOGTUPLE(s);
		YIELDLOG;
#endif

		YIELDACCESS;
		if (blocking) {
			/* wait for a tuple that might match */
#ifdef USE_SEMA
			num_blocked++;
			if (sem_wait(&blocked_sem))
                          perror("sem_wait");
#else
			status_list[clientnr]='m';
			if (pthread_mutex_lock(&blocked_mutex))
				perror("mutex_lock");
			status_list[clientnr]='b';
			if (pthread_cond_wait(&blocked_cond, &blocked_mutex))
				perror("cond_wait");
			status_list[clientnr]='u';
			if (pthread_mutex_unlock(&blocked_mutex))
				perror("mutex_unlock");
#endif
		}
		else {
			/* don't wait, return a failure code */
			int ack = -1;
			if (send_chunk(ctx, (char *) &ack, sizeof(int)))
			{
				perror("Cannot send -1 return code");
			}
			return;
		}
	}
}