proxy.c 19.4 KB
Newer Older
1
2
/*******************************************************************************
 * This file is part of SWIFT.
3
 * Copyright (c) 2013 Pedro Gonnet (pedro.gonnet@durham.ac.uk)
4
 *
5
6
7
8
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published
 * by the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
9
 *
10
11
12
13
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
14
 *
15
16
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
 *
18
19
20
21
22
23
24
25
26
 ******************************************************************************/

/* Config parameters. */
#include "../config.h"

/* Some standard headers. */
#include <float.h>
#include <limits.h>
#include <sched.h>
27
28
29
30
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
31
32
33

/* MPI headers. */
#ifdef WITH_MPI
34
#include <mpi.h>
35
36
#endif

37
/* This object's header. */
38
#include "proxy.h"
39
40

/* Local headers. */
41
42
#include "error.h"

43
44
45
46
47
extern int count_in_hydro;
extern int count_out_hydro;
extern int count_in_grav;
extern int count_out_grav;

48
49
50
/**
 * @brief Exchange cells with a remote node.
 *
51
 * @param p The #proxy.
52
 */
53
void proxy_cells_exch1(struct proxy *p) {
54
55
56

#ifdef WITH_MPI

57
58
  /* Get the number of pcells we will need to send. */
  p->size_pcells_out = 0;
59
  for (int k = 0; k < p->nr_cells_out; k++)
60
61
62
63
64
65
66
67
68
69
70
71
    p->size_pcells_out += p->cells_out[k]->pcell_size;

  /* Send the number of pcells. */
  if (MPI_Isend(&p->size_pcells_out, 1, MPI_INT, p->nodeID,
                p->mynodeID * proxy_tag_shift + proxy_tag_count, MPI_COMM_WORLD,
                &p->req_cells_count_out) != MPI_SUCCESS)
    error("Failed to isend nr of pcells.");
  // message( "isent pcell count (%i) from node %i to node %i." ,
  // p->size_pcells_out , p->mynodeID , p->nodeID ); fflush(stdout);

  /* Allocate and fill the pcell buffer. */
  if (p->pcells_out != NULL) free(p->pcells_out);
72
73
  if (posix_memalign((void **)&p->pcells_out, SWIFT_STRUCT_ALIGNMENT,
                     sizeof(struct pcell) * p->size_pcells_out) != 0)
74
    error("Failed to allocate pcell_out buffer.");
75
  for (int ind = 0, k = 0; k < p->nr_cells_out; k++) {
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
    memcpy(&p->pcells_out[ind], p->cells_out[k]->pcell,
           sizeof(struct pcell) * p->cells_out[k]->pcell_size);
    ind += p->cells_out[k]->pcell_size;
  }

  /* Send the pcell buffer. */
  if (MPI_Isend(p->pcells_out, sizeof(struct pcell) * p->size_pcells_out,
                MPI_BYTE, p->nodeID,
                p->mynodeID * proxy_tag_shift + proxy_tag_cells, MPI_COMM_WORLD,
                &p->req_cells_out) != MPI_SUCCESS)
    error("Failed to pcell_out buffer.");
  // message( "isent pcells (%i) from node %i to node %i." , p->size_pcells_out
  // , p->mynodeID , p->nodeID ); fflush(stdout);

  /* Receive the number of pcells. */
  if (MPI_Irecv(&p->size_pcells_in, 1, MPI_INT, p->nodeID,
                p->nodeID * proxy_tag_shift + proxy_tag_count, MPI_COMM_WORLD,
                &p->req_cells_count_in) != MPI_SUCCESS)
    error("Failed to irecv nr of pcells.");
// message( "irecv pcells count on node %i from node %i." , p->mynodeID ,
// p->nodeID ); fflush(stdout);

98
#else
99
  error("SWIFT was not compiled with MPI support.");
100
#endif
101
}
102

103
void proxy_cells_exch2(struct proxy *p) {
104
105
106

#ifdef WITH_MPI

107
108
  /* Re-allocate the pcell_in buffer. */
  if (p->pcells_in != NULL) free(p->pcells_in);
109
  if (posix_memalign((void **)&p->pcells_in, SWIFT_STRUCT_ALIGNMENT,
110
                     sizeof(struct pcell) * p->size_pcells_in) != 0)
111
112
113
114
115
116
117
118
119
120
    error("Failed to allocate pcell_in buffer.");

  /* Receive the particle buffers. */
  if (MPI_Irecv(p->pcells_in, sizeof(struct pcell) * p->size_pcells_in,
                MPI_BYTE, p->nodeID,
                p->nodeID * proxy_tag_shift + proxy_tag_cells, MPI_COMM_WORLD,
                &p->req_cells_in) != MPI_SUCCESS)
    error("Failed to irecv part data.");
// message( "irecv pcells (%i) on node %i from node %i." , p->size_pcells_in ,
// p->mynodeID , p->nodeID ); fflush(stdout);
121
122

#else
123
  error("SWIFT was not compiled with MPI support.");
124
#endif
125
}
126
127
128
129
130
131

/**
 * @brief Add a cell to the given proxy's input list.
 *
 * @param p The #proxy.
 * @param c The #cell.
132
 * @param type Why is this cell in the proxy (hdro, gravity, ...) ?
133
 */
134
135
136
void proxy_addcell_in(struct proxy *p, struct cell *c, int type) {

  if (type == proxy_cell_type_none) error("Invalid type for proxy");
137
138

  /* Check if the cell is already registered with the proxy. */
139
  for (int k = 0; k < p->nr_cells_in; k++)
140
141
142
143
144
145
    if (p->cells_in[k] == c) {

      /* Update the type */
      p->cells_in_type[k] = type;
      return;
    }
146
147
148

  /* Do we need to grow the number of in cells? */
  if (p->nr_cells_in == p->size_cells_in) {
149

150
    p->size_cells_in *= proxy_buffgrow;
151
152
153

    struct cell **temp_cell;
    if ((temp_cell = malloc(sizeof(struct cell *) * p->size_cells_in)) == NULL)
154
      error("Failed to allocate incoming cell list.");
155
    memcpy(temp_cell, p->cells_in, sizeof(struct cell *) * p->nr_cells_in);
156
    free(p->cells_in);
157
158
    p->cells_in = temp_cell;

159
160
    int *temp_type;
    if ((temp_type = malloc(sizeof(int) * p->size_cells_in)) == NULL)
161
      error("Failed to allocate incoming cell type list.");
162
    memcpy(temp_type, p->cells_in_type, sizeof(int) * p->nr_cells_in);
163
164
    free(p->cells_in_type);
    p->cells_in_type = temp_type;
165
166
167
168
  }

  /* Add the cell. */
  p->cells_in[p->nr_cells_in] = c;
169
  p->cells_in_type[p->nr_cells_in] = type;
170
171
  p->nr_cells_in += 1;
}
172
173
174
175
176
177

/**
 * @brief Add a cell to the given proxy's output list.
 *
 * @param p The #proxy.
 * @param c The #cell.
178
 * @param type Why is this cell in the proxy (hdro, gravity, ...) ?
179
 */
180
181
182
void proxy_addcell_out(struct proxy *p, struct cell *c, int type) {

  if (type == proxy_cell_type_none) error("Invalid type for proxy");
183
184

  /* Check if the cell is already registered with the proxy. */
185
  for (int k = 0; k < p->nr_cells_out; k++)
186
187
188
189
190
191
    if (p->cells_out[k] == c) {

      /* Update the type */
      p->cells_out_type[k] |= type;
      return;
    }
192
193
194
195

  /* Do we need to grow the number of out cells? */
  if (p->nr_cells_out == p->size_cells_out) {
    p->size_cells_out *= proxy_buffgrow;
196
197
198

    struct cell **temp_cell;
    if ((temp_cell = malloc(sizeof(struct cell *) * p->size_cells_out)) == NULL)
199
      error("Failed to allocate outgoing cell list.");
200
    memcpy(temp_cell, p->cells_out, sizeof(struct cell *) * p->nr_cells_out);
201
    free(p->cells_out);
202
203
    p->cells_out = temp_cell;

204
205
    int *temp_type;
    if ((temp_type = malloc(sizeof(int) * p->size_cells_out)) == NULL)
206
      error("Failed to allocate outgoing cell type list.");
207
    memcpy(temp_type, p->cells_out_type, sizeof(int) * p->nr_cells_out);
208
209
    free(p->cells_out_type);
    p->cells_out_type = temp_type;
210
211
212
213
  }

  /* Add the cell. */
  p->cells_out[p->nr_cells_out] = c;
214
  p->cells_out_type[p->nr_cells_out] = type;
215
216
  p->nr_cells_out += 1;
}
217
218
219
220

/**
 * @brief Exchange particles with a remote node.
 *
221
 * @param p The #proxy.
222
 */
223
void proxy_parts_exch1(struct proxy *p) {
224
225
226

#ifdef WITH_MPI

227
  /* Send the number of particles. */
228
229
  p->buff_out[0] = p->nr_parts_out;
  p->buff_out[1] = p->nr_gparts_out;
230
231
  p->buff_out[2] = p->nr_sparts_out;
  if (MPI_Isend(p->buff_out, 3, MPI_INT, p->nodeID,
232
233
234
                p->mynodeID * proxy_tag_shift + proxy_tag_count, MPI_COMM_WORLD,
                &p->req_parts_count_out) != MPI_SUCCESS)
    error("Failed to isend nr of parts.");
235
236
  /* message( "isent particle counts [%i, %i] from node %i to node %i." ,
  p->buff_out[0], p->buff_out[1], p->mynodeID , p->nodeID ); fflush(stdout); */
237
238
239

  /* Send the particle buffers. */
  if (p->nr_parts_out > 0) {
240
241
    if (MPI_Isend(p->parts_out, p->nr_parts_out, part_mpi_type, p->nodeID,
                  p->mynodeID * proxy_tag_shift + proxy_tag_parts,
242
                  MPI_COMM_WORLD, &p->req_parts_out) != MPI_SUCCESS ||
243
        MPI_Isend(p->xparts_out, p->nr_parts_out, xpart_mpi_type, p->nodeID,
244
                  p->mynodeID * proxy_tag_shift + proxy_tag_xparts,
245
                  MPI_COMM_WORLD, &p->req_xparts_out) != MPI_SUCCESS)
246
247
248
      error("Failed to isend part data.");
    // message( "isent particle data (%i) to node %i." , p->nr_parts_out ,
    // p->nodeID ); fflush(stdout);
249
    /*for (int k = 0; k < p->nr_parts_out; k++)
250
251
      message("sending particle %lli, x=[%.3e %.3e %.3e], h=%.3e, to node %i.",
              p->parts_out[k].id, p->parts_out[k].x[0], p->parts_out[k].x[1],
252
              p->parts_out[k].x[2], p->parts_out[k].h, p->nodeID);*/
253
  }
254
  if (p->nr_gparts_out > 0) {
255
    if (MPI_Isend(p->gparts_out, p->nr_gparts_out, gpart_mpi_type, p->nodeID,
256
257
                  p->mynodeID * proxy_tag_shift + proxy_tag_gparts,
                  MPI_COMM_WORLD, &p->req_gparts_out) != MPI_SUCCESS)
258
259
260
261
262
263
264
265
266
267
      error("Failed to isend gpart data.");
    // message( "isent gpart data (%i) to node %i." , p->nr_parts_out ,
    // p->nodeID ); fflush(stdout);
  }

  if (p->nr_sparts_out > 0) {
    if (MPI_Isend(p->sparts_out, p->nr_sparts_out, spart_mpi_type, p->nodeID,
                  p->mynodeID * proxy_tag_shift + proxy_tag_sparts,
                  MPI_COMM_WORLD, &p->req_sparts_out) != MPI_SUCCESS)
      error("Failed to isend spart data.");
268
269
270
    // message( "isent gpart data (%i) to node %i." , p->nr_parts_out ,
    // p->nodeID ); fflush(stdout);
  }
271
272

  /* Receive the number of particles. */
273
  if (MPI_Irecv(p->buff_in, 3, MPI_INT, p->nodeID,
274
275
276
277
                p->nodeID * proxy_tag_shift + proxy_tag_count, MPI_COMM_WORLD,
                &p->req_parts_count_in) != MPI_SUCCESS)
    error("Failed to irecv nr of parts.");

278
#else
279
  error("SWIFT was not compiled with MPI support.");
280
#endif
281
}
282

283
void proxy_parts_exch2(struct proxy *p) {
284
285
286

#ifdef WITH_MPI

287
288
289
  /* Unpack the incomming parts counts. */
  p->nr_parts_in = p->buff_in[0];
  p->nr_gparts_in = p->buff_in[1];
290
  p->nr_sparts_in = p->buff_in[2];
Pedro Gonnet's avatar
Pedro Gonnet committed
291

292
  /* Is there enough space in the buffers? */
293
294
295
296
297
298
  if (p->nr_parts_in > p->size_parts_in) {
    do {
      p->size_parts_in *= proxy_buffgrow;
    } while (p->nr_parts_in > p->size_parts_in);
    free(p->parts_in);
    free(p->xparts_in);
299
300
    if ((p->parts_in = (struct part *)malloc(sizeof(struct part) *
                                             p->size_parts_in)) == NULL ||
301
302
303
304
        (p->xparts_in = (struct xpart *)malloc(sizeof(struct xpart) *
                                               p->size_parts_in)) == NULL)
      error("Failed to re-allocate parts_in buffers.");
  }
305
306
307
308
309
  if (p->nr_gparts_in > p->size_gparts_in) {
    do {
      p->size_gparts_in *= proxy_buffgrow;
    } while (p->nr_gparts_in > p->size_gparts_in);
    free(p->gparts_in);
Pedro Gonnet's avatar
Pedro Gonnet committed
310
311
    if ((p->gparts_in = (struct gpart *)malloc(sizeof(struct gpart) *
                                               p->size_gparts_in)) == NULL)
312
313
      error("Failed to re-allocate gparts_in buffers.");
  }
314
315
316
317
318
319
320
321
322
  if (p->nr_sparts_in > p->size_sparts_in) {
    do {
      p->size_sparts_in *= proxy_buffgrow;
    } while (p->nr_sparts_in > p->size_sparts_in);
    free(p->sparts_in);
    if ((p->sparts_in = (struct spart *)malloc(sizeof(struct spart) *
                                               p->size_sparts_in)) == NULL)
      error("Failed to re-allocate sparts_in buffers.");
  }
323
324
325

  /* Receive the particle buffers. */
  if (p->nr_parts_in > 0) {
326
327
328
329
330
    if (MPI_Irecv(p->parts_in, p->nr_parts_in, part_mpi_type, p->nodeID,
                  p->nodeID * proxy_tag_shift + proxy_tag_parts, MPI_COMM_WORLD,
                  &p->req_parts_in) != MPI_SUCCESS ||
        MPI_Irecv(p->xparts_in, p->nr_parts_in, xpart_mpi_type, p->nodeID,
                  p->nodeID * proxy_tag_shift + proxy_tag_xparts,
331
                  MPI_COMM_WORLD, &p->req_xparts_in) != MPI_SUCCESS)
332
333
334
335
      error("Failed to irecv part data.");
    // message( "irecv particle data (%i) from node %i." , p->nr_parts_in ,
    // p->nodeID ); fflush(stdout);
  }
336
  if (p->nr_gparts_in > 0) {
337
    if (MPI_Irecv(p->gparts_in, p->nr_gparts_in, gpart_mpi_type, p->nodeID,
Pedro Gonnet's avatar
Pedro Gonnet committed
338
                  p->nodeID * proxy_tag_shift + proxy_tag_gparts,
339
340
341
342
343
                  MPI_COMM_WORLD, &p->req_gparts_in) != MPI_SUCCESS)
      error("Failed to irecv gpart data.");
    // message( "irecv gpart data (%i) from node %i." , p->nr_gparts_in ,
    // p->nodeID ); fflush(stdout);
  }
344
345
346
347
348
349
350
351
  if (p->nr_sparts_in > 0) {
    if (MPI_Irecv(p->sparts_in, p->nr_sparts_in, spart_mpi_type, p->nodeID,
                  p->nodeID * proxy_tag_shift + proxy_tag_sparts,
                  MPI_COMM_WORLD, &p->req_sparts_in) != MPI_SUCCESS)
      error("Failed to irecv spart data.");
    // message( "irecv gpart data (%i) from node %i." , p->nr_gparts_in ,
    // p->nodeID ); fflush(stdout);
  }
352
353

#else
354
  error("SWIFT was not compiled with MPI support.");
355
#endif
356
}
357
358
359
360
361
362
363
364
365

/**
 * @brief Load parts onto a proxy for exchange.
 *
 * @param p The #proxy.
 * @param parts Pointer to an array of #part to send.
 * @param xparts Pointer to an array of #xpart to send.
 * @param N The number of parts.
 */
Pedro Gonnet's avatar
const.    
Pedro Gonnet committed
366
367
void proxy_parts_load(struct proxy *p, const struct part *parts,
                      const struct xpart *xparts, int N) {
368
369
370
371
372
373

  /* Is there enough space in the buffer? */
  if (p->nr_parts_out + N > p->size_parts_out) {
    do {
      p->size_parts_out *= proxy_buffgrow;
    } while (p->nr_parts_out + N > p->size_parts_out);
Matthieu Schaller's avatar
Matthieu Schaller committed
374
375
    struct part *tp = NULL;
    struct xpart *txp = NULL;
376
    if ((tp = (struct part *)malloc(sizeof(struct part) * p->size_parts_out)) ==
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
            NULL ||
        (txp = (struct xpart *)malloc(sizeof(struct xpart) *
                                      p->size_parts_out)) == NULL)
      error("Failed to re-allocate parts_out buffers.");
    memcpy(tp, p->parts_out, sizeof(struct part) * p->nr_parts_out);
    memcpy(txp, p->xparts_out, sizeof(struct xpart) * p->nr_parts_out);
    free(p->parts_out);
    free(p->xparts_out);
    p->parts_out = tp;
    p->xparts_out = txp;
  }

  /* Copy the parts and xparts data to the buffer. */
  memcpy(&p->parts_out[p->nr_parts_out], parts, sizeof(struct part) * N);
  memcpy(&p->xparts_out[p->nr_parts_out], xparts, sizeof(struct xpart) * N);

  /* Increase the counters. */
  p->nr_parts_out += N;
}
396

397
/**
398
 * @brief Load gparts onto a proxy for exchange.
399
400
401
 *
 * @param p The #proxy.
 * @param gparts Pointer to an array of #gpart to send.
402
 * @param N The number of gparts.
403
 */
Pedro Gonnet's avatar
const.    
Pedro Gonnet committed
404
void proxy_gparts_load(struct proxy *p, const struct gpart *gparts, int N) {
405
406
407
408
409
410
411

  /* Is there enough space in the buffer? */
  if (p->nr_gparts_out + N > p->size_gparts_out) {
    do {
      p->size_gparts_out *= proxy_buffgrow;
    } while (p->nr_gparts_out + N > p->size_gparts_out);
    struct gpart *tp;
Pedro Gonnet's avatar
Pedro Gonnet committed
412
413
    if ((tp = (struct gpart *)malloc(sizeof(struct gpart) *
                                     p->size_gparts_out)) == NULL)
414
415
416
417
418
419
420
      error("Failed to re-allocate gparts_out buffers.");
    memcpy(tp, p->gparts_out, sizeof(struct gpart) * p->nr_gparts_out);
    free(p->gparts_out);
    p->gparts_out = tp;
  }

  /* Copy the parts and xparts data to the buffer. */
Pedro Gonnet's avatar
Pedro Gonnet committed
421
  memcpy(&p->gparts_out[p->nr_gparts_out], gparts, sizeof(struct gpart) * N);
422
423
424
425
426

  /* Increase the counters. */
  p->nr_gparts_out += N;
}

427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
/**
 * @brief Load sparts onto a proxy for exchange.
 *
 * @param p The #proxy.
 * @param sparts Pointer to an array of #spart to send.
 * @param N The number of sparts.
 */
void proxy_sparts_load(struct proxy *p, const struct spart *sparts, int N) {

  /* Is there enough space in the buffer? */
  if (p->nr_sparts_out + N > p->size_sparts_out) {
    do {
      p->size_sparts_out *= proxy_buffgrow;
    } while (p->nr_sparts_out + N > p->size_sparts_out);
    struct spart *tp;
    if ((tp = (struct spart *)malloc(sizeof(struct spart) *
                                     p->size_sparts_out)) == NULL)
      error("Failed to re-allocate sparts_out buffers.");
    memcpy(tp, p->sparts_out, sizeof(struct spart) * p->nr_sparts_out);
    free(p->sparts_out);
    p->sparts_out = tp;
  }

  /* Copy the parts and xparts data to the buffer. */
  memcpy(&p->sparts_out[p->nr_sparts_out], sparts, sizeof(struct spart) * N);

  /* Increase the counters. */
  p->nr_sparts_out += N;
}

457
458
459
460
/**
 * @brief Initialize the given proxy.
 *
 * @param p The #proxy.
461
 * @param mynodeID The node this proxy is running on.
462
463
 * @param nodeID The node with which this proxy will communicate.
 */
464
465
466
467
468
469
470
471
472
473
474
475
void proxy_init(struct proxy *p, int mynodeID, int nodeID) {

  /* Set the nodeID. */
  p->mynodeID = mynodeID;
  p->nodeID = nodeID;

  /* Allocate the cell send and receive buffers, if needed. */
  if (p->cells_in == NULL) {
    p->size_cells_in = proxy_buffinit;
    if ((p->cells_in =
             (struct cell **)malloc(sizeof(void *) * p->size_cells_in)) == NULL)
      error("Failed to allocate cells_in buffer.");
476
    if ((p->cells_in_type = (int *)malloc(sizeof(int) * p->size_cells_in)) ==
Matthieu Schaller's avatar
Matthieu Schaller committed
477
        NULL)
478
      error("Failed to allocate cells_in_type buffer.");
479
480
481
482
483
484
485
  }
  p->nr_cells_in = 0;
  if (p->cells_out == NULL) {
    p->size_cells_out = proxy_buffinit;
    if ((p->cells_out = (struct cell **)malloc(sizeof(void *) *
                                               p->size_cells_out)) == NULL)
      error("Failed to allocate cells_out buffer.");
486
487
    if ((p->cells_out_type = (int *)malloc(sizeof(int) * p->size_cells_out)) ==
        NULL)
488
      error("Failed to allocate cells_out_type buffer.");
489
490
491
492
493
494
  }
  p->nr_cells_out = 0;

  /* Allocate the part send and receive buffers, if needed. */
  if (p->parts_in == NULL) {
    p->size_parts_in = proxy_buffinit;
495
496
    if ((p->parts_in = (struct part *)malloc(sizeof(struct part) *
                                             p->size_parts_in)) == NULL ||
497
498
499
500
501
502
503
        (p->xparts_in = (struct xpart *)malloc(sizeof(struct xpart) *
                                               p->size_parts_in)) == NULL)
      error("Failed to allocate parts_in buffers.");
  }
  p->nr_parts_in = 0;
  if (p->parts_out == NULL) {
    p->size_parts_out = proxy_buffinit;
504
505
    if ((p->parts_out = (struct part *)malloc(sizeof(struct part) *
                                              p->size_parts_out)) == NULL ||
506
507
508
509
510
        (p->xparts_out = (struct xpart *)malloc(sizeof(struct xpart) *
                                                p->size_parts_out)) == NULL)
      error("Failed to allocate parts_out buffers.");
  }
  p->nr_parts_out = 0;
511
512
513
514

  /* Allocate the gpart send and receive buffers, if needed. */
  if (p->gparts_in == NULL) {
    p->size_gparts_in = proxy_buffinit;
Pedro Gonnet's avatar
Pedro Gonnet committed
515
516
    if ((p->gparts_in = (struct gpart *)malloc(sizeof(struct gpart) *
                                               p->size_gparts_in)) == NULL)
517
518
519
520
521
      error("Failed to allocate gparts_in buffers.");
  }
  p->nr_gparts_in = 0;
  if (p->gparts_out == NULL) {
    p->size_gparts_out = proxy_buffinit;
Pedro Gonnet's avatar
Pedro Gonnet committed
522
523
    if ((p->gparts_out = (struct gpart *)malloc(sizeof(struct gpart) *
                                                p->size_gparts_out)) == NULL)
524
525
526
      error("Failed to allocate gparts_out buffers.");
  }
  p->nr_gparts_out = 0;
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542

  /* Allocate the spart send and receive buffers, if needed. */
  if (p->sparts_in == NULL) {
    p->size_sparts_in = proxy_buffinit;
    if ((p->sparts_in = (struct spart *)malloc(sizeof(struct spart) *
                                               p->size_sparts_in)) == NULL)
      error("Failed to allocate sparts_in buffers.");
  }
  p->nr_sparts_in = 0;
  if (p->sparts_out == NULL) {
    p->size_sparts_out = proxy_buffinit;
    if ((p->sparts_out = (struct spart *)malloc(sizeof(struct spart) *
                                                p->size_sparts_out)) == NULL)
      error("Failed to allocate sparts_out buffers.");
  }
  p->nr_sparts_out = 0;
543
}