-
Notifications
You must be signed in to change notification settings - Fork 4.4k
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
CPI Bidirectional Input / Output #19838
Comments
Can you elaborate on your #2 concern, what copy are you referring to, the calls to @seanyoung When do you expect to need the return data released? |
@jackcmay Well, 2 and 3 are a bit blended, that is true. Both come from the differences in ABI v1 and v2, and their inter-operation. ABI v1: ABI v2: Inter-operation between v1 and v2: |
I think I need more detail on the invocation stack frame, this is a memory range that caller/callee both have access to? |
As I understand it, @Lichtso design for return data in ABI v2 is that there is new return data memory range allocated for each stack frame. It is not clear to me why this cannot be shared, in a similar vein as ABI v1. |
I think you mean when should be freed/cleared. After each instruction it should be cleared. |
Well, in ABI v1 nothing was shared memory, everything was copied (twice) across each boundary. The idea is for ABI v2 to allow a program to see the entire invocation stack and modify its own frame and the one above it (of the program it calls). This way programs can write data into the programs they call as input and write out data into their caller as output. Also, they can read data from the programs they call as output and their own input data from their caller. No additional copies required. |
Except that return data can passed up the stack without copies, in ABI v1.
Why can't the return buffer not be shared between callee/caller? |
Yes, except for the implicit passing.
Because if it is not in shared memory, then it needs to be copied (twice). |
On second thought, I'm not sure about re-using the input section as output. Consider this function:
Now the Now with your proposed ABI v2, when we eth abi encode the return buffer, we are overwriting the input section, and by encoding the The vector to slice pass above could be modified to not do vector to slice conversion if a variable is used for return buffer abi encoding, but do we really want this? Equally -- when writing rust, someone make take a slice of the input and pass that slice into something which is serializing into the return buffer. Again this will produce garbage. |
@Lichtso Are you thinking the return region will be separate from the input region? For ABIv2 a Or are you thinking that the program's entrypoint actually returns an optional data buffer that the runtime/helpers write into the shared region? Also, not all programs will be using the return data and over-allocating space for it for each call might be wasteful. |
That is the reason I wanted to reuse the input data area (as in not separate).
The first option (entrypoint provides a slice reference to write to yourself) seems more performant as it requires no extra copy step inside the helper method and no syscall. ABIv2 could also use one global shared memory area instead of one per invocation stack frame. However, what I dislike about it is that it makes the input and output data passing artificially asymmetric. |
Let me summarize:
|
https://millcomputing.com/ is an (in my opinion elegant) counterexample. But I agree with your summary and that we should leave it as it is and just map it as transaction global shared memory in ABI v2. The only thing I am still pondering about if there is a way to make it configurable / transparent to the program how the interface works. |
@Lichtso what are you aiming for when you say "configurable/transparent"? |
We are still hard-coding lots of mechanisms and parameters. |
This issue has been automatically locked since there has not been any activity in past 7 days after it was closed. Please open a new issue for related bugs. |
So, @seanyoung and I discussed #19318 (comment) on a call and came to the conclusion that the input data slice and the returned data slice could be both one bidirectional channel.
Problem
The current implementation (#19548) uses two syscalls for returning data through a global area in the
InvokeContext
: One syscall in the callee to write it and one syscall in the caller to read it. It is completely independent of the input data at the moment.There are three problems with that:
InvokeContext
because it needs to be copied from and into the invocation stack frames.InvokeContext
).The first problem can be ignored as this feature will be "born old" and replaced by the implementation in ABI v2 soon. The second however is a lot more tricky because it requires inter-operation between both ABI versions and probably copies of this returned data in between them. And the third one is up to our choosing, how to model the cost function: Should implicit passing cost as well (because it would in the new ABI)?
Proposed Solution
In ABI v2 (#19191) this would be implemented by shared memory in each invocation stack frame (the same used for input data), which both caller and callee have access to.
Let the current implementation sit as is,
but don't activate the feature gate until we have decided how to address the second and third problem.
The text was updated successfully, but these errors were encountered: