diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
new file mode 100644
index 0000000..bd4aa3e
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -0,0 +1,50 @@
+---
+name: Bug report
+about: Create a report to help us improve
+title: "[BUG] Add description"
+labels: bug
+assignees: ''
+
+---
+
+Before reporting a bug, please make sure you are using the latest version
+of all the lyncs packages. Use the following command to update them:
+
+```
+pip install [--user] --upgrade $(lyncs_packages)
+```
+
+If the library is failing due to linking problems or changes in the system,
+you can recompile all the source code in the following way:
+
+```
+pip install [--user] --force-reinstall --no-cache-dir $(lyncs_packages)
+```
+
+**Describe the bug**
+A clear and concise description of what the bug is.
+
+**To Reproduce**
+If applicable, list the steps to reproduce the behavior:
+
+**Error message / Output**
+If applicable, paste here the error messages / output you get.
+
+
+ Click to expand!
+
+ ```
+ # PASTE HERE
+ ```
+
+
+**Installed versions**
+Paste here the output of `lyncs_packages -v`.
+
+
+ Click to expand!
+
+ ```
+ # PASTE HERE
+ ```
+
diff --git a/.github/workflows/ci_cd_test.yml b/.github/workflows/ci_cd_test.yml
index 6dc58d3..c08f20f 100644
--- a/.github/workflows/ci_cd_test.yml
+++ b/.github/workflows/ci_cd_test.yml
@@ -111,3 +111,52 @@ jobs:
- name: Run tests
run: |
pytest -v --import-mode=importlib
+
+ lrz-benchmarks:
+ # needs: build-n-publish
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v2
+
+ - name: Install dependencies
+ run: |
+ sudo apt-get install python3-openstackclient python3-heatclient
+
+ - name: Start VM
+ id: start-vm
+ env:
+ LRZ_PROJECT_ID: ${{ secrets.lrz_project_id }}
+ LRZ_USERNAME: ${{ secrets.lrz_username }}
+ LRZ_PASSWORD: ${{ secrets.lrz_password }}
+ run: |
+ source .lrz_scripts/openrc.sh
+ openstack stack create -t .lrz_scripts/debian.yml github-stack --wait
+ openstack stack output show -f value github-stack public_ip
+ PUBLIC_IP=$(openstack stack output show -f value github-stack public_ip | tail -n 1)
+ echo "::set-output name=public-ip::${PUBLIC_IP}"
+ echo "Public IP is ${PUBLIC_IP}"
+
+ - name: Execute via ssh
+ uses: appleboy/ssh-action@master
+ with:
+ host: ${{ steps.start-vm.outputs.public-ip }}
+ username: debian
+ key: ${{ secrets.lrz_ssh_key }}
+ script_stop: true
+ timeout: 1m
+ debug: true
+ script: |
+ whoami
+ pwd
+ ls -al
+
+ - name: Stop VM
+ if: ${{ always() }}
+ env:
+ LRZ_PROJECT_ID: ${{ secrets.lrz_project_id }}
+ LRZ_USERNAME: ${{ secrets.lrz_username }}
+ LRZ_PASSWORD: ${{ secrets.lrz_password }}
+ run: |
+ source .lrz_scripts/openrc.sh
+ openstack stack delete github-stack --wait -y
diff --git a/.lrz_scripts/debian.yml b/.lrz_scripts/debian.yml
new file mode 100644
index 0000000..72fdced
--- /dev/null
+++ b/.lrz_scripts/debian.yml
@@ -0,0 +1,41 @@
+heat_template_version: queens
+description: Launch a server
+
+resources:
+ volume:
+ type: OS::Cinder::Volume
+ properties:
+ name: github_volume
+ image: Debian-10-buster
+ size: 20
+
+ server:
+ type: OS::Nova::Server
+ depends_on: volume
+ properties:
+ name: github_server
+ flavor: lrz.small
+ key_name: github
+ block_device_mapping_v2:
+ - volume_id: { get_resource: volume }
+ networks:
+ - network: internet
+
+ floating_ip:
+ type: OS::Neutron::FloatingIP
+ properties:
+ floating_network: { list_join: ['', [internet, '_pool']] }
+
+ floating_ip_association:
+ type: OS::Neutron::FloatingIPAssociation
+ depends_on:
+ - server
+ - floating_ip
+ properties:
+ floatingip_id: { get_resource: floating_ip }
+ port_id: { get_attr: [server, addresses, internet, 0, port] }
+
+outputs:
+ public_ip:
+ description: The public ip of the server
+ value: { get_attr: [floating_ip, floating_ip_address] }
diff --git a/.lrz_scripts/openrc.sh b/.lrz_scripts/openrc.sh
new file mode 100644
index 0000000..43bae56
--- /dev/null
+++ b/.lrz_scripts/openrc.sh
@@ -0,0 +1,36 @@
+#!/usr/bin/env bash
+# To use an OpenStack cloud you need to authenticate against the Identity
+# service named keystone, which returns a **Token** and **Service Catalog**.
+# The catalog contains the endpoints for all services the user/tenant has
+# access to - such as Compute, Image Service, Identity, Object Storage, Block
+# Storage, and Networking (code-named nova, glance, keystone, swift,
+# cinder, and neutron).
+#
+# *NOTE*: Using the 3 *Identity API* does not necessarily mean any other
+# OpenStack API is version 3. For example, your cloud provider may implement
+# Image API v1.1, Block Storage API v2, and Compute API v2.0. OS_AUTH_URL is
+# only for the Identity API served through keystone.
+export OS_AUTH_URL=https://cc.lrz.de:5000/v3
+# With the addition of Keystone we have standardized on the term **project**
+# as the entity that owns the resources.
+export OS_PROJECT_ID=$LRZ_PROJECT_ID
+export OS_PROJECT_NAME="$LRZ_USERNAME"
+export OS_USER_DOMAIN_NAME="ADS"
+if [ -z "$OS_USER_DOMAIN_NAME" ]; then unset OS_USER_DOMAIN_NAME; fi
+export OS_PROJECT_DOMAIN_ID="b6807b306c054287bec94113d22e9075"
+if [ -z "$OS_PROJECT_DOMAIN_ID" ]; then unset OS_PROJECT_DOMAIN_ID; fi
+# unset v2.0 items in case set
+unset OS_TENANT_ID
+unset OS_TENANT_NAME
+# In addition to the owning entity (tenant), OpenStack stores the entity
+# performing the action as the **user**.
+export OS_USERNAME="$LRZ_USERNAME"
+# With Keystone you pass the keystone password.
+export OS_PASSWORD="$LRZ_PASSWORD"
+# If your configuration has multiple regions, we set that information here.
+# OS_REGION_NAME is optional and only valid in certain environments.
+export OS_REGION_NAME="RegionOne"
+# Don't leave a blank variable, unset it if it was empty
+if [ -z "$OS_REGION_NAME" ]; then unset OS_REGION_NAME; fi
+export OS_INTERFACE=public
+export OS_IDENTITY_API_VERSION=3
diff --git a/lyncs_DDalphaAMG/solver.py b/lyncs_DDalphaAMG/solver.py
index ea28d0c..d4b5b36 100644
--- a/lyncs_DDalphaAMG/solver.py
+++ b/lyncs_DDalphaAMG/solver.py
@@ -5,6 +5,8 @@
https://github.com/sbacchio/DDalphaAMG/blob/master/src/DDalphaAMG.h
"""
+# pylint: disable=import-outside-toplevel
+
__all__ = [
"Solver",
]
@@ -14,7 +16,6 @@
from os.path import isfile, realpath, abspath
import numpy
from cppyy import nullptr
-from mpi4py import MPI
from lyncs_mpi import default_comm, CartesianClass
from lyncs_mpi.abc import Array, Global, Constant
from lyncs_cppyy.ll import cast, to_pointer, addressof
@@ -79,6 +80,8 @@ def __init__(
rnd_seeds: list(int)
An int per MPI process (list of length comm.size)
"""
+ from mpi4py import MPI
+
self._init_params = lib.DDalphaAMG_init()
self._run_params = lib.DDalphaAMG_parameters()
self._status = lib.DDalphaAMG_status()
@@ -251,6 +254,8 @@ def setup_status(self):
@property
def comm(self):
"Returns the MPI communicator used by the library."
+ from mpi4py import MPI
+
comm = MPI.Comm()
comm_ptr = to_pointer(MPI._addressof(comm), "MPI_Comm*")
lib.MPI_Comm_free(comm_ptr)
@@ -419,6 +424,8 @@ def get_lattice_partitioning(global_lattice, block_lattice=None, procs=None, com
raise ValueError("procs must be a list of length 4 (T, Z, Y, X)")
if comm is not None:
+ from mpi4py import MPI
+
if not isinstance(comm, MPI.Comm):
raise TypeError(f"Expected an MPI.Comm but got {type(comm)}")
diff --git a/setup.py b/setup.py
index 2480914..9a1136f 100644
--- a/setup.py
+++ b/setup.py
@@ -19,6 +19,7 @@
"lyncs-cppyy",
"lyncs-utils",
"lyncs-clime",
+ "lyncs-setuptools",
],
extras_require={
"test": ["pytest", "pytest-cov", "pytest-benchmark"],
diff --git a/test/test_solver.py b/test/test_solver.py
index 4c29c34..9c96889 100644
--- a/test/test_solver.py
+++ b/test/test_solver.py
@@ -161,3 +161,36 @@ def test_errors():
with raises(ValueError):
Solver(global_lattice=[4, 4, 4, 4], rnd_seeds=[1, 2])
+
+
+def test_data_movement():
+ client = Client(4)
+ procs = [2, 1, 1, 1]
+ comm1 = client.create_comm(2).create_cart(procs)
+ comm2 = client.create_comm(2, exclude=comm1.workers).create_cart(procs)
+
+ solver1 = Solver(
+ global_lattice=[4, 4, 4, 4],
+ block_lattice=[2, 2, 2, 2],
+ procs=procs,
+ kappa=0.1,
+ comm=comm1,
+ )
+ solver2 = Solver(
+ global_lattice=[4, 4, 4, 4],
+ block_lattice=[2, 2, 2, 2],
+ procs=procs,
+ kappa=0.1,
+ comm=comm2,
+ )
+
+ conf = solver1.read_configuration("test/conf.random")
+ plaq1 = solver1.set_configuration(conf)
+ assert np.isclose(plaq1, 0.13324460568521923)
+
+ plaq2 = solver2.set_configuration(conf)
+ assert np.isclose(plaq1, plaq2)
+
+ vec = solver1.random()
+ sol = solver1.solve(vec)
+ assert allclose(solver2.D(sol), vec)