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

Add dimensionality check through a Newton runtime #590

Open
wants to merge 23 commits into
base: issue-644
Choose a base branch
from

Conversation

blackgeorge-boom
Copy link
Collaborator

This is a draft PR aiming to show a simple dimensionality check at runtime.

Closes #586.

Aims to handle the problem of how to check the dimensionality of array positions, where the index of the array is a variable (whose value is unknown at compile time).

This can be useful for the runtime dimensionality check,
where we will need to allocate memory at runtime from the examined program,
in order to keep the Newton type information in the heap.

Addresses #586.
@blackgeorge-boom
Copy link
Collaborator Author

Currently, I'm stuck at the following. We need a way to keep at runtime the physics types of the intermediate results as they're calculated on the fly. For example:

	distance	x = 5;		/* meters  */
	speed		v = 1;		/* m/s     */

	state[0] = x;
	state[1] = v;

	for (int i = 0; i < 2; i++)
	{
		state[0] = state[i] + v*dt;
	}

For i = 0 this is valid, but for i = 1 it is not.

Currently, it should be straightforward, during compilation, to serialize the physics information into a JSON file:

{
  "state" : ["distance", "speed"],
  "dt" : "time",
  "x" : "distance",
  "v": "speed",
  "v*dt" : ?
}

The last element is intentionally left empty.

And let's assume in runtime we can deserialize this information, by inserting calls to the compiled binary that will be using the runtime utilities for the deserialization (this is not trivial though).

My question is: how to keep the physics type of the intermediate result v * dt?

At compile time, everything is a virtual register, so this problem is easy, regardless of whether a live value will end up in a register or in memory.

@KomaGR If I understood correctly, you had mentioned an idea of mapping memory addresses to physics, however, what if the result lies in a register and not in memory?

@KomaGR
Copy link
Collaborator

KomaGR commented Jun 6, 2022

I am a bit hesitant with the JSON format for this problem specifically. Parsing JSON is not trivial and could considerably increase the binary size of the runtime. If it's easy to integrate, it would be OK to rely on JSON format as a starting point and converge to something specific for our needs later.

@KomaGR If I understood correctly, you had mentioned an idea of mapping memory addresses to physics, however, what if the result lies in a register and not in memory?

I have to admit that I am not familiar with the different scenarios we could end up with when using various levels of optimization flags (e.g., O2/O3). We're talking about is a dynamic type system runtime for type-checking, which as a concept is not new and I believe we may find material on how to do such checks (if we decide that they are in scope for the project).

E.g., Python uses this kind of typing (although with a huge amount of overhead):

>>> a = 1
>>> b = "42"
>>> type(a)
<class 'int'>
>>> type(b)
<class 'str'>
>>> a+b
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'str'
>>> if a == 1:
...     c = 2
... else:
...     c = "0"
... 
>>> a+c
3
>>> b+c
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can only concatenate str (not "int") to str

In our case what is I think new is that we're using dynamic typing for physical dimensions using an under-the-hood solution. I.e., without using a library (see Boost.Units).

@blackgeorge-boom
Copy link
Collaborator Author

I agree that we are trying to implement runtime support for dynamic typing for physics types.

In our case what is I think new is that we're using dynamic typing for physical dimensions using an under-the-hood solution. I.e., without using a library (see Boost.Units).

Yes. We should actually make sure that we have some novelty here, compared to Boost.

Addresses #586.
@blackgeorge-boom
Copy link
Collaborator Author

After discussing with @KomaGR, I will try to do the following:

  1. When encountering the alloca in LLVM IR, generate a call to __newtonInsert.
  2. Take the return value of the runtime call and associate it with the alloca.
  3. Whenever loading from the alloca, associate the new value with the "id" value of the alloca.

@KomaGR
Copy link
Collaborator

KomaGR commented Jul 1, 2022

I will try to provide runtime support for handling the dimension propagation for multiplication and division operations.

blackgeorge-boom and others added 10 commits July 8, 2022 13:12
When encountering a variable definition, we insert a call to malloc
in order to allocate an array-state for the variable. Then, we add
a call to `newtonInsert` where we send the array as an argument for
the runtime to record and we get back a unique identifier. This will
be used as a future reference for our variable's dimension array.

Addresses #586.
Initially, it covers simple arithmetic operations between variables of
primitive types.

Addresses #586.
Currently, each array access generates a separate virtual register in
LLVM. Therefore, for every access we allocate a separate dimension
array and get a new identifier back from the runtime call. We need
to find a way to use the same identifier for the same array accesses.

Addresses #586.
@KomaGR KomaGR changed the base branch from master to issue-644 February 24, 2023 15:54
@KomaGR
Copy link
Collaborator

KomaGR commented Feb 24, 2023

@blackgeorge-boom What is the status regarding this pull request. I know we're probably not moving forward with the runtime proposal for now. Does this pull request implement the static compile-time dimensionality check (even if not capable of catching some dimensionality errors)?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Out of range error in LLVM getOperand()
2 participants