PULSAR  0.1
Parallel Unified Linear Algebra with Systolic Arrays
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros
prt_vsa.c File Reference

PULSAR Runtime (PRT) More...

#include "prt_vsa.h"
Include dependency graph for prt_vsa.c:

Go to the source code of this file.

Functions

int prt_tuple_equal (void *tuple_a, void *tuple_b)
 tuple equality check Check if tuples are identical in length and content. More...
 
unsigned int prt_tuple_hash (void *tuple)
 tuple hash Required by the VSA's tuples hash table. Computes the lenght in characters and calls a string hash function. More...
 
prt_vsa_tprt_vsa_new (int num_threads, void *global_store, int(*vdp_to_core)(int *, void *, int))
 VSA constructor. More...
 
void prt_vsa_delete (prt_vsa_t *vsa)
 VSA destructor. More...
 
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. More...
 
void prt_vsa_vdp_insert_local (prt_vsa_t *vsa, prt_vdp_t *vdp, int core, int node_rank)
 
void prt_vsa_vdp_merge_channels (prt_vsa_t *vsa, prt_vdp_t *vdp)
 
void prt_vsa_vdp_track_tags_local (prt_vsa_t *vsa, prt_vdp_t *vdp, int core, int node_rank)
 
void prt_vsa_vdp_track_tags_remote (prt_vsa_t *vsa, prt_vdp_t *vdp, int node_rank)
 
void prt_vsa_run (prt_vsa_t *vsa)
 VSA's production cycle Launches worker threads. Sends the master thread in the communication proxy production cycle. Joins the worker threads. More...
 
void prt_vsa_config_set (prt_vsa_t *vsa, prt_config_param_t param, prt_config_value_t value)
 Set VSA configuration parameter. More...
 
void prt_vsa_dump (prt_vsa_t *vsa)
 Dump the VSA structure. More...
 

Detailed Description

PULSAR Runtime (PRT)

Virtual Systolic Array (VSA) implementation.

Author
Jakub Kurzak

PULSAR Runtime /pulsar/ Copyright (C) 2012-2013 University of Tennessee.

Definition in file prt_vsa.c.

Function Documentation

int prt_tuple_equal ( void *  tuple_a,
void *  tuple_b 
)

tuple equality check Check if tuples are identical in length and content.

Parameters
tuple_a
tuple_b
Return values
0Tuples differ.
1Tuples are identical.

Definition at line 161 of file prt_tuple.c.

References prt_tuple_compare().

162 {
163  return (prt_tuple_compare(tuple_a, tuple_b) == 0);
164 }
int prt_tuple_compare(void *tuple_a, void *tuple_b)
tuple comparison
Definition: prt_tuple.c:135

Here is the call graph for this function:

Here is the caller graph for this function:

unsigned int prt_tuple_hash ( void *  tuple)

tuple hash Required by the VSA's tuples hash table. Computes the lenght in characters and calls a string hash function.

Parameters
tuple
Returns
hash

Definition at line 188 of file prt_tuple.c.

189 {
190  int len = 0;
191  int *tup = (int*)tuple;
192  while (tup[len] != INT_MAX)
193  len++;
194  return fnv_hash(tuple, len*sizeof(int));
195 }

Here is the caller graph for this function:

void prt_vsa_config_set ( prt_vsa_t vsa,
prt_config_param_t  param,
prt_config_value_t  value 
)

Set VSA configuration parameter.

Parameters
vsa
param
value

Definition at line 416 of file prt_vsa.c.

References prt_vsa_s::config, prt_error, PRT_SVG_TRACING, PRT_SVG_TRACING_OFF, PRT_SVG_TRACING_ON, PRT_VDP_SCHEDULING, PRT_VDP_SCHEDULING_AGGRESSIVE, PRT_VDP_SCHEDULING_LAZY, prt_config_s::svg_tracing, and prt_config_s::vdp_scheduling.

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 }
struct prt_config_s * config
Definition: prt_vsa.h:55
#define prt_error(msg)
Definition: prt_assert.h:24
int svg_tracing
Definition: prt_config.h:43
int vdp_scheduling
Definition: prt_config.h:42
void prt_vsa_delete ( prt_vsa_t vsa)

VSA destructor.

Parameters
VSA

Definition at line 83 of file prt_vsa.c.

References prt_vsa_s::channel_lists, prt_vsa_s::channel_tags, prt_vsa_s::config, icl_hash_destroy(), icl_list_destroy(), prt_vsa_s::num_nodes, prt_vsa_s::num_threads, prt_vsa_s::proxy, prt_assert, prt_channel_delete(), prt_config_delete(), prt_proxy_delete(), prt_thread_delete(), prt_vsa_s::thread, prt_vsa_s::thread_attr, and prt_vsa_s::vdps_hash.

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 }
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
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
struct prt_config_s * config
Definition: prt_vsa.h:55
struct prt_thread_s ** thread
Definition: prt_vsa.h:51
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
int num_nodes
Definition: prt_vsa.h:47
void prt_config_delete(prt_config_t *config)
config object destructor
Definition: prt_config.c:39
void prt_thread_delete(prt_thread_t *thread)
thread object destructor
Definition: prt_thread.c:48
void prt_channel_delete(prt_channel_t *channel)
channel destructor
Definition: prt_channel.c:63
pthread_attr_t thread_attr
Definition: prt_vsa.h:50
#define prt_assert(cond, msg)
Definition: prt_assert.h:30
int * channel_tags
Definition: prt_vsa.h:58
icl_list_t ** channel_lists
Definition: prt_vsa.h:57
icl_hash_t * vdps_hash
Definition: prt_vsa.h:54
struct prt_proxy_s * proxy
Definition: prt_vsa.h:56
int num_threads
Definition: prt_vsa.h:48

Here is the call graph for this function:

void prt_vsa_dump ( prt_vsa_t vsa)

Dump the VSA structure.

Parameters
vsa

Definition at line 454 of file prt_vsa.c.

References icl_list_s::data, prt_channel_s::dst_slot, prt_channel_s::dst_tuple, icl_hash_foreach, icl_list_first(), icl_list_next(), prt_vdp_s::input, prt_vsa_s::node_rank, prt_vdp_s::num_inputs, prt_vsa_s::num_nodes, prt_vdp_s::num_outputs, prt_vsa_s::num_threads, prt_vdp_s::output, prt_vsa_s::proxy, prt_tuple_print(), prt_channel_s::src_slot, prt_channel_s::src_tuple, prt_channel_s::tag, prt_proxy_s::tags_hash, prt_vsa_s::thread, prt_vdp_s::tuple, prt_channel_s::vdp, and prt_thread_s::vdps.

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
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
struct prt_thread_s ** thread
Definition: prt_vsa.h:51
icl_list_t * icl_list_first(icl_list_t *head)
Get the first item in this linked list.
Definition: icl_list.c:192
int num_nodes
Definition: prt_vsa.h:47
int * dst_tuple
Definition: prt_channel.h:35
int * src_tuple
Definition: prt_channel.h:33
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
int num_inputs
Definition: prt_vdp.h:41
int num_outputs
Definition: prt_vdp.h:43
int node_rank
Definition: prt_vsa.h:46
Virtual Data Processor (VDP) Is uniquely identified by a tuple. Fires for a predefined number of cycl...
Definition: prt_vdp.h:37
VSA&#39;s worker thread Owns a number of VDPs. Knows the communication proxy.
Definition: prt_thread.h:27
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
int num_threads
Definition: prt_vsa.h:48
icl_hash_t * tags_hash
Definition: prt_proxy.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

Here is the call graph for this function:

prt_vsa_t* prt_vsa_new ( int  num_threads,
void *  global_store,
int(*)(int *, void *, int)  vdp_to_core 
)

VSA constructor.

Parameters
num_threadsnumber of local worker threads
global_storeVSA's global store accessible to all VDPs
vdp_to_corefunction mapping VDP's tuple to a global core number
max_vdpsmaximum number of VDP's within a node
Returns
new VSA

Definition at line 27 of file prt_vsa.c.

References prt_vsa_s::channel_lists, prt_vsa_s::channel_tags, prt_vsa_s::config, prt_vsa_s::global_store, icl_hash_create(), prt_vsa_s::node_rank, prt_vsa_s::num_cores, prt_vsa_s::num_nodes, prt_vsa_s::num_threads, prt_vsa_s::proxy, prt_assert, prt_config_new(), prt_proxy_new(), prt_thread_new(), prt_tuple_equal(), prt_tuple_hash(), PRT_VSA_MAX_VDPS_PER_NODE, prt_vsa_s::thread, prt_vsa_s::thread_attr, prt_vsa_s::vdp_to_core, prt_vsa_s::vdps_hash, prt_thread_s::vsa, and prt_proxy_s::vsa.

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 }
prt_vdp_map_func_t vdp_to_core
Definition: prt_vsa.h:53
struct prt_config_s * config
Definition: prt_vsa.h:55
struct prt_thread_s ** thread
Definition: prt_vsa.h:51
struct prt_vsa_s * vsa
Definition: prt_thread.h:28
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
prt_proxy_t * prt_proxy_new(int num_threads)
communication proxy constructor
Definition: prt_proxy.c:21
int num_cores
Definition: prt_vsa.h:49
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
struct prt_vsa_s * vsa
Definition: prt_proxy.h:40
int node_rank
Definition: prt_vsa.h:46
#define prt_assert(cond, msg)
Definition: prt_assert.h:30
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
icl_list_t ** channel_lists
Definition: prt_vsa.h:57
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
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
prt_config_t * prt_config_new()
config object constructor
Definition: prt_config.c:19
struct prt_proxy_s * proxy
Definition: prt_vsa.h:56
int num_threads
Definition: prt_vsa.h:48

Here is the call graph for this function:

void prt_vsa_run ( prt_vsa_t vsa)

VSA's production cycle Launches worker threads. Sends the master thread in the communication proxy production cycle. Joins the worker threads.

Parameters
vsa

Definition at line 376 of file prt_vsa.c.

References prt_vsa_s::config, prt_thread_s::id, Indigo, prt_vsa_s::num_threads, prt_vsa_s::proxy, prt_assert, prt_proxy_run(), PRT_SVG_TRACING_ON, prt_thread_run(), svg_trace_finish(), svg_trace_init(), svg_trace_start(), svg_trace_stop(), prt_config_s::svg_tracing, prt_vsa_s::thread, and prt_vsa_s::thread_attr.

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 }
struct prt_config_s * config
Definition: prt_vsa.h:55
struct prt_thread_s ** thread
Definition: prt_vsa.h:51
void svg_trace_init(int num_cores)
Initialize tracing.
Definition: svg_trace.c:38
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
void svg_trace_start(int thread_rank)
Start tracing an event.
Definition: svg_trace.c:50
pthread_attr_t thread_attr
Definition: prt_vsa.h:50
#define prt_assert(cond, msg)
Definition: prt_assert.h:30
void svg_trace_finish()
Finish tracing. Collect traces from all nodes. Write the combined trace to an SVG file...
Definition: svg_trace.c:78
void svg_trace_stop(int thread_rank, int color)
Stop tracing an event.
Definition: svg_trace.c:63
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
struct prt_proxy_s * proxy
Definition: prt_vsa.h:56
pthread_t id
Definition: prt_thread.h:31
int num_threads
Definition: prt_vsa.h:48

Here is the call graph for this function:

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.

Parameters
vsa
vdp

Definition at line 127 of file prt_vsa.c.

References prt_vsa_s::global_store, prt_vsa_s::node_rank, prt_vsa_s::num_cores, prt_vsa_s::num_threads, prt_assert, prt_vsa_vdp_insert_local(), prt_vsa_vdp_track_tags_remote(), prt_vdp_s::tuple, and prt_vsa_s::vdp_to_core.

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 }
prt_vdp_map_func_t vdp_to_core
Definition: prt_vsa.h:53
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 num_cores
Definition: prt_vsa.h:49
void prt_vsa_vdp_track_tags_remote(prt_vsa_t *vsa, prt_vdp_t *vdp, int node_rank)
Definition: prt_vsa.c:298
void * global_store
Definition: prt_vsa.h:52
int node_rank
Definition: prt_vsa.h:46
#define prt_assert(cond, msg)
Definition: prt_assert.h:30
int * tuple
Definition: prt_vdp.h:39
int num_threads
Definition: prt_vsa.h:48

Here is the call graph for this function:

void prt_vsa_vdp_insert_local ( prt_vsa_t vsa,
prt_vdp_t vdp,
int  core,
int  node_rank 
)

Definition at line 147 of file prt_vsa.c.

References icl_hash_insert(), icl_list_append(), prt_vsa_s::num_threads, prt_assert, prt_vsa_vdp_merge_channels(), prt_vsa_vdp_track_tags_local(), prt_vdp_s::thread, prt_vsa_s::thread, prt_vdp_s::tuple, prt_thread_s::vdps, and prt_vsa_s::vdps_hash.

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 }
void prt_vsa_vdp_merge_channels(prt_vsa_t *vsa, prt_vdp_t *vdp)
Definition: prt_vsa.c:168
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
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
icl_list_t * vdps
Definition: prt_thread.h:32
#define prt_assert(cond, msg)
Definition: prt_assert.h:30
icl_hash_t * vdps_hash
Definition: prt_vsa.h:54
struct prt_thread_s * thread
Definition: prt_vdp.h:38
Definition: icl_hash.h:19
int * tuple
Definition: prt_vdp.h:39
int num_threads
Definition: prt_vsa.h:48

Here is the call graph for this function:

Here is the caller graph for this function:

void prt_vsa_vdp_merge_channels ( prt_vsa_t vsa,
prt_vdp_t vdp 
)

Definition at line 168 of file prt_vsa.c.

References prt_channel_s::dst_slot, prt_channel_s::dst_tuple, icl_hash_find(), prt_vdp_s::input, prt_vdp_s::num_inputs, prt_vdp_s::num_outputs, prt_vdp_s::output, prt_vsa_s::proxy, prt_assert, prt_channel_delete(), prt_proxy_max_packet_size(), prt_tuple_equal(), prt_channel_s::src_slot, prt_channel_s::src_tuple, prt_channel_s::tag, prt_vdp_s::tuple, and prt_vsa_s::vdps_hash.

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 }
struct prt_channel_s ** input
Definition: prt_vdp.h:42
int * dst_tuple
Definition: prt_channel.h:35
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
int * src_tuple
Definition: prt_channel.h:33
void prt_channel_delete(prt_channel_t *channel)
channel destructor
Definition: prt_channel.c:63
VDP&#39;s data channel Implements a data link between a pair of VDPs. Identifies the source and destinati...
Definition: prt_channel.h:29
int num_inputs
Definition: prt_vdp.h:41
int num_outputs
Definition: prt_vdp.h:43
#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 * icl_hash_find(icl_hash_t *ht, void *key)
Search for an entry in a hash table.
Definition: icl_hash.c:108
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
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

Here is the call graph for this function:

Here is the caller graph for this function:

void prt_vsa_vdp_track_tags_local ( prt_vsa_t vsa,
prt_vdp_t vdp,
int  core,
int  node_rank 
)

Definition at line 215 of file prt_vsa.c.

References prt_vsa_s::channel_lists, prt_vsa_s::channel_tags, icl_list_s::data, prt_channel_s::dst_node, prt_channel_s::dst_tuple, prt_vsa_s::global_store, icl_hash_insert(), icl_list_append(), icl_list_new(), icl_list_search(), prt_vdp_s::input, prt_vsa_s::node_rank, prt_vsa_s::num_cores, prt_vdp_s::num_inputs, prt_vdp_s::num_outputs, prt_vsa_s::num_threads, prt_vdp_s::output, prt_vsa_s::proxy, prt_assert, prt_channel_compare(), prt_tuple_new2, prt_channel_s::src_tuple, prt_channel_s::tag, prt_proxy_s::tags_hash, and prt_vsa_s::vdp_to_core.

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)
267  vsa->channel_lists[dst_node] = icl_list_new();
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 }
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
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
void * data
Definition: icl_list.h:20
prt_vdp_map_func_t vdp_to_core
Definition: prt_vsa.h:53
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
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
int * dst_tuple
Definition: prt_channel.h:35
int num_cores
Definition: prt_vsa.h:49
int * src_tuple
Definition: prt_channel.h:33
#define prt_tuple_new2(a, b)
Definition: prt_tuple.h:35
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 * 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
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
int * channel_tags
Definition: prt_vsa.h:58
icl_list_t ** channel_lists
Definition: prt_vsa.h:57
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 num_threads
Definition: prt_vsa.h:48
icl_hash_t * tags_hash
Definition: prt_proxy.h:42

Here is the call graph for this function:

Here is the caller graph for this function:

void prt_vsa_vdp_track_tags_remote ( prt_vsa_t vsa,
prt_vdp_t vdp,
int  node_rank 
)

Definition at line 298 of file prt_vsa.c.

References prt_vsa_s::channel_lists, prt_vsa_s::channel_tags, prt_channel_s::dst_node, prt_channel_s::dst_tuple, prt_vsa_s::global_store, icl_list_append(), icl_list_new(), icl_list_search(), prt_vdp_s::input, prt_vsa_s::node_rank, prt_vsa_s::num_cores, prt_vdp_s::num_inputs, prt_vdp_s::num_outputs, prt_vsa_s::num_threads, prt_vdp_s::output, prt_channel_compare(), prt_channel_delete(), prt_channel_s::src_tuple, prt_channel_s::tag, and prt_vsa_s::vdp_to_core.

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 }
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
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
prt_vdp_map_func_t vdp_to_core
Definition: prt_vsa.h:53
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
int * dst_tuple
Definition: prt_channel.h:35
int num_cores
Definition: prt_vsa.h:49
int * src_tuple
Definition: prt_channel.h:33
void prt_channel_delete(prt_channel_t *channel)
channel destructor
Definition: prt_channel.c:63
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 * 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
int num_outputs
Definition: prt_vdp.h:43
int node_rank
Definition: prt_vsa.h:46
int * channel_tags
Definition: prt_vsa.h:58
icl_list_t ** channel_lists
Definition: prt_vsa.h:57
struct prt_channel_s ** output
Definition: prt_vdp.h:44
int num_threads
Definition: prt_vsa.h:48

Here is the call graph for this function:

Here is the caller graph for this function: