1 #include "BSprivate.h"
2 
3 /*+ BSpack_n_send - Pack and Send messages for the coloring
4 
5 	Input Parameters:
6 .   n_msg_queue - the number of messages to send
7 .   msg_queue - the queue of messages
8 .   A - the sparse matrix
9 .   procinfo - the usual processor info
10 .   local_color - the local coloring
11 .   local_ptr - array of pointers indicating which neighbors in
12 .               each row are local neighbors (on this processor)
13 .   global_ptr - array of pointers indicating which neighbors in
14 .                each row are global neighbors (not on this processor)
15 .   msg_buffer - space in which to pack messages
16 .   msg_buffer_size - the size of the message buffer
17 .   type - the message type to use
18 
19 +*/
BSpack_n_send(BSmsg_list * msg_list,int n_msg_queue,int * msg_queue,BSspmat * A,BSprocinfo * procinfo,int * local_color,int * local_ptr,int * global_ptr,int * msg_buffer,int msg_buffer_size,int type)20 void BSpack_n_send(BSmsg_list *msg_list, int n_msg_queue, int *msg_queue,
21 	BSspmat *A, BSprocinfo *procinfo, int *local_color, int *local_ptr,
22 	int *global_ptr, int *msg_buffer, int msg_buffer_size, int type)
23 {
24 	BSsprow	**local_col_array;
25 	int i, l_vtx, p1;
26 	BSsprow	*t_node;
27 	int	*row_ptr;
28 	int	*msg_proc_num;
29 	int	*msg_queue_ptr;
30 	int	proc_num, next_proc_num, msg_buffer_ptr;
31 	int	owner;
32 
33 	local_col_array = A->rows;
34 	MY_MALLOC(msg_proc_num,(int *),sizeof(int)*n_msg_queue,1);
35 	MY_MALLOC(msg_queue_ptr,(int *),sizeof(int)*n_msg_queue,2);
36 
37 	proc_num = INT_MAX;
38 
39 	for (i=0; i<n_msg_queue; i++) {
40 		l_vtx = msg_queue[i];
41 		msg_queue_ptr[i] = global_ptr[l_vtx];
42 		t_node = local_col_array[l_vtx];
43 		row_ptr = t_node->col;
44 		(*A->map->fglobal2proc) (1,&(row_ptr[msg_queue_ptr[i]]),
45 			&(msg_proc_num[i]),procinfo,A->map); CHKERR(0);
46 		if (msg_proc_num[i] < proc_num)
47 			proc_num = msg_proc_num[i];
48 	}
49 
50 	while (proc_num < INT_MAX) {
51 
52 		next_proc_num = INT_MAX;
53 		msg_buffer[0] = 0;
54 		msg_buffer_ptr = 1;
55 		for (i=0; i<n_msg_queue; i++) {
56 			if(msg_proc_num[i] == proc_num) {
57 				if ((msg_buffer_ptr+4) > msg_buffer_size) {
58 					MY_SEND_SYNC(msg_list,type,&(msg_buffer[0]),msg_buffer_ptr,
59 						proc_num,MPI_INT,procinfo);
60 					msg_buffer[0] = 0;
61 					msg_buffer_ptr = 1;
62 				}
63 				l_vtx = msg_queue[i];
64 				t_node = local_col_array[l_vtx];
65 				row_ptr = t_node->col;
66 				msg_buffer[0]++;
67 				p1 = msg_buffer_ptr;
68 				(*A->map->flocal2global) (1,&l_vtx,&(msg_buffer[p1]),
69 					procinfo,A->map); CHKERR(0);
70 				msg_buffer[p1+1] = local_color[l_vtx];
71 				msg_buffer[p1+2] = 1;
72 				msg_buffer[p1+3] = row_ptr[msg_queue_ptr[i]];
73 				p1 = msg_buffer_ptr+2;
74 				msg_queue_ptr[i]++;
75 				msg_buffer_ptr += 4;
76 				(*A->map->fglobal2proc)(1,&(row_ptr[msg_queue_ptr[i]]),
77 					&owner,procinfo,A->map); CHKERR(0);
78 				while (owner == proc_num) {
79 					if (msg_buffer_ptr >= msg_buffer_size) {
80 						MY_SEND_SYNC(msg_list,type,&(msg_buffer[0]),
81 							msg_buffer_ptr,proc_num,MPI_INT,procinfo);
82 						msg_buffer[0] = 1;
83 						(*A->map->flocal2global) (1,&l_vtx,
84 							&(msg_buffer[1]),procinfo,A->map); CHKERR(0);
85 						msg_buffer[2] = local_color[l_vtx];
86 						msg_buffer[3] = 0;
87 						p1 = 3;
88 						msg_buffer_ptr = 4;
89 					}
90 					msg_buffer[p1]++;
91 					msg_buffer[msg_buffer_ptr]
92 						= row_ptr[msg_queue_ptr[i]];
93 					msg_queue_ptr[i]++;
94 					msg_buffer_ptr++;
95 					(*A->map->fglobal2proc)
96 						(1,&(row_ptr[msg_queue_ptr[i]]),
97 						&owner,procinfo,A->map); CHKERR(0);
98 				}
99 				if (msg_queue_ptr[i] >= local_ptr[l_vtx]) {
100 					msg_proc_num[i] = INT_MAX;
101 				}
102 				else {
103 					(*A->map->fglobal2proc)
104 						(1,&(row_ptr[msg_queue_ptr[i]]),
105 						&(msg_proc_num[i]),procinfo,A->map); CHKERR(0);
106 				}
107 			}
108 			if (msg_proc_num[i] < next_proc_num)
109 				next_proc_num = msg_proc_num[i];
110 		}
111 		MY_SEND_SYNC(msg_list,type,&(msg_buffer[0]),msg_buffer_ptr,proc_num,
112 			MPI_INT,procinfo);
113 		proc_num = next_proc_num;
114 	}
115 	MY_FREE(msg_proc_num);
116 	MY_FREE(msg_queue_ptr);
117 }
118 
119