NewMadeleine

Documentation

nm_mcast_basic.c
/*
* NewMadeleine
* Copyright (C) 2021-2022 (see AUTHORS file)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* 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.
*/
/* Basic example / test using mcast interface to do a broadcast, received by a
* regular recv. */
#include <stdlib.h>
#include <stdio.h>
#include "../common/nm_examples_helper.h"
#define NB_EXCHANGES 10
int main(int argc, char** argv)
{
const nm_tag_t tag = 0xbeef;
const char msg[] = "Hello, world!";
const nm_len_t msg_size = strlen(msg) + 1;
int worldsize;
nm_launcher_get_size(&worldsize);
if(worldsize == 1)
{
fprintf(stderr, "We need several nodes.\n");
return EXIT_FAILURE;
}
fprintf(stderr, "# With barrier, different tags...\n");
for (int k = 0; k < NB_EXCHANGES; k++)
{
if (is_server)
{
int* dests = malloc(sizeof(int) * (worldsize - 1));
int i;
for (i = 1; i < worldsize; i++)
{
dests[i-1] = i;
}
struct nm_data_s data;
nm_data_contiguous_build(&data, (char*) msg, msg_size);
nm_mcast_send(mcast_service, p_comm, dests, NULL, worldsize-1, tag+k, &data, 0, NM_COLL_TREE_DEFAULT);
free(dests);
}
else
{
char* buffer = malloc(msg_size);
nm_sr_recv(nm_comm_get_session(p_comm), 0, tag+k, buffer, msg_size);
if (strcmp(buffer, msg))
{
NM_FATAL("Received msg: '%s' (should be '%s')\n", buffer, msg);
}
free(buffer);
}
}
fprintf(stderr, "# With barrier, same tags...\n");
for (int k = 0; k < NB_EXCHANGES; k++)
{
if (is_server)
{
int* dests = malloc(sizeof(int) * (worldsize - 1));
int i;
for (i = 1; i < worldsize; i++)
{
dests[i-1] = i;
}
struct nm_data_s data;
nm_data_contiguous_build(&data, (char*) msg, msg_size);
nm_mcast_send(mcast_service, p_comm, dests, NULL, worldsize-1, tag, &data, 0, NM_COLL_TREE_DEFAULT);
free(dests);
}
else
{
char* buffer = malloc(msg_size);
nm_sr_recv(nm_comm_get_session(p_comm), 0, tag, buffer, msg_size);
if (strcmp(buffer, msg))
{
NM_FATAL("Received msg: '%s' (should be '%s')\n", buffer, msg);
}
free(buffer);
}
}
fprintf(stderr, "# Without barrier, different tags...\n");
for (int k = 0; k < NB_EXCHANGES; k++)
{
if (is_server)
{
int* dests = malloc(sizeof(int) * (worldsize - 1));
int i;
for (i = 1; i < worldsize; i++)
{
dests[i-1] = i;
}
struct nm_data_s data;
nm_data_contiguous_build(&data, (char*) msg, msg_size);
nm_mcast_send(mcast_service, p_comm, dests, NULL, worldsize-1, tag+k, &data, 0, NM_COLL_TREE_DEFAULT);
free(dests);
}
else
{
char* buffer = malloc(msg_size);
nm_sr_recv(nm_comm_get_session(p_comm), 0, tag+k, buffer, msg_size);
if (strcmp(buffer, msg))
{
NM_FATAL("Received msg: '%s' (should be '%s')\n", buffer, msg);
}
free(buffer);
}
}
fprintf(stderr, "# Without barrier, same tags...\n");
for (int k = 0; k < NB_EXCHANGES; k++)
{
if (is_server)
{
int* dests = malloc(sizeof(int) * (worldsize - 1));
int i;
for (i = 1; i < worldsize; i++)
{
dests[i-1] = i;
}
struct nm_data_s data;
nm_data_contiguous_build(&data, (char*) msg, msg_size);
nm_mcast_send(mcast_service, p_comm, dests, NULL, worldsize-1, tag, &data, 0, NM_COLL_TREE_DEFAULT);
free(dests);
}
else
{
char* buffer = malloc(msg_size);
nm_sr_recv(nm_comm_get_session(p_comm), 0, tag, buffer, msg_size);
if (strcmp(buffer, msg))
{
NM_FATAL("Received msg: '%s' (should be '%s')\n", buffer, msg);
}
free(buffer);
}
}
fprintf(stderr, "# Without barrier, same tags, binary tree...\n");
for (int k = 0; k < NB_EXCHANGES; k++)
{
if (is_server)
{
int* dests = malloc(sizeof(int) * (worldsize - 1));
int i;
for (i = 1; i < worldsize; i++)
{
dests[i-1] = i;
}
struct nm_data_s data;
nm_data_contiguous_build(&data, (char*) msg, msg_size);
nm_mcast_send(mcast_service, p_comm, dests, NULL, worldsize-1, tag, &data, 0, NM_COLL_TREE_BINARY);
free(dests);
}
else
{
char* buffer = malloc(msg_size);
nm_sr_recv(nm_comm_get_session(p_comm), 0, tag, buffer, msg_size);
if (strcmp(buffer, msg))
{
NM_FATAL("Received msg: '%s' (should be '%s')\n", buffer, msg);
}
free(buffer);
}
}
fprintf(stderr, "# Without barrier, same tags, chain tree...\n");
for (int k = 0; k < NB_EXCHANGES; k++)
{
if (is_server)
{
int* dests = malloc(sizeof(int) * (worldsize - 1));
int i;
for (i = 1; i < worldsize; i++)
{
dests[i-1] = i;
}
struct nm_data_s data;
nm_data_contiguous_build(&data, (char*) msg, msg_size);
nm_mcast_send(mcast_service, p_comm, dests, NULL, worldsize-1, tag, &data, 0, NM_COLL_TREE_CHAIN);
free(dests);
}
else
{
char* buffer = malloc(msg_size);
nm_sr_recv(nm_comm_get_session(p_comm), 0, tag, buffer, msg_size);
if (strcmp(buffer, msg))
{
NM_FATAL("Received msg: '%s' (should be '%s')\n", buffer, msg);
}
free(buffer);
}
}
printf("success\n");
nm_mcast_finalize(mcast_service);
return EXIT_SUCCESS;
}
void nm_coll_barrier(nm_comm_t comm, nm_tag_t tag)
@ NM_COLL_TREE_DEFAULT
for public interfaces, will fallback to one of the previous tree kinds
Definition: nm_coll_trees.h:51
@ NM_COLL_TREE_BINARY
Definition: nm_coll_trees.h:47
@ NM_COLL_TREE_CHAIN
Definition: nm_coll_trees.h:39
int nm_launcher_get_size(int *size)
Returns the number of nodes.
void nm_mcast_send(nm_mcast_service_t nm_mcast, nm_comm_t p_recv_comm, int *p_dests, int *p_prios, int n_dests, nm_tag_t tag, struct nm_data_s *p_data, nm_len_t hlen, nm_coll_tree_kind_t tree_kind)
Send data in a blocking mode.
void nm_mcast_finalize(nm_mcast_service_t nm_mcast)
Release the mcast interface.
nm_mcast_service_t nm_mcast_init(nm_comm_t p_comm)
Initializes the mcast interface.
struct nm_mcast_service_s * nm_mcast_service_t
Public abstraction for a mcast service.
static nm_session_t nm_comm_get_session(nm_comm_t p_comm)
nm_tag_t tag
the user-supplied tag
static void nm_data_contiguous_build(struct nm_data_s *p_data, void *ptr, nm_len_t len)
Definition: nm_data.h:315
static int is_server
@ NM_EXAMPLES_TOPO_STAR
static void nm_examples_exit(void)
static void nm_examples_init_topo(int *argc, char *argv[], enum nm_example_topo_e topo)
#define NM_FATAL(format,...)
Definition: nm_log.h:36
nm_mpi_communicator_t * p_comm
communicator used for communication
static int nm_sr_recv(nm_session_t p_session, nm_gate_t p_gate, nm_tag_t tag, void *data, nm_len_t len)
blocking recv
uint64_t nm_tag_t
user tags, 64 bits, contained in indirect hashtable
Definition: nm_types.h:58
uint64_t nm_len_t
data length used by nmad
Definition: nm_types.h:70
a data descriptor, used to pack/unpack data from app layout to/from contiguous buffers
Definition: nm_data.h:189