Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
U
uva
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Taddeüs Kroes
uva
Commits
ba58168b
Commit
ba58168b
authored
Apr 18, 2011
by
Sander Mathijs van Veen
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ModSim: Finished code for assignment 4 part 1.
parent
c19decc2
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
303 additions
and
0 deletions
+303
-0
modsim/ass4_sander/part1/Makefile
modsim/ass4_sander/part1/Makefile
+10
-0
modsim/ass4_sander/part1/interval.c
modsim/ass4_sander/part1/interval.c
+90
-0
modsim/ass4_sander/part1/interval.h
modsim/ass4_sander/part1/interval.h
+26
-0
modsim/ass4_sander/part1/main.c
modsim/ass4_sander/part1/main.c
+66
-0
modsim/ass4_sander/part1/main.h
modsim/ass4_sander/part1/main.h
+8
-0
modsim/ass4_sander/part1/master.c
modsim/ass4_sander/part1/master.c
+65
-0
modsim/ass4_sander/part1/master.h
modsim/ass4_sander/part1/master.h
+4
-0
modsim/ass4_sander/part1/slave.c
modsim/ass4_sander/part1/slave.c
+31
-0
modsim/ass4_sander/part1/slave.h
modsim/ass4_sander/part1/slave.h
+3
-0
No files found.
modsim/ass4_sander/part1/Makefile
0 → 100644
View file @
ba58168b
CFLAGS
+=
-std
=
c99
-Wall
-Wextra
-g
-O2
LDFLAGS
+=
-lmpi
MAIN
=
main
OFILES
=
interval.o slave.o master.o main.o
$(MAIN)
:
$(OFILES)
clean
:
rm
-vf
$(MAIN)
$(OFILES)
modsim/ass4_sander/part1/interval.c
0 → 100644
View file @
ba58168b
/*
* Created by Sander van Veen (UvA ID: 6167969)
*/
/* interval is a pointer to a struct used by the functions
* in the file interval.c. As such it constitutes an opaque data type
*/
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <time.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/times.h>
#include <limits.h>
#include "interval.h"
#include <math.h>
/*
* Over the years the number of clock ticks per second has been called by many
* names. The code give here appears to work on most machines. Use MY_CLK_TCK
* to convert the output of times() to seconds.
*/
static
clock_t
MY_CLK_TCK
=
0
;
typedef
struct
interval_t
{
struct
timeval
last_wct
;
/* Used for wall-clock time */
struct
tms
last_cput
;
/* Used for CPU time */
}
interval_t
;
/*
* The function new_interval creates and initialises a new interval_t structure
* and returns a pointer to this structure.
*/
interval
interval_init
(
void
)
{
interval
nw
=
calloc
(
1
,
sizeof
(
interval_t
));
if
(
!
nw
)
return
NULL
;
gettimeofday
(
&
(
nw
->
last_wct
),
NULL
);
times
(
&
(
nw
->
last_cput
));
if
(
!
MY_CLK_TCK
)
MY_CLK_TCK
=
sysconf
(
_SC_CLK_TCK
);
return
nw
;
}
/*
* Free the memory used by the interval pointer and set the pointer to NULL. If
* the pointer is valid, zero is returned, or 1 otherwise.
*/
int
interval_destroy
(
interval
*
intervalPtr
)
{
if
(
intervalPtr
==
NULL
)
return
1
;
free
(
*
intervalPtr
);
*
intervalPtr
=
NULL
;
return
0
;
}
/*
* Returns the wall clock time, user CPU time and system CPU time for the
* calling process and its children consumed since the previous call for the
* specified interval. Returns zero on success, -1 when an invalid pointer is
* passed as argument.
*/
int
interval_time
(
interval
id
,
double
*
wct
,
double
*
ust
,
double
*
syt
)
{
if
(
!
id
||
wct
==
NULL
||
ust
==
NULL
||
syt
==
NULL
)
return
-
1
;
struct
timeval
last_wct
=
id
->
last_wct
;
struct
tms
last_cput
=
id
->
last_cput
;
if
(
interval_destroy
(
&
id
)
)
return
-
1
;
id
=
interval_init
();
*
wct
=
(
id
->
last_wct
.
tv_sec
+
id
->
last_wct
.
tv_usec
/
1e6
)
-
(
last_wct
.
tv_sec
+
last_wct
.
tv_usec
/
1e6
);
*
ust
=
difftime
(
id
->
last_cput
.
tms_utime
,
last_cput
.
tms_utime
)
/
MY_CLK_TCK
;
*
syt
=
difftime
(
id
->
last_cput
.
tms_stime
,
last_cput
.
tms_stime
)
/
MY_CLK_TCK
;
return
0
;
}
modsim/ass4_sander/part1/interval.h
0 → 100644
View file @
ba58168b
/* interval is a pointer to a struct used by the functions
in the file interval.c. As such it constitutes an opaque data type */
typedef
struct
interval_t
*
interval
;
/* the function interval_init creates and initialises a new
interval_t struct and returns its address */
interval
interval_init
(
void
);
/* The function interval_destroy frees the memory for an interval
variable and NULLs its value to prevent accidental reuse.
It returns zero on success, -1 when an invalid pointer
is passed as an argument. */
int
interval_destroy
(
interval
*
intervalPtr
);
/* the function interval_time returns the wall clock time,
user CPU time and system CPU time for the calling process
and its children consumed since the previous call for the
specified interval.
It returns zero on success, -1 when an invalid pointer
is passed as an argument. */
int
interval_time
(
interval
id
,
double
*
wct
,
double
*
ust
,
double
*
syt
);
modsim/ass4_sander/part1/main.c
0 → 100644
View file @
ba58168b
#include <stdlib.h>
#include <stdio.h>
#include <mpi.h>
#include "main.h"
#include "interval.h"
#include "master.h"
#include "slave.h"
#define LIST_SIZE 1000000 // Total items for all tasks (million)
int
test_stride
=
1
;
// Items per task
int
test_current_item
=
0
;
// Position in item list
double
test_list
[
LIST_SIZE
];
// List containing all test items
int
main
(
int
argc
,
char
**
argv
)
{
int
role
;
// Create list of zero values.
for
(
int
i
=
0
;
i
<
LIST_SIZE
;
i
++
)
test_list
[
i
]
=
.
0
;
// Perhaps the user wants a different stride?
if
(
argc
==
2
)
test_stride
=
atoi
(
argv
[
1
]);
// Initialize MPI.
argc
=
1
;
// Reset argc to hide our arguments.
MPI_Init
(
&
argc
,
&
argv
);
// Find out my identity in the default communicator.
MPI_Comm_rank
(
MPI_COMM_WORLD
,
&
role
);
if
(
role
==
0
)
{
int
ntasks
=
master_init
();
// Benchmark
double
wct
,
ust
,
syt
;
interval
start_time
=
interval_init
();
master_run
(
ntasks
,
test_stride
);
(
void
)
interval_time
(
start_time
,
&
wct
,
&
ust
,
&
syt
);
printf
(
"test list has size: %d
\n
"
,
LIST_SIZE
);
printf
(
"real: %.12e
\n
user: %.12e
\n
sys: %.12e
\n
"
,
wct
,
ust
,
syt
);
// Memory clean up
interval_destroy
(
&
start_time
);
master_destroy
(
ntasks
);
}
else
{
slave
(
test_stride
);
}
// Shut down MPI.
MPI_Finalize
();
return
0
;
}
unit_work_t
*
get_next_work_item
(
void
)
{
if
(
test_current_item
+
(
test_stride
-
1
)
<
LIST_SIZE
)
return
NULL
;
return
&
test_list
[
test_current_item
+
test_stride
];
}
void
process_results
(
unit_result_t
result
)
{
// Fill in with whatever is relevant to process the results returned by the
// slave.
}
modsim/ass4_sander/part1/main.h
0 → 100644
View file @
ba58168b
#define WORK_TAG 1
#define DIE_TAG 2
typedef
double
unit_work_t
;
typedef
double
unit_result_t
;
unit_work_t
*
get_next_work_item
(
void
);
void
process_results
(
unit_result_t
result
);
modsim/ass4_sander/part1/master.c
0 → 100644
View file @
ba58168b
#include <mpi.h>
#include "main.h"
#include "master.h"
int
master_init
(
void
)
{
// Find out how many processes there are in the default communicator
int
ntasks
;
MPI_Comm_size
(
MPI_COMM_WORLD
,
&
ntasks
);
return
ntasks
;
}
void
master_run
(
int
ntasks
,
int
items_per_task
)
{
int
rank
;
unit_work_t
*
work
;
unit_result_t
result
;
MPI_Status
status
;
// Seed the slaves; send one unit of work to each slave.
for
(
rank
=
1
;
rank
<
ntasks
;
++
rank
)
{
// Get the next items of work to do
work
=
get_next_work_item
();
// Send it to each rank
MPI_Send
(
work
,
// message buffer
items_per_task
,
// size of data array
MPI_INT
,
// data item is an integer
rank
,
// destination process rank
WORK_TAG
,
// user chosen message tag
MPI_COMM_WORLD
);
// default communicator
}
// Loop over getting new work requests until there is no work to be done.
while
((
work
=
get_next_work_item
())
!=
NULL
)
{
// Receive results from a slave
MPI_Recv
(
&
result
,
// message buffer
1
,
// one data item
MPI_DOUBLE
,
// of type double real
MPI_ANY_SOURCE
,
// receive from any sender
MPI_ANY_TAG
,
// any type of message
MPI_COMM_WORLD
,
// default communicator
&
status
);
// info about the received message
// Send the slave a new work unit
MPI_Send
(
work
,
// message buffer
items_per_task
,
// size of data array
MPI_INT
,
// data item is an integer
status
.
MPI_SOURCE
,
// to who we just received from
WORK_TAG
,
// user chosen message tag
MPI_COMM_WORLD
);
// default communicator
}
// There's no more work to be done, so receive all the outstanding results
// from the slaves.
for
(
rank
=
1
;
rank
<
ntasks
;
++
rank
)
{
MPI_Recv
(
&
result
,
1
,
MPI_DOUBLE
,
MPI_ANY_SOURCE
,
MPI_ANY_TAG
,
MPI_COMM_WORLD
,
&
status
);
}
}
void
master_destroy
(
int
ntasks
)
{
// Tell all slaves to exit by sending an empty message with the DIE_TAG.
for
(
int
rank
=
1
;
rank
<
ntasks
;
++
rank
)
{
MPI_Send
(
0
,
0
,
MPI_INT
,
rank
,
DIE_TAG
,
MPI_COMM_WORLD
);
}
}
modsim/ass4_sander/part1/master.h
0 → 100644
View file @
ba58168b
int
master_init
(
void
);
void
master_run
(
int
ntasks
,
int
items_per_task
);
void
master_destroy
(
int
ntasks
);
modsim/ass4_sander/part1/slave.c
0 → 100644
View file @
ba58168b
#include <mpi.h>
#include "main.h"
#include "slave.h"
void
slave
(
int
items_per_task
)
{
for
(;;)
{
unit_work_t
work
;
MPI_Status
status
;
/* Receive a message from the master */
MPI_Recv
(
&
work
,
items_per_task
,
MPI_INT
,
0
,
MPI_ANY_TAG
,
MPI_COMM_WORLD
,
&
status
);
/* Check the tag of the received message. */
if
(
status
.
MPI_TAG
==
DIE_TAG
)
return
;
/* Do the work */
unit_result_t
result
=
do_work
(
&
work
,
items_per_task
);
/* Send the result back */
MPI_Send
(
&
result
,
1
,
MPI_DOUBLE
,
0
,
0
,
MPI_COMM_WORLD
);
}
}
unit_result_t
do_work
(
unit_work_t
*
work
,
int
items_per_task
)
{
// Fill in with whatever is necessary to process the work and generate a
// result.
return
.
0
;
}
modsim/ass4_sander/part1/slave.h
0 → 100644
View file @
ba58168b
void
slave
(
int
items_per_task
);
unit_result_t
do_work
(
unit_work_t
*
work
,
int
items_per_task
);
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment