Skip to content

Commit

Permalink
Merge branch 'internal-instantiator' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
LourensVeen committed Jan 6, 2025
2 parents 4fbf524 + 5b0ea5c commit 7d6d122
Show file tree
Hide file tree
Showing 63 changed files with 5,074 additions and 552 deletions.
7 changes: 7 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ endif
.PHONY: test
test: test_python test_scripts test_cpp test_fortran

.PHONY: test_all
test_all: test test_cluster

.PHONY: test_python_only
test_python_only:
MUSCLE_TEST_PYTHON_ONLY=1 tox
Expand All @@ -37,6 +40,10 @@ test_cpp: cpp
test_fortran: fortran_tests
cd libmuscle/fortran && $(MAKE) test

.PHONY: test_cluster
test_cluster:
tox -e cluster

.PHONY: test_scripts
test_scripts:
cd scripts && $(MAKE) test
Expand Down
12 changes: 12 additions & 0 deletions integration_test/cluster_test/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.PHONY: all
all: component_$(MPI_TYPE)


CXXFLAGS += $(shell pkg-config --cflags libmuscle_mpi ymmsl)
LDLIBS += $(shell pkg-config --libs libmuscle_mpi ymmsl)

CXXFLAGS += -g

component_$(MPI_TYPE): component.cpp
mpicxx -o $@ $(CXXFLAGS) $^ $(LDLIBS)

Empty file.
99 changes: 99 additions & 0 deletions integration_test/cluster_test/component.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
#include <cstdlib>
#include <fstream>
#include <string>

// This is a Linux-specific API, but this test always runs on Linux so that's okay.
#define _GNU_SOURCE
#include <sched.h>
#include <unistd.h>

#include "mpi.h"

#include "libmuscle/libmuscle.hpp"
#include "ymmsl/ymmsl.hpp"

using std::ofstream;
using std::to_string;

using libmuscle::Instance;
using libmuscle::Message;
using ymmsl::Operator;


/** Log where we are running so that the test can check for it. */
void log_location() {
int rank;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);

char nodeid[1024];
gethostname(nodeid, sizeof(nodeid));

cpu_set_t cpu_set;
CPU_ZERO(&cpu_set);
sched_getaffinity(0, sizeof(cpu_set_t), &cpu_set);

{
ofstream outfile("out_" + to_string(rank) + ".txt");
outfile << nodeid << std::endl;

bool first = true;
for (int i = 0; i < CPU_SETSIZE; ++i) {
if (CPU_ISSET(i, &cpu_set)) {
if (!first)
outfile << ",";
outfile << i;
first = false;
}
}
outfile << std::endl;
}
}


/** A simple dummy component. */
void component(int argc, char * argv[]) {
const int root_rank = 0;
int rank;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);

Instance instance(argc, argv, {
{Operator::F_INIT, {"init_in"}},
{Operator::O_I, {"inter_out"}},
{Operator::S, {"inter_in"}},
{Operator::O_F, {"final_out"}}},
MPI_COMM_WORLD, root_rank);

// outfile << "Starting reuse loop" << std::endl;
while (instance.reuse_instance()) {
// F_INIT

int64_t steps = instance.get_setting_as<int64_t>("steps");

instance.receive("init_in", Message(0.0));

for (int step = 0; step < steps; ++step) {
// O_I
if (rank == root_rank) {
instance.send("inter_out", Message(step));
}

// S
instance.receive("inter_in", Message(0.0));
}

// O_F
if (rank == root_rank) {
instance.send("final_out", Message(steps));
}
}
}


int main(int argc, char * argv[]) {
MPI_Init(&argc, &argv);
log_location();
component(argc, argv);
MPI_Finalize();
return EXIT_SUCCESS;
}

49 changes: 49 additions & 0 deletions integration_test/cluster_test/component.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import logging
import os
import socket

from libmuscle import Instance, Message
from ymmsl import Operator


def log_location() -> None:
"""Log where we are running so that the test can check for it."""
print(socket.gethostname())
print(','.join(map(str, sorted(os.sched_getaffinity(0)))))


def component() -> None:
"""A simple dummy component.
This sends and receives on all operators, allowing different coupling patterns
with a single program.
"""
instance = Instance({
Operator.F_INIT: ['init_in'],
Operator.O_I: ['inter_out'],
Operator.S: ['inter_in'],
Operator.O_F: ['final_out']})

while instance.reuse_instance():
# F_INIT
steps = instance.get_setting('steps', 'int')

instance.receive('init_in', default=Message(0.0))

for step in range(steps):
# O_I
instance.send('inter_out', Message(step))

# S
instance.receive('inter_in', default=Message(0.0))

# O_F
instance.send('final_out', Message(steps))


if __name__ == '__main__':
logging.basicConfig()
logging.getLogger().setLevel(logging.INFO)

log_location()
component()
Loading

0 comments on commit 7d6d122

Please sign in to comment.