Skip to content
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

Parameter generation improvements #41

Draft
wants to merge 5 commits into
base: develop
Choose a base branch
from
Draft
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
9 changes: 4 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ This is a test and benchmark suite for MPI.

The intention is to not rely on an entire library, but only incremental steps.

Lemons are both tests that fail, MPI functions that don't do the correct thing and
bad performance implementations.
Lemons are both tests that fail, MPI functions that don't do the correct thing
and bad performance implementations.


# Usage
Expand All @@ -17,7 +17,8 @@ python -m lemonspotter [path_to_database]
```

# Requirements
To run Lemonspotter only python 3.8.0 is needed. To contribute to development, please install all packages listed in the `requirements.txt` file.
To run Lemonspotter only python 3.8.0 is needed. To contribute to development,
please install all packages listed in the `requirements.txt` file.

## Arguments

Expand All @@ -26,5 +27,3 @@ To run Lemonspotter only python 3.8.0 is needed. To contribute to development, p

#### Print Lemonspotter Version
```-v, --version```


9 changes: 9 additions & 0 deletions lemonspotter/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,15 @@ def set_logging_level(log_level: str):
logging.basicConfig(level=numeric_level)


def check_version() -> None:
"""
Check that current version of Python runtime is at least 3.8.
"""

if not (sys.version_info[0] >= 3 and sys.version_info[1] >= 8):
raise RuntimeError('Python 3.8 is required to run LemonSpotter.')


def main() -> None:
"""
This function is the workflow of LemonSpotter.
Expand Down
52 changes: 52 additions & 0 deletions lemonspotter/core/argument.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
"""
This module contains the class definition of an Argument.
"""

from typing import Sequence, Optional

from lemonspotter.core.variable import Variable


class Argument:
"""
This class represents parameters of Function objects translated from the specification.
"""

# TODO Arguments need to also support code fragements?
# some dependencies will require executing additional code.

def __init__(self,
variable: Variable,
dependencies: Optional[Sequence[Variable]] = None):
self._variable = variable
self._dependencies = dependencies

def __str__(self) -> str:
return self._variable.name

def __repr__(self) -> str:
return self._variable.name

@property
def variable(self) -> Variable:
"""
"""

return self._variable

@property
def has_dependencies(self) -> bool:
"""
"""

return self._dependencies is not None

@property
def dependencies(self) -> Sequence[Variable]:
"""
"""

if self._dependencies is None:
raise RuntimeError('No dependencies for this argument.')

return self._dependencies
94 changes: 78 additions & 16 deletions lemonspotter/core/function.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
This module defines the function class which respresents functions from the specification.
"""

from typing import Mapping, Any, AbstractSet, Sequence, Iterable
from functools import lru_cache
from typing import Mapping, Any, AbstractSet, Sequence, Iterable, Optional

from lemonspotter.core.database import Database
from lemonspotter.core.type import Type
from lemonspotter.core.parameter import Parameter
from lemonspotter.core.parameter import Direction


class Function:
Expand All @@ -22,6 +22,12 @@ def __init__(self, json: Mapping[str, Any]) -> None:
self._json: Mapping[str, Any] = json
self.properties: Mapping[str, Any] = {}

# cache
self._parameters: Optional[Sequence[Parameter]] = None
self._in_parameters: Optional[Sequence[Parameter]] = None
self._inout_parameters: Optional[Sequence[Parameter]] = None
self._out_parameters: Optional[Sequence[Parameter]] = None

def __repr__(self) -> str:
"""
Defines informal string behavior for function type
Expand All @@ -41,78 +47,134 @@ def name(self) -> str:
"""This property provides access to the Function name."""

if 'name' not in self._json:
raise Exception('Function name is not in JSON.')
raise RuntimeError('Function name is not in JSON.')

return self._json['name']

@property
def has_parameters(self) -> bool:
""""""

return self._json.get('parameters', False)
return 'parameters' in self._json

@property
def has_in_parameters(self) -> bool:
""""""

return len(self.in_parameters) > 0

@property
def has_inout_parameters(self) -> bool:
""""""

return len(self.inout_parameters) > 0

@property
def has_out_parameters(self) -> bool:
""""""

return len(self.out_parameters) > 0
carsonwoods marked this conversation as resolved.
Show resolved Hide resolved

@property # type: ignore
@lru_cache()
def parameters(self) -> Sequence[Parameter]:
"""This property provides access to the parameter list of this Function object."""

if 'parameters' not in self._json:
raise Exception('Parameters are not in JSON.')
raise RuntimeError('Parameters are not in JSON.')

if self._parameters is None:
self._parameters = tuple(Parameter(parameter)
for parameter in self._json['parameters'])

return self._parameters

@property
def in_parameters(self) -> Sequence[Parameter]:
"""
Find all parameters which are with IN parameters.
"""

if self._in_parameters is None:
self._in_parameters = tuple(parameter
for parameter in self.parameters
if parameter.direction is Direction.IN)

return self._in_parameters

@property
def inout_parameters(self) -> Sequence[Parameter]:
"""
Find all parameters which are with INOUT parameters.
"""

if self._inout_parameters is None:
self._inout_parameters = tuple(parameter
for parameter in self.parameters
if parameter.direction is Direction.INOUT)

return self._inout_parameters

@property
def out_parameters(self) -> Sequence[Parameter]:
"""
Find all parameters which are either OUT parameters.
"""

if self._out_parameters is None:
self._out_parameters = tuple(parameter
for parameter in self.parameters
if parameter.direction is Direction.OUT)

return tuple(Parameter(parameter) for parameter in self._json['parameters'])
return self._out_parameters

@property
def return_type(self) -> Type:
"""This property provides the Type object of the return of this Function."""

if 'return' not in self._json:
raise Exception('Return is not in JSON.')
raise RuntimeError('Return is not in JSON.')

return Database().get_type(self._json['return'])

@property # type: ignore
@lru_cache()
def needs_any(self) -> AbstractSet['Function']:
"""This property provides access to the any set of needed Function objects."""

if 'needs_any' not in self._json:
raise Exception('Needs any is not in JSON.')
raise RuntimeError('Needs any is not in JSON.')

subset = filter(lambda name: Database().has_function(name), self._json['needs_any'])

return set(Database().get_function(func_name) for func_name in subset)

@property # type: ignore
@lru_cache()
def needs_all(self) -> AbstractSet['Function']:
"""This property provides access to the all set of needed Function objects."""

if 'needs_all' not in self._json:
raise Exception('Needs all is not in JSON.')
raise RuntimeError('Needs all is not in JSON.')

subset = filter(lambda name: Database().has_function(name), self._json['needs_all'])

return set(Database().get_function(func_name) for func_name in subset)

@property # type: ignore
@lru_cache()
def leads_any(self) -> AbstractSet['Function']:
"""This property provides access to the any set of lead Function objects."""

if 'leads_any' not in self._json:
raise Exception('Leads any is not in JSON.')
raise RuntimeError('Leads any is not in JSON.')

subset = filter(lambda name: Database().has_function(name), self._json['leads_any'])

return set(Database().get_function(func_name) for func_name in subset)

@property # type: ignore
@lru_cache()
def leads_all(self) -> AbstractSet['Function']:
"""This property provides access to the all set of lead the Function objects."""

if 'leads_all' not in self._json:
raise Exception('Leads all is not in JSON.')
raise RuntimeError('Leads all is not in JSON.')

subset = filter(lambda name: Database().has_function(name), self._json['leads_all'])

Expand Down
9 changes: 6 additions & 3 deletions lemonspotter/core/parameter.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@


class Direction(Enum):
"""
"""

IN = 'in'
OUT = 'out'
INOUT = 'inout'
Expand All @@ -28,7 +31,7 @@ def name(self) -> str:
"""This property provides the name of the Parameter."""

if 'name' not in self._json:
raise Exception('Name is not in JSON.')
raise RuntimeError('Name is not in JSON.')

return self._json['name']

Expand All @@ -37,7 +40,7 @@ def type(self) -> Type:
"""This property provides the Type object of the abstract type of this Parameter."""

if 'abstract_type' not in self._json:
raise Exception('Abstract type is not in JSON.')
raise RuntimeError('Abstract type is not in JSON.')

return Database().get_type(self._json['abstract_type'])

Expand All @@ -46,7 +49,7 @@ def direction(self) -> Direction:
"""This property provides the direction of the Parameter."""

if 'direction' not in self._json:
raise Exception('Direction is not in JSON.')
raise RuntimeError('Direction is not in JSON.')

return Direction(self._json['direction'])

Expand Down
1 change: 1 addition & 0 deletions lemonspotter/core/partition.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ def symbol(cls, operand: 'Operand') -> str:
return symbols[operand]


# TODO should be multiple subclasses of Partition
class PartitionType(Enum):
NUMERIC = 'numeric'
LITERAL = 'literal'
Expand Down
Loading