Skip to content

fix charm4py formatting and add check #305

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 26 additions & 1 deletion .github/workflows/charm4py.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ jobs:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
pip install setuptools cython cffi greenlet numpy torch torchvision filelock matplotlib
pip install setuptools cython cffi greenlet numpy numba torch torchvision filelock matplotlib
if [ ${{ matrix.os }} == 'macos-13' ]; then
# pypi only distributes torch packages w/ numpy v1 for macos-x86_64
pip install 'numpy<2'
Expand All @@ -50,3 +50,28 @@ jobs:
# needed for param server
export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES
python auto_test.py

build:
name: Lint
runs-on: ubuntu-latest

permissions:
contents: read
packages: read
# To report GitHub Actions status checks
statuses: write

steps:
- name: Checkout code
uses: actions/checkout@v4
with:
# super-linter needs the full git history to get the
# list of files that changed across commits
fetch-depth: 0

- name: Super-linter
uses: super-linter/super-linter/[email protected] # x-release-please-version
env:
# To report GitHub Actions status checks
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
VALIDATE_PYTHON_BLACK: true
89 changes: 52 additions & 37 deletions auto_test.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import time
import subprocess
import sys

if sys.version_info[0] < 3:
print("auto_test requires Python 3")
exit(1)
Expand All @@ -10,21 +11,23 @@
import json


if len(sys.argv) == 2 and sys.argv[1] == '-version_check':
if len(sys.argv) == 2 and sys.argv[1] == "-version_check":
exit(sys.version_info[0])


def searchForPython(python_implementations):
py3_exec = None
py3_exec = shutil.which('python3')
py3_exec = shutil.which("python3")
if py3_exec is None:
exec_str = shutil.which('python')
exec_str = shutil.which("python")
if exec_str is not None:
version = subprocess.call([exec_str, 'auto_test.py', '-version_check'])
version = subprocess.call([exec_str, "auto_test.py", "-version_check"])
if version >= 3:
py3_exec = exec_str
if py3_exec is None:
print("WARNING: Python 3 executable not found for auto_test. If desired, set manually")
print(
"WARNING: Python 3 executable not found for auto_test. If desired, set manually"
)
else:
python_implementations.add((3, py3_exec))

Expand All @@ -33,76 +36,88 @@ def searchForPython(python_implementations):
TIMEOUT = 120 # timeout for each test (in seconds)
CHARM_QUIET_AFTER_NUM_TESTS = 5

commonArgs = ['++local']
default_num_processes = int(os.environ.get('CHARM4PY_TEST_NUM_PROCESSES', 4))
commonArgs = ["++local"]
default_num_processes = int(os.environ.get("CHARM4PY_TEST_NUM_PROCESSES", 4))

try:
import numba

numbaInstalled = True
except:
numbaInstalled = False

# search for python executables
python_implementations = set() # python implementations can also be added here manually
python_implementations = set() # python implementations can also be added here manually
searchForPython(python_implementations)

interfaces = ['cython']
interfaces = ["cython"]

with open('test_config.json', 'r') as infile:
with open("test_config.json", "r") as infile:
tests = json.load(infile)

num_tests = 0
durations = defaultdict(dict)
for test in tests:
if 'condition' in test:
if test['condition'] == 'numbaInstalled' and not numbaInstalled:
if "condition" in test:
if test["condition"] == "numbaInstalled" and not numbaInstalled:
continue
if test['condition'] == 'not numbaInstalled' and numbaInstalled:
if test["condition"] == "not numbaInstalled" and numbaInstalled:
continue
if 'timeout_override' in test:
TIMEOUT = test['timeout_override']
if "timeout_override" in test:
TIMEOUT = test["timeout_override"]
else:
TIMEOUT = 120
num_processes = max(test.get('force_min_processes', default_num_processes), default_num_processes)
num_processes = max(
test.get("force_min_processes", default_num_processes), default_num_processes
)
for interface in interfaces:
durations[interface][test['path']] = []
durations[interface][test["path"]] = []
for version, python in sorted(python_implementations):
if version < test.get('requires_py_version', -1):
if version < test.get("requires_py_version", -1):
continue
additionalArgs = []
if num_tests >= CHARM_QUIET_AFTER_NUM_TESTS and '++quiet' not in commonArgs:
additionalArgs.append('++quiet')
cmd = ['charmrun/charmrun']
if test.get('prefix'):
cmd += [test['prefix']]
if not test.get('interactive', False):
cmd += [python] + [test['path']]
if num_tests >= CHARM_QUIET_AFTER_NUM_TESTS and "++quiet" not in commonArgs:
additionalArgs.append("++quiet")
cmd = ["charmrun/charmrun"]
if test.get("prefix"):
cmd += [test["prefix"]]
if not test.get("interactive", False):
cmd += [python] + [test["path"]]
else:
cmd += [python] + ['-m', 'charm4py.interactive']
if 'args' in test:
cmd += test['args'].split(' ')
cmd += [python] + ["-m", "charm4py.interactive"]
if "args" in test:
cmd += test["args"].split(" ")
cmd += commonArgs
cmd += ['+p' + str(num_processes), '+libcharm_interface', interface]
cmd += ["+p" + str(num_processes), "+libcharm_interface", interface]
cmd += additionalArgs
print('Test command is ' + ' '.join(cmd))
print("Test command is " + " ".join(cmd))
startTime = time.time()
stdin = None
if test.get('interactive', False):
stdin = open(test['path'])
if test.get("interactive", False):
stdin = open(test["path"])
p = subprocess.Popen(cmd, stdin=stdin)
try:
rc = p.wait(TIMEOUT)
except subprocess.TimeoutExpired:
print("Timeout (" + str(TIMEOUT) + " secs) expired when running " + test['path'] + ", Killing process")
print(
"Timeout ("
+ str(TIMEOUT)
+ " secs) expired when running "
+ test["path"]
+ ", Killing process"
)
p.kill()
rc = -1
if rc != 0:
print("ERROR running test " + test['path'] + " with " + python)
print("ERROR running test " + test["path"] + " with " + python)
exit(1)
else:
elapsed = round(time.time() - startTime, 3)
durations[interface][test['path']].append(elapsed)
print("\n\n--------------------- TEST PASSED (in " + str(elapsed) + " secs) ---------------------\n\n")
durations[interface][test["path"]].append(elapsed)
print(
"\n\n--------------------- TEST PASSED (in "
+ str(elapsed)
+ " secs) ---------------------\n\n"
)
num_tests += 1


Expand Down
25 changes: 17 additions & 8 deletions charm4py/__init__.py
Original file line number Diff line number Diff line change
@@ -1,28 +1,35 @@
import sys

if sys.version_info < (3, 8, 0):
raise RuntimeError('Charm4py requires Python 3.8 or higher')
raise RuntimeError("Charm4py requires Python 3.8 or higher")
import atexit
import os

try:
import greenlet
except ImportError:
print('Charm4py requires the greenlet package. It can be installed via pip')
print("Charm4py requires the greenlet package. It can be installed via pip")
exit(-1)


charm4py_version = 'unknown'
charm4py_version = "unknown"
try:
from ._version import version as charm4py_version
except:
try:
import subprocess
charm4py_version = subprocess.check_output(['git', 'describe'],
cwd=os.path.dirname(__file__)).rstrip().decode()

charm4py_version = (
subprocess.check_output(["git", "describe"], cwd=os.path.dirname(__file__))
.rstrip()
.decode()
)
except:
pass

if os.environ.get('CHARM_NOLOAD', '0') == '0':
if os.environ.get("CHARM_NOLOAD", "0") == "0":
from .charm import register, charm, readonlies, Options

Reducer = charm.reducers
Future = charm.createFuture

Expand All @@ -34,7 +41,9 @@

def checkCharmStarted():
if not charm.started:
print('Program is exiting but charm was not started: charm.start() was not '
'called or error happened before start')
print(
"Program is exiting but charm was not started: charm.start() was not "
"called or error happened before start"
)

atexit.register(checkCharmStarted)
9 changes: 6 additions & 3 deletions charm4py/channel.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
class Channel(object):

def __new__(cls, chare, remote, local=None):
if not hasattr(chare, '__channels__'):
if not hasattr(chare, "__channels__"):
chare.__initchannelattrs__()
ch = chare.__findPendingChannel__(remote, False)
if ch is None:
Expand All @@ -16,7 +16,7 @@ def __new__(cls, chare, remote, local=None):
ch.setEstablished()
if local is None:
# if local is None, we assume local endpoint is the individual chare
if hasattr(chare, 'thisIndex'):
if hasattr(chare, "thisIndex"):
local = chare.thisProxy[chare.thisIndex]
else:
local = chare.thisProxy
Expand All @@ -26,6 +26,7 @@ def __new__(cls, chare, remote, local=None):

CHAN_BUF_SIZE = 40000


class _Channel(object):

def __init__(self, port, remote, locally_initiated):
Expand All @@ -36,7 +37,9 @@ def __init__(self, port, remote, locally_initiated):
self.recv_seqno = 0
self.data = {}
self.recv_fut = None # this future is used to block on self.recv()
self.wait_ready = None # this future is used to block on ready (by charm.iwait())
self.wait_ready = (
None # this future is used to block on ready (by charm.iwait())
)
self.established = False
self.established_fut = None
self.locally_initiated = locally_initiated
Expand Down
Loading