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

Kernels fails with contract violation (support scalar outputs) #83

Open
agent-lee opened this issue Feb 16, 2021 · 4 comments
Open

Kernels fails with contract violation (support scalar outputs) #83

agent-lee opened this issue Feb 16, 2021 · 4 comments

Comments

@agent-lee
Copy link
Collaborator

Minimal repro:

void foo(float x_in, float y_in[3], float z_out) {
  float acc = 0.0f;
  for (int a = 0; a < 3; a++) {
    acc = acc + x_in * y_in[a];
  }
  z_out = acc;
}

Error message:

[vtlee@vtlee-fedora-IT2277812 ifelse0]$ diospyros.py --manifest spec/diospyros.json 
Standard C compilation successful
Writing intermediate files to: compile-out
in-range: contract violation
  expected: real?
  given: #f
Error: Compilation aborted. cdios return error code 1.
@avanhatt avanhatt changed the title Kernels fails with contract violation Kernels fails with contract violation (support scalar outputs) Feb 16, 2021
@avanhatt
Copy link
Contributor

We currently fail on this kernel because the output is a scalar, so a workaround is to have the output be a 1-element array.

I can implement scalar outputs, but it doesn't seem particularly useful right now because we don't have any rewrite rules for horizontal vector operations (so the example kernels won't see any improvement). Is there a use case here where some more complicated, per-elements computations feed into a final horizontal accumulation?

@agent-lee
Copy link
Collaborator Author

The particular function I have is inlined so it's possible that it may get called inside a loop. Though in general I don't know if this is a valid assumption. Do the multiple function subroutines get inlined into the dataflow graph before the dios compiler gets to processing it? If so then maybe we're ok and I'll just wrap it with a loop.

@avanhatt
Copy link
Contributor

Diospyros essentially inlines everything into the outermost function of what is passed in. So yes, if the calling context is a loop here, it would be more useful to pass the surrounding loop context, something like:

#define SIZE 8
void foo(float x_in, float y_in[3], float z_out) {
  float acc = 0.0f;
  for (int a = 0; a < 3; a++) {
    acc = acc + x_in * y_in[a];
  }
  z_out = acc;
}

void loop(..., float all_outs[SIZE]) {
    for (int a = 0; a < SIZE; a++) {
        all_outs[a] = foo(...);
    }
}

In that case, the inner function foo should not need the input/output parameters to be tagged, as long as the outer (later) function does have the tags.

@avanhatt
Copy link
Contributor

Better error message for now in 0ac745b

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

No branches or pull requests

2 participants