1
0
Fork 0
mirror of https://github.com/hermitcore/libhermit.git synced 2025-03-09 00:00:03 +01:00

add iRCCE examples

This commit is contained in:
Stefan Lankes 2015-10-17 11:58:56 +02:00
parent e339311d05
commit d9a5fca2d4
5 changed files with 860 additions and 6 deletions

View file

@ -1,7 +1,7 @@
ARCH = x86
TARGET=x86_64-hermit
MAKE = make
override STRIP_DEBUG = --strip-unneeded --strip-debug
override STRIP_DEBUG = --strip-debug #--strip-unneeded --strip-debug
KEEP_DEBUG = --only-keep-debug
# Set your own cross compiler tool chain prefix here
@ -43,7 +43,7 @@ endif
default: all
all: stream hg
all: stream hg RCCE_pingping RCCE_pingpong
stream.o: stream.c
@echo [CC] $@
@ -56,6 +56,20 @@ stream: stream.o
$Q$(OBJCOPY_FOR_TARGET) $(STRIP_DEBUG) $@
$Qchmod a-x $@.sym
RCCE_pingping: RCCE_pingping.o
@echo [LD] $@
$Q$(CC_FOR_TARGET) $(LDFLAGS_FOR_TARGET) $(CFLAGS_FOR_TARGET) -o $@ $< -lircce
$Q$(OBJCOPY_FOR_TARGET) $(KEEP_DEBUG) $@ $@.sym
$Q$(OBJCOPY_FOR_TARGET) $(STRIP_DEBUG) $@
$Qchmod a-x $@.sym
RCCE_pingpong: RCCE_pingpong.o
@echo [LD] $@
$Q$(CC_FOR_TARGET) $(LDFLAGS_FOR_TARGET) $(CFLAGS_FOR_TARGET) -o $@ $< -lircce
$Q$(OBJCOPY_FOR_TARGET) $(KEEP_DEBUG) $@ $@.sym
$Q$(OBJCOPY_FOR_TARGET) $(STRIP_DEBUG) $@
$Qchmod a-x $@.sym
hg: hg.o hist.o rdtsc.o run.o init.o opt.o report.o setup.o
@echo [LD] $@
$Q$(CC_FOR_TARGET) $(LDFLAGS_FOR_TARGET) $(CFLAGS_FOR_TARGET) -o $@ $< hist.o rdtsc.o run.o init.o opt.o report.o setup.o
@ -69,7 +83,7 @@ clean:
veryclean:
@echo Propper cleaning benchmarks
$Q$(RM) stream hg *.sym *.o *~
$Q$(RM) stream hg RCCE_pingping RCCE_pingpong *.sym *.o *~
depend:
$Q$(CC_FOR_TARGET) -MM $(CFLAGS_FOR_TARGET) *.c > Makefile.dep

View file

@ -0,0 +1,145 @@
/*
* Copyright 2010 Carsten Clauss, Chair for Operating Systems,
* RWTH Aachen University
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <string.h>
#include <stdio.h>
#include "RCCE.h"
#undef _CACHE_WARM_UP_
#undef _ERROR_CHECK_
#define MAXBUFSIZE 1024*1024*4
#define DEFAULTLEN 1024
#define NUMROUNDS 10000
char send_buffer[MAXBUFSIZE+1];
char recv_buffer[MAXBUFSIZE+1];
char dummy = 0;
int RCCE_APP(int argc, char **argv)
{
int i;
int num_ranks;
int remote_rank, my_rank;
int numrounds = NUMROUNDS;
int maxlen = DEFAULTLEN;
int length;
int round;
double timer;
RCCE_SEND_REQUEST send_request;
RCCE_RECV_REQUEST recv_request;
RCCE_init(&argc, &argv);
my_rank = RCCE_ue();
num_ranks = RCCE_num_ues();
if(argc > 1) numrounds = atoi(argv[1]);
if(numrounds < 1)
{
if(my_rank == 0) fprintf(stderr, "Pingping needs at least 1 round; try again\n");
exit(-1);
}
if(argc > 2) maxlen = atoi(argv[2]);
if(maxlen < 1)
{
if(my_rank == 0) fprintf(stderr, "Illegal message size: %s; try again\n", argv[2]);
exit(-1);
}
else if(maxlen > MAXBUFSIZE)
{
if(my_rank == 0) fprintf(stderr, "Message size %d is too big; try again\n", maxlen);
exit(-1);
}
if(num_ranks != 2)
{
if(my_rank == 0) fprintf(stderr, "Pingping needs exactly two UEs; try again\n");
exit(-1);
}
remote_rank = (my_rank + 1) % 2;
if(my_rank == 0) printf("#bytes\t\tusec\t\tMB/sec\n");
for(length=1; length <= maxlen; length*=2)
{
#ifdef _CACHE_WARM_UP_
for(i=0; i < length; i++)
{
/* cache warm-up: */
dummy += send_buffer[i];
dummy += recv_buffer[i];
}
#endif
/* synchronize before starting PING-PING: */
RCCE_barrier(&RCCE_COMM_WORLD);
for(round=0; round < numrounds+1; round++)
{
#ifdef _ERROR_CHECK_
for(i=0; i < length; i++)
{
send_buffer[i] = (i+length+round) % 127;
}
#endif
/* send PING: */
RCCE_isend(send_buffer, length, remote_rank, &send_request);
/* recv PING: */
RCCE_irecv(recv_buffer, length, remote_rank, &recv_request);
/* wait for completion: */
RCCE_isend_wait(&send_request);
RCCE_irecv_wait(&recv_request);
/* start timer: */
if(round==0) timer = RCCE_wtime();
#ifdef _ERROR_CHECK_
for(i=0; i < length; i++)
{
if(recv_buffer[i] != (i+length+round) % 127)
{
fprintf(stderr, "ERROR: %d VS %d\n", recv_buffer[i], (i+length+round) % 127);
exit(-1);
}
}
#endif
}
/* stop timer: */
timer = RCCE_wtime() - timer;
if(my_rank == 0) printf("%d\t\t%1.2lf\t\t%1.2lf\n", length, timer/(numrounds)*1000000, (length / (timer/(numrounds))) / (1024*1024) );
}
RCCE_finalize();
return 0;
}

View file

@ -0,0 +1,181 @@
/*
* Copyright 2010 Carsten Clauss, Chair for Operating Systems,
* RWTH Aachen University
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <string.h>
#include <stdio.h>
#include "RCCE.h"
#undef _CACHE_WARM_UP_
#undef _USE_SEPARATED_BUFFERS_
#undef _ERROR_CHECK_
#define MAXBUFSIZE 1024*1024*4
#define DEFAULTLEN 1024
#define NUMROUNDS 10000
#ifdef _USE_SEPARATED_BUFFERS_
char send_buffer[MAXBUFSIZE+1];
char recv_buffer[MAXBUFSIZE+1];
#else
#define send_buffer buffer
#define recv_buffer buffer
char buffer[MAXBUFSIZE+1];
#endif
char dummy = 0;
int RCCE_APP(int argc, char **argv)
{
int i;
int num_ranks;
int remote_rank, my_rank;
int numrounds = NUMROUNDS;
int maxlen = DEFAULTLEN;
int length;
int round;
int ircce_mode = 0;
double timer;
RCCE_SEND_REQUEST rcce_send_req;
RCCE_RECV_REQUEST rcce_recv_req;
RCCE_init(&argc, &argv);
my_rank = RCCE_ue();
num_ranks = RCCE_num_ues();
if(argc > 1) numrounds = atoi(argv[1]);
if(numrounds < 1)
{
if(my_rank == 0) fprintf(stderr, "Pingpong needs at least 1 round; try again\n");
exit(-1);
}
if(argc > 2) maxlen = atoi(argv[2]);
if(maxlen < 1)
{
if(my_rank == 0) fprintf(stderr, "Illegal message size: %s; try again\n", argv[2]);
exit(-1);
}
else if(maxlen > MAXBUFSIZE)
{
if(my_rank == 0) fprintf(stderr, "Message size %d is too big; try again\n", maxlen);
exit(-1);
}
if(argc > 3) ircce_mode = 1;
if(num_ranks != 2)
{
if(my_rank == 0) fprintf(stderr, "Pingpong needs exactly two UEs; try again\n");
exit(-1);
}
remote_rank = (my_rank + 1) % 2;
if(my_rank == 0) printf("#bytes\t\tusec\t\tMB/sec\n");
for(length=1; length <= maxlen; length*=2)
{
#ifdef _CACHE_WARM_UP_
for(i=0; i < length; i++)
{
/* cache warm-up: */
dummy += send_buffer[i];
dummy += recv_buffer[i];
}
#endif
/* synchronize before starting PING-PONG: */
RCCE_barrier(&RCCE_COMM_WORLD);
for(round=0; round < numrounds+1; round++)
{
#ifdef _ERROR_CHECK_
for(i=0; i < length; i++)
{
send_buffer[i] = (i+length+round) % 127;
}
#endif
if(my_rank == 0)
{
/* send PING: */
if(ircce_mode) {
RCCE_isend(send_buffer, length, remote_rank, &rcce_send_req);
RCCE_isend_wait(&rcce_send_req);
} else
RCCE_send(send_buffer, length, remote_rank);
/* recv PONG: */
if(ircce_mode) {
RCCE_irecv(recv_buffer, length, remote_rank, &rcce_recv_req);
RCCE_irecv_wait(&rcce_recv_req);
} else
RCCE_recv(recv_buffer, length, remote_rank);
}
else
{
/* recv PING: */
if(ircce_mode) {
RCCE_irecv(recv_buffer, length, remote_rank, &rcce_recv_req);
RCCE_irecv_wait(&rcce_recv_req);
} else
RCCE_recv(recv_buffer, length, remote_rank);
/* send PONG: */
if(ircce_mode) {
RCCE_isend(send_buffer, length, remote_rank, &rcce_send_req);
RCCE_isend_wait(&rcce_send_req);
} else
RCCE_send(send_buffer, length, remote_rank);
}
/* start timer: */
if(round == 0) timer = RCCE_wtime();
#ifdef _ERROR_CHECK_
for(i=0; i < length; i++)
{
if(recv_buffer[i] != (i+length+round) % 127)
{
fprintf(stderr, "ERROR: %d VS %d\n", recv_buffer[i], (i+length+round) % 127);
exit(-1);
}
}
#endif
}
/* stop timer: */
timer = RCCE_wtime() - timer;
if(my_rank == 0) printf("%d\t\t%1.2lf\t\t%1.2lf\n", length, timer/(2.0*numrounds)*1000000, (length / (timer/(2.0*numrounds))) / (1024*1024) );
fflush(stdout);
}
RCCE_finalize();
return 0;
}

View file

@ -43,7 +43,7 @@ endif
default: all
all: hello hello++ hellof jacobi thr_hello
all: hello hello++ hellof jacobi thr_hello RCCE_minimum
hello++: hello++.o
@echo [LD] $@
@ -84,13 +84,20 @@ thr_hello: thr_hello.o
$Q$(OBJCOPY_FOR_TARGET) $(STRIP_DEBUG) $@
$Qchmod a-x $@.sym
RCCE_minimum: RCCE_minimum.o
@echo [LD] $@
$Q$(CC_FOR_TARGET) $(LDFLAGS_FOR_TARGET) $(CFLAGS_FOR_TARGET) -o $@ $< -lircce
$Q$(OBJCOPY_FOR_TARGET) $(KEEP_DEBUG) $@ $@.sym
$Q$(OBJCOPY_FOR_TARGET) $(STRIP_DEBUG) $@
$Qchmod a-x $@.sym
clean:
@echo Cleaning tests
$Q$(RM) hello hello++ hellof jacobi thr_hello *.sym *.o *~
$Q$(RM) hello hello++ hellof jacobi thr_hello RCCE_minimum *.sym *.o *~
veryclean:
@echo Propper cleaning tests
$Q$(RM) hello hello++ hellof jacobi thr_hello *.sym *.o *~
$Q$(RM) hello hello++ hellof jacobi thr_hello RCCE_minimum *.sym *.o *~
depend:
$Q$(CC_FOR_TARGET) -MM $(CFLAGS_FOR_TARGET) *.c > Makefile.dep

View file

@ -0,0 +1,507 @@
/*
* Copyright 2010 Carsten Clauss, Chair for Operating Systems,
* RWTH Aachen University
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "RCCE.h"
#undef _SCCPRAM_PUT_REMOTE_
extern t_vcharp RCCE_malloc(size_t);
extern int RCCE_put(t_vcharp, t_vcharp, int, int);
extern int RCCE_get(t_vcharp, t_vcharp, int, int);
extern int RCCE_acquire_lock(int);
extern int RCCE_release_lock(int);
#define MAX_STEPS 1000*10120
#define OCCURRENCE 100
#undef _TOKEN_PASSING_
#undef _MASTER_CORE_
#undef _MASTER_TREE_
#pragma omp thread_private(stamp_t, nuM_ranks, my_arnk, steps)
#pragma omp thread_private(my_token, global_tokens, remote_token)
#pragma omp thread_private(distance, neighbor, val_array)
typedef long long int stamp_t;
typedef struct _token_t
{
stamp_t steps;
int rank;
int exit;
} token_t;
int num_ranks;
int my_rank;
stamp_t steps;
token_t my_token;
token_t *global_tokens;
int distance = 1;
int neighbor;
volatile unsigned char val_array[RCCE_LINE_SIZE];
token_t* remote_token;
#ifdef _TOKEN_PASSING_
void stop_and_check()
{
#ifndef _SCCPRAM_PUT_REMOTE_
neighbor = RCCE_ue() - distance;
if(neighbor < 0) neighbor = neighbor + RCCE_num_ues();
#else
neighbor = RCCE_ue() + distance;
if( neighbor > RCCE_num_ues() - 1 ) neighbor = neighbor - RCCE_num_ues();
#endif
if(neighbor != RCCE_ue())
{
// do the token-passing:
while(1)
{
#ifndef _SCCPRAM_PUT_REMOTE_
RCCE_get(val_array, (t_vcharp)global_tokens, RCCE_LINE_SIZE, neighbor);
#else
RCCE_get(val_array, (t_vcharp)global_tokens, RCCE_LINE_SIZE, RCCE_ue() );
#endif
remote_token = (token_t*)val_array;
//printf("(%d|%lld) neighbor: %d|%lld / my_token: %d|%lld\n", RCCE_ue(), steps, remote_token->rank, remote_token->steps, my_token.rank, my_token.steps);
if(remote_token->exit)
{
int current = neighbor;
// my current neighbor is atually finished --> determine a new neighbor:
distance++;
#ifndef _SCCPRAM_PUT_REMOTE_
neighbor = RCCE_ue() - distance;
if(neighbor < 0) neighbor = neighbor + RCCE_num_ues();
#else
neighbor = RCCE_ue() + distance;
if( neighbor > RCCE_num_ues() - 1 ) neighbor = neighbor - RCCE_num_ues();
#endif
if(neighbor == RCCE_ue())
{
// there is no other neighbor still running --> go on!
break;
}
else
{
// restart token-passing with new neighbor...
continue;
}
}
if(remote_token->rank == RCCE_ue())
{
// my own rank has rounded:
if(remote_token->steps == steps)
{
// go on!
break;
}
else
{
// update my token:
my_token.steps = steps;
my_token.rank = RCCE_ue();
#ifndef _SCCPRAM_PUT_REMOTE_
RCCE_put((t_vcharp)global_tokens, (t_vcharp)&my_token, RCCE_LINE_SIZE, RCCE_ue());
#else
RCCE_put((t_vcharp)global_tokens, (t_vcharp)&my_token, RCCE_LINE_SIZE, neighbor);
#endif
}
}
else
{
if( (steps < remote_token->steps) || ((steps == remote_token->steps) && (RCCE_ue() < remote_token->rank)) )
{
// update my token:
my_token.steps = steps;
my_token.rank = RCCE_ue();
#ifndef _SCCPRAM_PUT_REMOTE_
RCCE_put((t_vcharp)global_tokens, (t_vcharp)&my_token, RCCE_LINE_SIZE, RCCE_ue());
#else
RCCE_put((t_vcharp)global_tokens, (t_vcharp)&my_token, RCCE_LINE_SIZE, neighbor);
#endif
}
else
{
if( (remote_token->rank != my_token.rank) || (remote_token->steps != my_token.steps) )
{
// forward remote token:
memcpy(&my_token, remote_token, sizeof(token_t));
#ifndef _SCCPRAM_PUT_REMOTE_
RCCE_put((t_vcharp)global_tokens, (t_vcharp)&my_token, RCCE_LINE_SIZE, RCCE_ue());
#else
RCCE_put((t_vcharp)global_tokens, (t_vcharp)&my_token, RCCE_LINE_SIZE, neighbor);
#endif
}
}
}
}
}
}
#else
#if defined(_MASTER_CORE_) || defined(_MASTER_TREE_)
void stop_and_check()
{
while(1)
{
RCCE_get(val_array, (t_vcharp)global_tokens, RCCE_LINE_SIZE, RCCE_ue());
remote_token = (token_t*)val_array;
// printf("RANK %d: %lld\n", my_rank, steps); fflush(stdout); sleep(1);
if(remote_token->exit) break;
}
}
#else
void stop_and_check()
{
int i;
int winner_rank = my_rank;
stamp_t winner_steps = steps;
while(1)
{
winner_rank = my_rank;
winner_steps = steps;
for(i=0; i<num_ranks; i++)
{
RCCE_get(val_array, (t_vcharp)global_tokens, RCCE_LINE_SIZE, i);
remote_token = (token_t*)val_array;
if(remote_token->steps < winner_steps)
{
winner_steps = remote_token->steps;
winner_rank = remote_token->rank;
}
}
if(winner_rank == my_rank) break;
}
}
#endif
#endif
#ifdef _MASTER_CORE_
void one_single_master()
{
int i, j;
int winner_rank;
int winner_flag;
stamp_t winner_steps;
int count;
count = 0;
while(1)
{
winner_flag = 0;
for(i=0,j=0; i<num_ranks - 1; i++)
{
RCCE_get(val_array, (t_vcharp)global_tokens, RCCE_LINE_SIZE, i);
remote_token = (token_t*)val_array;
if( (!j) || (remote_token->steps < winner_steps) )
{
if(remote_token->exit == 0)
{
j=1;
winner_steps = remote_token->steps;
winner_rank = remote_token->rank;
winner_flag = 1;
}
}
}
if(winner_flag)
{
my_token.steps = winner_steps;
my_token.rank = winner_rank;
my_token.exit = 1;
RCCE_put((t_vcharp)global_tokens, (t_vcharp)&my_token, RCCE_LINE_SIZE, winner_rank);
}
count++;
if(count == 1000)
{
RCCE_get(val_array, (t_vcharp)global_tokens, RCCE_LINE_SIZE, num_ranks-1);
remote_token = (token_t*)val_array;
if(remote_token->exit == num_ranks - 1) break;
count = 0;
}
}
}
#endif
#ifdef _MASTER_TREE_
void multiple_masters(int flag)
{
int i;
int winner_rank;
int winner_flag;
stamp_t winner_steps;
int start_rank;
int num_ranks;
int count;
if(flag)
{
start_rank = 32 + (my_rank-40) * 2;
num_ranks = 2;
}
else
{
start_rank = (my_rank - 32) * 4;
num_ranks = 4;
}
RCCE_put((t_vcharp)global_tokens, (t_vcharp)&my_token, RCCE_LINE_SIZE, RCCE_ue());
count = 0;
while(1)
{
winner_flag = 0;
for(i=start_rank; i<start_rank + num_ranks; i++)
{
RCCE_get(val_array, (t_vcharp)global_tokens, RCCE_LINE_SIZE, i);
remote_token = (token_t*)val_array;
if( (i==start_rank) || (remote_token->steps < winner_steps) )
{
winner_steps = remote_token->steps;
winner_rank = remote_token->rank;
winner_flag = 1;
}
}
if(winner_flag)
{
my_token.steps = winner_steps;
my_token.rank = winner_rank;
RCCE_put((t_vcharp)global_tokens, (t_vcharp)&my_token, RCCE_LINE_SIZE, RCCE_ue());
}
count++;
if(count == 1000)
{
RCCE_get(val_array, (t_vcharp)global_tokens, RCCE_LINE_SIZE, 47);
remote_token = (token_t*)val_array;
if(remote_token->exit >= 32) break;
count = 0;
}
}
}
void super_master()
{
int i;
int winner_rank;
int winner_flag;
stamp_t winner_steps;
int start_rank;
int count;
int old_winner_rank = -1;
stamp_t old_winner_steps = 0;
RCCE_put((t_vcharp)global_tokens, (t_vcharp)&my_token, RCCE_LINE_SIZE, RCCE_ue());
while(1)
{
winner_flag = 0;
RCCE_get(val_array, (t_vcharp)global_tokens, RCCE_LINE_SIZE, 44);
remote_token = (token_t*)val_array;
winner_steps = remote_token->steps;
winner_rank = remote_token->rank;
RCCE_get(val_array, (t_vcharp)global_tokens, RCCE_LINE_SIZE, 45);
remote_token = (token_t*)val_array;
if(remote_token->steps < winner_steps)
{
winner_steps = remote_token->steps;
winner_rank = remote_token->rank;
}
if( (winner_steps > old_winner_steps) || ( (winner_steps == old_winner_steps) && (winner_rank != old_winner_rank) ) )
{
winner_flag = 1;
old_winner_rank = winner_rank;
old_winner_steps = winner_steps;
}
if( winner_flag && (winner_rank < 32) && (winner_rank % 2 == RCCE_ue() % 2) )
{
my_token.steps = winner_steps;
my_token.rank = winner_rank;
my_token.exit = 1;
RCCE_put((t_vcharp)global_tokens, (t_vcharp)&my_token, RCCE_LINE_SIZE, winner_rank);
}
count++;
if(count == 1000)
{
RCCE_get(val_array, (t_vcharp)global_tokens, RCCE_LINE_SIZE, 47);
remote_token = (token_t*)val_array;
if(remote_token->exit >= 32) break;
count = 0;
}
}
}
#endif
int RCCE_APP(int argc, char **argv)
{
int i, j;
double timer;
RCCE_init(&argc, &argv);
my_rank = RCCE_ue();
num_ranks = RCCE_num_ues();
srand(my_rank);
global_tokens = (token_t*)RCCE_malloc(RCCE_LINE_SIZE);
my_token.steps = 0;
my_token.exit = 0;
my_token.rank = RCCE_ue();
RCCE_put((t_vcharp)global_tokens, (t_vcharp)&my_token, RCCE_LINE_SIZE, RCCE_ue());
RCCE_barrier(&RCCE_COMM_WORLD);
#ifdef _TOKEN_PASSING_
if(my_rank == 0) printf("MINIMUM started with %d procs and TOKEN PASSING ...\n", num_ranks); fflush(stdout);
#else
#ifdef _MASTER_CORE_
if(my_rank == 0) printf("MINIMUM started with %d procs and MASTER CORE ...\n", num_ranks); fflush(stdout);
#else
#ifdef _MASTER_TREE_
if(my_rank == 0) printf("MINIMUM started with %d procs and MASTER TREE ...\n", num_ranks); fflush(stdout);
#else
if(my_rank == 0) printf("MINIMUM started with %d procs and GLOBAL VIEW ...\n", num_ranks); fflush(stdout);
#endif
#endif
#endif
RCCE_barrier(&RCCE_COMM_WORLD);
timer = RCCE_wtime() - timer;
#ifdef _MASTER_CORE_
if(my_rank == RCCE_num_ues()-1) one_single_master();
else for(steps=0; steps < MAX_STEPS / (num_ranks -1); steps++)
#else
#ifdef _MASTER_TREE_
if(my_rank >= 32)
{
if(my_rank < 40) multiple_masters(0);
else if(my_rank < 46) multiple_masters(1);
else super_master();
}
else for(steps=0; steps < MAX_STEPS / 32; steps++)
#else
for(steps=0; steps < MAX_STEPS / num_ranks; steps++)
#endif
#endif
{
if( (rand() % OCCURRENCE) == 0 )
{
stop_and_check();
}
my_token.steps = steps;
my_token.rank = RCCE_ue();
my_token.exit = 0;
#ifndef _SCCPRAM_PUT_REMOTE_
RCCE_put((t_vcharp)global_tokens, (t_vcharp)&my_token, RCCE_LINE_SIZE, RCCE_ue());
#else
neighbor = RCCE_ue() + distance;
if( neighbor > RCCE_num_ues() - 1 ) neighbor = neighbor - RCCE_num_ues();
RCCE_put((t_vcharp)global_tokens, (t_vcharp)&my_token, RCCE_LINE_SIZE, neighbor);
#endif
}
#if defined(_MASTER_CORE_) || defined(_MASTER_TREE_)
RCCE_acquire_lock(num_ranks-1);
RCCE_get(val_array, (t_vcharp)global_tokens, RCCE_LINE_SIZE, num_ranks-1);
remote_token = (token_t*)val_array;
remote_token->exit++;
RCCE_put((t_vcharp)global_tokens, val_array, RCCE_LINE_SIZE, num_ranks-1);
RCCE_release_lock(num_ranks-1);
#ifdef _MASTER_TREE_
if(my_rank < 32)
{
my_token.steps = steps;
my_token.rank = RCCE_ue();
my_token.exit = 1;
RCCE_put((t_vcharp)global_tokens, (t_vcharp)&my_token, RCCE_LINE_SIZE, RCCE_ue());
}
#endif
#else
my_token.steps = steps;
my_token.rank = RCCE_ue();
my_token.exit = 1;
RCCE_put((t_vcharp)global_tokens, (t_vcharp)&my_token, RCCE_LINE_SIZE, RCCE_ue());
#endif
RCCE_barrier(&RCCE_COMM_WORLD);
timer = RCCE_wtime() - timer;
//printf("EXIT: %d at %lld / count: %d\n", my_rank, steps, remote_token->exit); fflush(stdout);
if(my_rank == 0) printf("MINIMUM finished after %1.3lf sec.\n", timer); fflush(stdout);
RCCE_finalize();
return 0;
}