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)