PULSAR  0.1
Parallel Unified Linear Algebra with Systolic Arrays
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros
prt_vsa.c
Go to the documentation of this file.
1 
11 #include "prt_vsa.h"
12 
13 extern int prt_tuple_equal(void *tuple_a, void *tuple_b);
14 extern unsigned int prt_tuple_hash(void *tuple);
15 
17 
28  int num_threads, void *global_store, int (*vdp_to_core)(int*, void*, int))
29 {
30  // Allocate the VSA.
31  prt_vsa_t *vsa = (prt_vsa_t*)malloc(sizeof(prt_vsa_t));
32  prt_assert(vsa != NULL, "malloc failed");
33 
34  // Init the VSA.
35  MPI_Comm_rank(MPI_COMM_WORLD, &vsa->node_rank);
36  MPI_Comm_size(MPI_COMM_WORLD, &vsa->num_nodes);
37  vsa->num_threads = num_threads;
38  vsa->num_cores = vsa->num_nodes*vsa->num_threads;
39  vsa->global_store = global_store;
40  vsa->vdp_to_core = vdp_to_core;
41 
42  // Init config & proxy.
43  vsa->config = prt_config_new();
44  vsa->proxy = prt_proxy_new(num_threads);
45  vsa->proxy->vsa = vsa;
46 
47  // Init pthreads.
48  pthread_attr_init(&vsa->thread_attr);
49  pthread_attr_setscope(&vsa->thread_attr, PTHREAD_SCOPE_SYSTEM);
50  pthread_setconcurrency(vsa->num_threads+1);
51 
52  int i;
53  // Initialize the threads.
54  vsa->thread = (prt_thread_t**)malloc(vsa->num_threads*sizeof(prt_thread_t*));
55  prt_assert(vsa->thread != NULL, "malloc failed");
56  for (i = 0; i < vsa->num_threads; i++) {
57  vsa->thread[i] = prt_thread_new(i, vsa->node_rank*vsa->num_threads+i);
58  vsa->thread[i]->vsa = vsa;
59  }
60 
61  // Initialize the VDPs hash.
62  int nbuckets = PRT_VSA_MAX_VDPS_PER_NODE;
64 
65  // Allocate the array of channel lists.
66  vsa->channel_lists = (icl_list_t**)calloc(vsa->num_nodes, sizeof(icl_list_t*));
67  prt_assert(vsa->channel_lists != NULL, "malloc failed");
68 
69  // Allocate counters for channel tags.
70  vsa->channel_tags = (int*)calloc(vsa->num_nodes, sizeof(int));
71  prt_assert(vsa->channel_tags != NULL, "malloc failed");
72 
73  // Return the VSA.
74  return vsa;
75 }
76 
78 
84 {
85  int i;
86  // Pthreads cleanup.
87  pthread_attr_destroy(&vsa->thread_attr);
88  for (i = 0; i < vsa->num_threads; i++)
89  prt_thread_delete(vsa->thread[i]);
90  free(vsa->thread);
91 
92  // Delete config & proxy.
94  prt_proxy_delete(vsa->proxy);
95 
96  // Destroy the VDPs hash.
97 // icl_hash_destroy(vsa->vdps_hash, free, (void(*)(void*))prt_vdp_delete);
98  icl_hash_destroy(vsa->vdps_hash, free, (void(*)(void*))NULL);
99 
100  // Destroy the channel lists.
101  for (i = 0; i < vsa->num_nodes; i++)
102  if (vsa->channel_lists[i] != NULL) {
103  int status = icl_list_destroy(
104  vsa->channel_lists[i], (void(*)(void*))prt_channel_delete);
105  prt_assert(status == 0, "icl_list_destroy failed");
106  }
107 
108  // Free the array of lists.
109  free(vsa->channel_lists);
110  // Free the tag counters.
111  free(vsa->channel_tags);
112 
113  // Free the VSA.
114  free(vsa);
115 }
116 
118 
128 {
129  int i;
130  // Check arguments.
131  prt_assert(vsa != NULL, "NULL VSA");
132  prt_assert(vdp != NULL, "NULL VDP");
133 
134  // Compute global core number and process rank.
135  int core = vsa->vdp_to_core(vdp->tuple, vsa->global_store, vsa->num_cores);
136  int node_rank = core / vsa->num_threads;
137 
138  // IF VDP in this node.
139  if (node_rank == vsa->node_rank)
140  prt_vsa_vdp_insert_local(vsa, vdp, core, node_rank);
141  else
142  prt_vsa_vdp_track_tags_remote(vsa, vdp, node_rank);
143 }
144 
145 
146 
148  prt_vsa_t *vsa, prt_vdp_t *vdp, int core, int node_rank)
149 {
150  // Insert in the VSA's VDP hash.
151  icl_entry_t *entry = icl_hash_insert(
152  vsa->vdps_hash, (void*)vdp->tuple, (void*)vdp);
153  prt_assert(entry != NULL, "icl_hash_insert failed");
154 
155  // Insert in the thread's VDPs list.
156  int thread_rank = core % vsa->num_threads;
157  icl_list_t *node = icl_list_append(vsa->thread[thread_rank]->vdps, vdp);
158  prt_assert(node != NULL, "icl_list_append failed");
159  vdp->thread = vsa->thread[thread_rank];
160 
161  // Merge intra-node channels.
162  prt_vsa_vdp_merge_channels(vsa, vdp);
163  // Track channel tags for inter-node communication.
164  prt_vsa_vdp_track_tags_local(vsa, vdp, core, node_rank);
165 }
166 
167 
169 {
170  int i;
171  // FOR each input channel.
172  for (i = 0; i < vdp->num_inputs; i++) {
173  prt_channel_t *channel = vdp->input[i];
174  if (channel != NULL) {
175  // Look for maximum channel size.
176  prt_proxy_max_packet_size(vsa->proxy, channel);
177  // Look up the source VDP.
178  prt_vdp_t *src_vdp = icl_hash_find(vsa->vdps_hash, (void*)channel->src_tuple);
179  // IF source VDP found.
180  if (src_vdp != NULL) {
181  // Check if the channel on the source VDP points to this VDP.
182  int *src_vdp_dst_tuple = src_vdp->output[channel->src_slot]->dst_tuple;
183  int retval = prt_tuple_equal(src_vdp_dst_tuple, vdp->tuple);
184  prt_assert(retval == 1, "VDP channel tuple mismatch");
185  // Swap this channel to the existing channel.
186  vdp->input[i] = src_vdp->output[channel->src_slot];
187  prt_channel_delete(channel);
188  vdp->input[i]->tag = -1;
189  }
190  }
191  }
192  // FOR each output channel.
193  for (i = 0; i < vdp->num_outputs; i++) {
194  prt_channel_t *channel = vdp->output[i];
195  if (channel != NULL) {
196  // Look for maximum channel size.
197  prt_proxy_max_packet_size(vsa->proxy, channel);
198  // Look up the destination VDP.
199  prt_vdp_t *dst_vdp = icl_hash_find(vsa->vdps_hash, (void*)channel->dst_tuple);
200  // IF destination VDP found.
201  if (dst_vdp != NULL) {
202  // Check if the channel on the destination VDP points to this VDP.
203  int *dst_vdp_src_tuple = dst_vdp->input[channel->dst_slot]->src_tuple;
204  int retval = prt_tuple_equal(dst_vdp_src_tuple, vdp->tuple);
205  prt_assert(retval == 1, "VDP channel tuple mismatch");
206  // Swap this channel for the existing channel.
207  vdp->output[i] = dst_vdp->input[channel->dst_slot];
208  prt_channel_delete(channel);
209  vdp->output[i]->tag = -1;
210  }
211  }
212  }
213 }
214 
216  prt_vsa_t *vsa, prt_vdp_t *vdp, int core, int node_rank)
217 {
218  int i;
219  // FOR each input channel.
220  for (i = 0; i < vdp->num_inputs; i++) {
221  prt_channel_t *channel = vdp->input[i];
222  if (channel != NULL) {
223  channel->dst_node = node_rank;
224  int src_core = vsa->vdp_to_core(
225  channel->src_tuple, vsa->global_store, vsa->num_cores);
226  int src_node = src_core / vsa->num_threads;
227  // IF another node is the source.
228  if (src_node != vsa->node_rank) {
229  // Create the list if empty.
230  if (vsa->channel_lists[src_node] == NULL)
231  vsa->channel_lists[src_node] = icl_list_new();
232  // Search the list for the channel.
233  icl_list_t *node = icl_list_search(
234  vsa->channel_lists[src_node], channel, prt_channel_compare);
235  // IF channel already on the list.
236  if (node != NULL)
237  // Assign the existing tag.
238  channel->tag = ((prt_channel_t*)(node->data))->tag;
239  // ELSE
240  else {
241  // Add the channel to the list.
242  icl_list_append(vsa->channel_lists[src_node], channel);
243  // Assign the next value and increment.
244  channel->tag = vsa->channel_tags[src_node];
245  vsa->channel_tags[src_node]++;
246  }
247  // Add the channel to the proxy's tag hash.
248  int *src_node_tag = prt_tuple_new2(src_node, channel->tag);
249  icl_entry_t *entry = icl_hash_insert(
250  vsa->proxy->tags_hash, (void*)src_node_tag, (void*)channel);
251  prt_assert(entry != NULL, "icl_hash_insert failed");
252  }
253  }
254  }
255  // FOR each output channel.
256  for (i = 0; i < vdp->num_outputs; i++) {
257  prt_channel_t *channel = vdp->output[i];
258  if (channel != NULL) {
259  int dst_core = vsa->vdp_to_core(
260  channel->dst_tuple, vsa->global_store, vsa->num_cores);
261  int dst_node = dst_core / vsa->num_threads;
262  channel->dst_node = dst_node;
263  // IF another node is the destination.
264  if (dst_node != vsa->node_rank) {
265  // Create the list if empty.
266  if (vsa->channel_lists[dst_node] == NULL)
268  // Search the list for the channel.
269  icl_list_t *node = icl_list_search(
270  vsa->channel_lists[dst_node], channel, prt_channel_compare);
271  // IF channel already on the list.
272  if (node != NULL)
273  // Assign the existing tag.
274  channel->tag = ((prt_channel_t*)(node->data))->tag;
275  // ELSE
276  else {
277  // Add the channel to the list.
278  icl_list_append(vsa->channel_lists[dst_node], channel);
279  // Assign the next value and increment.
280  channel->tag = vsa->channel_tags[dst_node];
281  vsa->channel_tags[dst_node]++;
282  }
283  // Add the channel to the proxy's tag hash.
284  int *dst_node_tag = prt_tuple_new2(dst_node, channel->tag);
285  icl_entry_t *entry = icl_hash_insert(
286  vsa->proxy->tags_hash, (void*)dst_node_tag, (void*)channel);
287  prt_assert(entry != NULL, "icl_hash_insert failed");
288  }
289  }
290  }
291 
292 
293 
294 }
295 
296 
297 
299 {
300  int i;
301  // FOR each input channel.
302  for (i = 0; i < vdp->num_inputs; i++) {
303  prt_channel_t *channel = vdp->input[i];
304  if (channel != NULL) {
305  int src_core = vsa->vdp_to_core(channel->src_tuple, vsa->global_store, vsa->num_cores);
306  int src_node = src_core / vsa->num_threads;
307  channel->dst_node = node_rank;
308  // IF this node is the source.
309  if (src_node == vsa->node_rank) {
310  // Create the list if empty.
311  if (vsa->channel_lists[node_rank] == NULL)
312  vsa->channel_lists[node_rank] = icl_list_new();
313  // Search the list for the channel.
314  icl_list_t *node = icl_list_search(
315  vsa->channel_lists[node_rank], channel, prt_channel_compare);
316  // IF channel already on the list.
317  if (node != NULL) {
318  // Free this channel.
319  prt_channel_delete(channel);
320  }
321  else {
322  // Add the channel to the list.
323  icl_list_append(vsa->channel_lists[node_rank], channel);
324  // Assign the next value and increment.
325  channel->tag = vsa->channel_tags[node_rank];
326  vsa->channel_tags[node_rank]++;
327  }
328  }
329  else
330  prt_channel_delete(channel);
331  }
332  }
333  // FOR each output channel.
334  for (i = 0; i < vdp->num_outputs; i++) {
335  prt_channel_t *channel = vdp->output[i];
336  if (channel != NULL) {
337  int dst_core = vsa->vdp_to_core(channel->dst_tuple, vsa->global_store, vsa->num_cores);
338  int dst_node = dst_core / vsa->num_threads;
339  channel->dst_node = dst_node;
340  // IF this node is the destination.
341  if (dst_node == vsa->node_rank) {
342  // Create the list if empty.
343  if (vsa->channel_lists[node_rank] == NULL)
344  vsa->channel_lists[node_rank] = icl_list_new();
345  // Search the list for the channel.
346  icl_list_t *node = icl_list_search(
347  vsa->channel_lists[node_rank], channel, prt_channel_compare);
348  // IF channel already on the list.
349  if (node != NULL) {
350  // Free this channel.
351  prt_channel_delete(channel);
352  }
353  else {
354  // Add the channel to the list.
355  icl_list_append(vsa->channel_lists[node_rank], channel);
356  // Assign the next value and increment.
357  channel->tag = vsa->channel_tags[node_rank];
358  vsa->channel_tags[node_rank]++;
359  }
360  }
361  else
362  prt_channel_delete(channel);
363  }
364  }
365 }
366 
368 
377 {
378  // Init tracing.
380 
381  int i;
382  // Launch threads.
383  for (i = 0; i < vsa->num_threads; i++) {
384  int status =
385  pthread_create(
386  &vsa->thread[i]->id, &vsa->thread_attr, prt_thread_run, vsa->thread[i]);
387  prt_assert(status == 0, "pthread_create failed");
388  }
389 
390  // Barrier for trace alignment.
391  svg_trace_start(0);
392  MPI_Barrier(MPI_COMM_WORLD);
394 
395  // Service the communication proxy.
396  prt_proxy_run(vsa->proxy);
397 
398  // Join threads.
399  for (i = 0; i < vsa->num_threads; i++) {
400  int status = pthread_join(vsa->thread[i]->id, NULL);
401  prt_assert(status == 0, "pthread_join failed");
402  }
403  // Finish tracing.
406 }
407 
409 
418 {
419  switch (param) {
420  case PRT_VDP_SCHEDULING:
421  switch (value) {
424  vsa->config->vdp_scheduling = value;
425  break;
426  default:
427  prt_error("invalid value");
428  break;
429  }
430  break;
431  case PRT_SVG_TRACING:
432  switch (value) {
433  case PRT_SVG_TRACING_ON:
434  case PRT_SVG_TRACING_OFF:
435  vsa->config->svg_tracing = value;
436  break;
437  default:
438  prt_error("invalid value");
439  break;
440  }
441  break;
442  default:
443  prt_error("invalid param");
444  break;
445  }
446 }
447 
449 
455 {
456  int rank;
457  for (rank = 0; rank < vsa->num_nodes; rank++)
458  {
459  if (rank == vsa->node_rank)
460  {
461  printf(" NODE:%3d\n", vsa->node_rank);
462  int thread_rank;
463  for (thread_rank = 0; thread_rank < vsa->num_threads; thread_rank++)
464  {
465  printf(" THREAD:%3d\n", thread_rank);
466  prt_thread_t *thread = vsa->thread[thread_rank];
467  icl_list_t *ptr;
468  for (ptr = icl_list_first(thread->vdps);
469  ptr != NULL;
470  ptr = icl_list_next(thread->vdps, ptr))
471  {
472  prt_vdp_t *vdp = (prt_vdp_t*)ptr->data;
473  printf(" VDP:"); prt_tuple_print(vdp->tuple); printf("\n");
474  int i;
475  for (i = 0; i < vdp->num_inputs; i++)
476  {
477  prt_channel_t *channel = vdp->input[i];
478  if (channel != NULL) {
479  printf(" input from VDP"); prt_tuple_print(channel->src_tuple);
480  if (channel->tag == -1)
481  printf(" slot%3d, channel tag: \n", channel->src_slot);
482  else
483  printf(" slot%3d, channel tag:%3d\n", channel->src_slot, channel->tag);
484  }
485  else {
486  printf(" input NULL\n");
487  }
488  }
489  for (i = 0; i < vdp->num_outputs; i++)
490  {
491  if (i == 0)
492  printf("\n");
493  prt_channel_t *channel = vdp->output[i];
494  if (channel != NULL) {
495  printf(" output to VDP"); prt_tuple_print(channel->dst_tuple);
496  if (channel->tag == -1)
497  printf(" slot%3d, channel tag: \n", channel->dst_slot);
498  else
499  printf(" slot%3d, channel tag:%3d\n", channel->dst_slot, channel->tag);
500  }
501  else {
502  printf(" output NULL\n");
503  }
504  }
505  }
506  }
507  }
508  MPI_Barrier(MPI_COMM_WORLD);
509  fflush(stdout);
510  sleep(1);
511  }
512 
513  for (rank = 0; rank < vsa->num_nodes; rank++)
514  {
515  if (rank == vsa->node_rank)
516  {
517  printf(" NODE:%3d\n", vsa->node_rank);
518  int tmpint;
519  icl_entry_t *tmpent;
520  int *pk;
521  prt_channel_t *pd;
522  icl_hash_foreach(vsa->proxy->tags_hash, tmpint, tmpent, pk, pd)
523  {
524  prt_channel_t *channel = pd;
525  printf(" %d %d: ", pk[0], pk[1]);
526  prt_tuple_print(channel->src_tuple);
527  printf(" -> ");
528  prt_tuple_print(channel->dst_tuple);
529  printf("\n");
530  }
531  }
532  MPI_Barrier(MPI_COMM_WORLD);
533  fflush(stdout);
534  sleep(1);
535  }
536 }
void prt_tuple_print(int *tuple)
tuple print
Definition: prt_tuple.c:172
icl_list_t * icl_list_search(icl_list_t *head, void *data, int(*compare)(void *, void *))
Finds a data item in the specified linked list.
Definition: icl_list.c:115
void prt_vsa_config_set(prt_vsa_t *vsa, prt_config_param_t param, prt_config_value_t value)
Set VSA configuration parameter.
Definition: prt_vsa.c:416
enum prt_config_param_e prt_config_param_t
PRT configuration parameters.
int icl_hash_destroy(icl_hash_t *ht, void(*free_key)(void *), void(*free_data)(void *))
Free hash table structures. Key and data are freed using functions.
Definition: icl_hash.c:279
icl_list_t * icl_list_new()
Create new linked list.
Definition: icl_list.c:23
struct prt_channel_s ** input
Definition: prt_vdp.h:42
#define icl_hash_foreach(ht, tmpint, tmpent, kp, dp)
Definition: icl_hash.h:44
void * data
Definition: icl_list.h:20
void prt_vsa_delete(prt_vsa_t *vsa)
VSA destructor.
Definition: prt_vsa.c:83
int icl_list_destroy(icl_list_t *head, void(*free_function)(void *))
Frees the resources associated with this linked list.
Definition: icl_list.c:144
void prt_vsa_dump(prt_vsa_t *vsa)
Dump the VSA structure.
Definition: prt_vsa.c:454
prt_vdp_map_func_t vdp_to_core
Definition: prt_vsa.h:53
void prt_vsa_vdp_merge_channels(prt_vsa_t *vsa, prt_vdp_t *vdp)
Definition: prt_vsa.c:168
struct prt_config_s * config
Definition: prt_vsa.h:55
struct prt_thread_s ** thread
Definition: prt_vsa.h:51
icl_list_t * icl_list_append(icl_list_t *head, void *data)
Insert a node at the end of this list.
Definition: icl_list.c:297
void prt_vsa_vdp_insert(prt_vsa_t *vsa, prt_vdp_t *vdp)
Inserts a new VDP into a VSA. Puts the VDP in the list of VDPs of the owner thread. Connects corresponding input and output channels of connected VDPs.
Definition: prt_vsa.c:127
void svg_trace_init(int num_cores)
Initialize tracing.
Definition: svg_trace.c:38
icl_entry_t * icl_hash_insert(icl_hash_t *ht, void *key, void *data)
Insert an item into the hash table.
Definition: icl_hash.c:134
void prt_vsa_vdp_track_tags_local(prt_vsa_t *vsa, prt_vdp_t *vdp, int core, int node_rank)
Definition: prt_vsa.c:215
void prt_proxy_delete(prt_proxy_t *proxy)
communication proxy destructor Checking if all the lists are empty at the time of destruction...
Definition: prt_proxy.c:66
struct prt_vsa_s * vsa
Definition: prt_thread.h:28
icl_list_t * icl_list_first(icl_list_t *head)
Get the first item in this linked list.
Definition: icl_list.c:192
#define prt_error(msg)
Definition: prt_assert.h:24
Virtual Systolic Array (VSA) VSA contains global informationa about the system, a local communication...
Definition: prt_vsa.h:45
int num_nodes
Definition: prt_vsa.h:47
unsigned int prt_tuple_hash(void *tuple)
tuple hash Required by the VSA&#39;s tuples hash table. Computes the lenght in characters and calls a str...
Definition: prt_tuple.c:188
void prt_vsa_vdp_insert_local(prt_vsa_t *vsa, prt_vdp_t *vdp, int core, int node_rank)
Definition: prt_vsa.c:147
int * dst_tuple
Definition: prt_channel.h:35
prt_proxy_t * prt_proxy_new(int num_threads)
communication proxy constructor
Definition: prt_proxy.c:21
int svg_tracing
Definition: prt_config.h:43
void * prt_thread_run(void *thrd)
thread&#39;s production cycle Cycle through VDPs. Fire the ones that are ready. Remove the ones which bur...
Definition: prt_thread.c:70
int num_cores
Definition: prt_vsa.h:49
void prt_config_delete(prt_config_t *config)
config object destructor
Definition: prt_config.c:39
void prt_proxy_max_packet_size(prt_proxy_t *proxy, prt_channel_t *channel)
Look for maximum channel/packet size.
Definition: prt_proxy.c:105
void prt_thread_delete(prt_thread_t *thread)
thread object destructor
Definition: prt_thread.c:48
void svg_trace_start(int thread_rank)
Start tracing an event.
Definition: svg_trace.c:50
int * src_tuple
Definition: prt_channel.h:33
#define prt_tuple_new2(a, b)
Definition: prt_tuple.h:35
void prt_channel_delete(prt_channel_t *channel)
channel destructor
Definition: prt_channel.c:63
icl_list_t * vdps
Definition: prt_thread.h:32
VDP&#39;s data channel Implements a data link between a pair of VDPs. Identifies the source and destinati...
Definition: prt_channel.h:29
void prt_vsa_vdp_track_tags_remote(prt_vsa_t *vsa, prt_vdp_t *vdp, int node_rank)
Definition: prt_vsa.c:298
pthread_attr_t thread_attr
Definition: prt_vsa.h:50
prt_thread_t * prt_thread_new(int rank, int core)
thread object constructor
Definition: prt_thread.c:22
void * global_store
Definition: prt_vsa.h:52
int prt_channel_compare(void *channel1, void *channel2)
Compare two channels. Channels are equal if they have the same source and destination tuples and slot...
Definition: prt_channel.c:171
int num_inputs
Definition: prt_vdp.h:41
struct prt_vsa_s * vsa
Definition: prt_proxy.h:40
int num_outputs
Definition: prt_vdp.h:43
int node_rank
Definition: prt_vsa.h:46
#define prt_assert(cond, msg)
Definition: prt_assert.h:30
Virtual Data Processor (VDP) Is uniquely identified by a tuple. Fires for a predefined number of cycl...
Definition: prt_vdp.h:37
void svg_trace_finish()
Finish tracing. Collect traces from all nodes. Write the combined trace to an SVG file...
Definition: svg_trace.c:78
int * channel_tags
Definition: prt_vsa.h:58
VSA&#39;s worker thread Owns a number of VDPs. Knows the communication proxy.
Definition: prt_thread.h:27
void * icl_hash_find(icl_hash_t *ht, void *key)
Search for an entry in a hash table.
Definition: icl_hash.c:108
icl_list_t ** channel_lists
Definition: prt_vsa.h:57
enum prt_config_value_e prt_config_value_t
values of PRT configuration parameters
void svg_trace_stop(int thread_rank, int color)
Stop tracing an event.
Definition: svg_trace.c:63
icl_hash_t * vdps_hash
Definition: prt_vsa.h:54
int prt_tuple_equal(void *tuple_a, void *tuple_b)
tuple equality check Check if tuples are identical in length and content.
Definition: prt_tuple.c:161
void prt_proxy_run(prt_proxy_t *proxy)
communication proxy production cycle Serves communication requests of local worker threads until shut...
Definition: prt_proxy.c:171
icl_hash_t * icl_hash_create(int nbuckets, unsigned int(*hash_function)(void *), int(*hash_key_compare)(void *, void *))
Create a new hash table.
Definition: icl_hash.c:70
#define PRT_VSA_MAX_VDPS_PER_NODE
maximum VDPs per node She size of the VSA&#39;s hash table of VDPs. Should be a prime number ...
Definition: prt_vsa.h:32
struct prt_thread_s * thread
Definition: prt_vdp.h:38
prt_config_t * prt_config_new()
config object constructor
Definition: prt_config.c:19
Definition: icl_hash.h:19
struct prt_proxy_s * proxy
Definition: prt_vsa.h:56
struct prt_channel_s ** output
Definition: prt_vdp.h:44
int * tuple
Definition: prt_vdp.h:39
void prt_vsa_run(prt_vsa_t *vsa)
VSA&#39;s production cycle Launches worker threads. Sends the master thread in the communication proxy pr...
Definition: prt_vsa.c:376
struct prt_vdp_s * vdp
Definition: prt_channel.h:30
pthread_t id
Definition: prt_thread.h:31
Virtual Systolic Array (VSA)
prt_vsa_t * prt_vsa_new(int num_threads, void *global_store, int(*vdp_to_core)(int *, void *, int))
VSA constructor.
Definition: prt_vsa.c:27
int num_threads
Definition: prt_vsa.h:48
icl_hash_t * tags_hash
Definition: prt_proxy.h:42
int vdp_scheduling
Definition: prt_config.h:42
icl_list_t * icl_list_next(icl_list_t *head, icl_list_t *pos)
Get the node following the specified node.
Definition: icl_list.c:225