phillipstanleymarbell / Noisy-lang-compiler

Noisy language compiler
MIT License
17 stars 1 forks source link

Add dimensionality check through a Newton runtime #590

Open blackgeorge-boom opened 2 years ago

blackgeorge-boom commented 2 years ago

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).

blackgeorge-boom commented 2 years ago

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 commented 2 years ago

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 commented 2 years ago

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.

blackgeorge-boom commented 2 years ago

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 commented 2 years ago

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

KomaGR commented 1 year ago

@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)?