-
Notifications
You must be signed in to change notification settings - Fork 21
Expand file tree
/
Copy pathEx01_HelloWorld.jdf
More file actions
153 lines (130 loc) · 3.43 KB
/
Ex01_HelloWorld.jdf
File metadata and controls
153 lines (130 loc) · 3.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
extern "C" %{
/**
* This second example shows how to create a simple jdf that has only one single task.
* JDF syntax
* parsec_JDFNAME_New()
* parsec_context_add_taskpool()
* parsec_data_collection_init()
*
* Can play with the HelloWorld bounds to show embarissingly parallel algorithm.
*
* @version 4.0
* @email parsec-users@icl.utk.edu
*
*/
#include "parsec.h"
%}
/**
* HelloWorld task that is performed by the owner of taskdist(k)
*
* A task always needs at least:
* 1) an execution space, even if only one task exists. In this case, we just
* use a variable k that varies from 0 to 0 included.
* 2) a task placement/distribution that is given through a descriptor
* 3) one flow READ, WRITE, RW or CTL with a name and some input (<-) / output
* (->) dependencies
*
*/
HelloWorld(k)
k = 0 .. 0
/**
* Here we define which process will execute the task, this is explained in
* further details in following examples
*/
: taskdist( k )
/**
* A task has a finite number of input/output, and needs at least one input even
* if this one is not used. We start here by a task that doesn't use
* information, so we have only one 'flow' named A that receives NULL.
*/
READ A <- NULL
/**
* This is the body of the task that will be executed by one of the thread in the
* engine.
*/
BODY
{
printf("HelloWorld %d\n", k);
}
END
extern "C" %{
static uint32_t
rank_of(parsec_data_collection_t *desc, ...)
{
(void)desc;
return 0;
}
static int32_t
vpid_of(parsec_data_collection_t *desc, ...)
{
(void)desc;
return 0;
}
static parsec_data_key_t
data_key(parsec_data_collection_t *desc, ...)
{
int k;
va_list ap;
(void)desc;
va_start(ap, desc);
k = va_arg(ap, int);
va_end(ap);
return (uint64_t)k;
}
int main(int argc, char *argv[])
{
parsec_context_t* parsec;
int rc;
int rank, world;
parsec_data_collection_t taskdist;
parsec_taskpool_t *tp;
#if defined(PARSEC_HAVE_MPI)
{
int provided;
MPI_Init_thread(&argc, &argv, MPI_THREAD_SERIALIZED, &provided);
}
MPI_Comm_size(MPI_COMM_WORLD, &world);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
#else
world = 1;
rank = 0;
#endif
parsec = parsec_init(&argc, &argv);
/**
* See Ex03_ChainMPI.jdf for explanation
*/
parsec_data_collection_init(&taskdist, world, rank);
taskdist.rank_of = rank_of;
taskdist.vpid_of = vpid_of;
taskdist.data_key = data_key;
/**
* Let's create the taskpool that contains the description of the algorithm to
* run.
* The prototype of the parsec_Ex01_HelloWorld_new() is automatically
* generated and included in the generated .h file Ex01_HelloWorld.h
*/
tp = (parsec_taskpool_t*)parsec_Ex01_HelloWorld_new(&taskdist);
/**
* Let's submit this taskpool to the runtime and wait for the completion
*/
rc = parsec_context_add_taskpool( parsec, tp );
PARSEC_CHECK_ERROR(rc, "parsec_context_add_taskpool");
rc = parsec_context_start(parsec);
PARSEC_CHECK_ERROR(rc, "parsec_context_start");
rc = parsec_context_wait(parsec);
PARSEC_CHECK_ERROR(rc, "parsec_context_wait");
/**
* We are done, time to cleanup the taskpool.
*/
parsec_taskpool_free(tp);
/**
* See Ex03_ChainMPI.jdf for explanation
*/
parsec_data_collection_destroy(&taskdist);
parsec_fini(&parsec);
#if defined(PARSEC_HAVE_MPI)
MPI_Finalize();
#endif
return 0;
}
%}