Skip to content

Comments

Add internal slots to MLOperand and MLActivation#337

Closed
zolkis wants to merge 17 commits intowebmachinelearning:mainfrom
zolkis:operand-activation-improvements
Closed

Add internal slots to MLOperand and MLActivation#337
zolkis wants to merge 17 commits intowebmachinelearning:mainfrom
zolkis:operand-activation-improvements

Conversation

@zolkis
Copy link
Collaborator

@zolkis zolkis commented Feb 1, 2023

Fix #336
Discussion about content preferred there.
Discussion about spec/syntax preferred here.


Preview | Diff

@zolkis zolkis changed the title WiP: Add internal slots to MLOperand and MLActivation Add internal slots to MLOperand and MLActivation Feb 7, 2023
@zolkis
Copy link
Collaborator Author

zolkis commented Feb 8, 2023

@huningxin PTAL :)

Copy link
Contributor

@huningxin huningxin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @zolkis !

My two cents:

  1. Should this PR focus on the MLOperand as the first step?
  2. With MLOperand internal slots, MLGraphBuilder.input() and MLGraphBuilder.constant() algorithm steps could be crafted.

WDYT?

index.bs Outdated
: <dfn>\[[tensorData]]</dfn> of type {{ArrayBufferView}}
::
The {{MLOperand}}'s data buffer (only for constant operands)
: <dfn>\[[activation]]</dfn> of type {{MLActivation}}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MLOperand may not need to associate with an MLActivation. It may need a slot for the operator (e.g., platform object represents the node within the platform graph) that produces this MLOperand.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I agree this was meant as an internal slot for the operator. But currently MLOperator is MLActivation. I think we might need both. I expressed my doubts in #335

@zolkis
Copy link
Collaborator Author

zolkis commented Feb 22, 2023

Should this PR focus on the MLOperand as the first step?
With MLOperand internal slots, MLGraphBuilder.input() and MLGraphBuilder.constant() algorithm steps could be crafted.

I would need both to move on. MLOperand is connected with operations, which currently overlap with activations (see #335). We need to clarify these relationships before moving on to algorithms. I have several algorithms in the work that depend on this.
Making algorithms for only input() and constant() is not enough, as our goal is to have a PR for each missing algorithm in Q1.

@zolkis zolkis mentioned this pull request Feb 23, 2023
@zolkis
Copy link
Collaborator Author

zolkis commented Mar 2, 2023

Experimentally added constructors for MLOperand and MLActivation. These need not be explicit, could also be internal steps in the spec. However, for formalism it is good to explore the constructor way.

index.bs Outdated
1. Let |kind| be the second argument.
1. If |kind| is not an {{MLOperandKind}}, throw a "{{TypeError}}" {{DOMException}} and abort these steps.
1. Set [=this=]'s {{MLOperand/[[kind]]}} to |kind|.
1. Let |type| be the third argument.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should |type| be passed? Or just use {{MLOperandDescriptor/type}} instead?

index.bs Outdated
1. If |dimensions| is not an array of positive numbers, return `false`;
1. If |dimensions|.length is 0, return `false`.
1. If |dimensions|.length is too large to be supported by the implementation, return `false`.
1. If any element of |dimensions| is too large to be supported by the implementation, return `false`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the data type of element be validated, to be unsigned long? The value 0 (0 size dimension) should also be invalid.

Copy link
Collaborator Author

@zolkis zolkis Mar 16, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know, I guess all integer type values should be accepted (the first step checks that), the question is range.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The range should be [1, ULONG_MAX].

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that may be implementation dependent. What we can explicitly check is that it's a positive ulong, but the implementation may have other constraints that it should be able to tell the API user if the specified dimension is not supported for whatever reason.

index.bs Outdated
1. If |type| is not equal to |bufferView|'s [=element type=], throw a "{{DataError}}" {{DOMException}} and abort these steps.
1. If the [=byte length=] of |desc| is not supported by the implementation, throw a "{{DataError}}" {{DOMException}} and abort these steps.
1. If the [=byte length=] of |desc| is not equal with |bufferView|.\[[ByteLength]], throw a "{{DataError}}" {{DOMException}} and abort these steps.
1. Set [=this=]'s {{MLOperand/[[tensorData]]}} to |bufferView|.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should MLOperand have corresponding platform object? Should the kind, type, dimensions and values be used to create the platform object?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Made a phrasing for that, let's check.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because the next step is to register this to underlying platform, I am not sure whether MLOperand needs to keep a reference to |bufferView|. Any use cases?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The use case is for that step when registering to the underlying platform IIUC.

index.bs Outdated
1. Otherwise, of |kind| is `"output"`:
1. Let |dimensions| be the fourth argument.
1. If the [=check dimensions=] steps given |type| and |dimensions| return `false`, throw a "{{DataError}}" {{DOMException}} and abort these steps.
1. Let |activation| be the fifth argument.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think |activation| should be used here. |activation| is only used as activation function that may be fused into an operator. Instead, could the platform object representing an operator be used? The operator produces this MLOperand.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, but it would be nice to have a definition for an operator. An obscure internal object exposed in an internal slot doesn't sound like a clear definition. :)
I wonder if defining MLOperator and also keeping MLActivation would work better? since now we have only MLActivation defined in the spec but MLOperator is used in the implementation.

In that sense, MLOperator would be similarly empty object like MLGraph currently is. Of course Occam tells that if we can do without MLOperator in the spec, we should. But then we need a clear "private" definition of an operator object (for internal use).

index.bs Outdated
1. If |desc| is not an {{MLOperandDescriptor}}, throw a "{{TypeError}}" {{DOMException}} and abort these steps.
1. If |type| is not equal to |desc|'s {{MLOperandDescriptor/type}}, throw a "{{DataError}}" {{DOMException}} and abort these steps.
1. If the [=byte length=] of |desc| is not supported by the implementation, throw a "{{DataError}}" {{DOMException}} and abort these steps.
1. Set [=this=]'s {{MLOperand/[[dimensions]]}} to |desc|.{{MLOperandDescriptor/dimensions}}.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto, may need to create the platform object representing this "input" MLOperand.

… private, add operator internal slot, improve steps

Signed-off-by: Zoltan Kis <[email protected]>
@zolkis
Copy link
Collaborator Author

zolkis commented Mar 16, 2023

I addressed the comments the following way:

  • removed the constructors, instead now we have private steps for creating the objects (can be easily turned into constructors any time)
  • added a step for binding to a corresponding underlying platform object
  • fixed / updated many of the steps.

The goal of the PR is to establish a start, that can be used from other (future) algorithms. We can improve on these also in future PRs.

@zolkis
Copy link
Collaborator Author

zolkis commented Mar 18, 2023

Added clarification notes to MLOperand and MLActivation.
About the latter, the internal slots that are included now (incl. MLActivationOptions) are just a working assumption (for what I might need later). In a later PR we can sanitize what could we trim from there. For instance options is a candidate, but at the moment I do need them, e.g. in the steps of methods that create MLActivation objects, it is relevant to point out the options which those activations use. See the clamp algorithm.

zolkis pushed a commit to zolkis/webnn that referenced this pull request Mar 18, 2023
index.bs Outdated
1. If |type| is not equal to |bufferView|'s [=element type=], throw a "{{DataError}}" {{DOMException}} and abort these steps.
1. If the [=byte length=] of |desc| is not supported by the implementation, throw a "{{DataError}}" {{DOMException}} and abort these steps.
1. If the [=byte length=] of |desc| is not equal with |bufferView|.\[[ByteLength]], throw a "{{DataError}}" {{DOMException}} and abort these steps.
1. Set [=this=]'s {{MLOperand/[[tensorData]]}} to |bufferView|.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because the next step is to register this to underlying platform, I am not sure whether MLOperand needs to keep a reference to |bufferView|. Any use cases?

index.bs Outdated
1. Set [=this=]'s {{MLOperand/[[tensorData]]}} to |bufferView|.
1. Otherwise, of |kind| is `"input"`:
1. Let |name| be the fourth argument.
1. Make a request to the underlying platform to register [=this=] as a constant.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we make a request to "platform graph builder"? Should the "platform graph builder" be an internal slot of MLGraphBuilder |builder|?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For text "as a constant", should we map it to the common computational graph concept?

Let's say MLOperands are actually the "edges" within the graph, while the operators are "nodes". For a node, the input edges represent the input operands of this operator, the output edges represent the output operands of this operator. There could be three types of edge: 1) input edge that only points to a node ("to" node) without the "from" node. It represent the graph input; 2) intermediate edge that connects two nodes, "from" node and "to" node; 3) output edge that only has a "from" a node without a "to" node.

For WebNN MLOperand kind,

  • "input" MLOperand should map to input edge of the computational graph.
  • "constant" MLOperand should also map to input edge, bound with static data.
  • "output" MLOperand is always has the "from" node. It may be two possible types of edge:
    • When it is consumed by another operator, say used as an input operand for an operator build method, builder.relu(x), it turns to an intermediate edge.
    • When it is passed to build(MLNamedOperands outputs) method in the outputs argument, it turns to the output edge of the computational graph.

It might be helpful to refer to a platform graph API, such as DirectML DML_GRAPH_DESC.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Besides "register", I suppose the MLOperand should keep the platform operand object (or the edge of platform computational graph) created by platform graph builder as an internal slot. This platform object should be passed to the platform graph builder when creating an operator (or the node of the platform computational graph).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks Ningxin, looks like this uncovered a lot of things :).
I can do all these, but it is hard to formally use here a graph concept that is defined later (by implementations).

I agree we should define the elements of the structure in the spec, by internal slots (the edge position you described above) and also reference examples like DirectML as you suggested.

We can/should define algorithms for what it means to "register as a constant" or as an output, associating an internal slot for them.

These "create MLOperand" and "create MLActivation" are anyway meta-algorithms, used internally in the spec, so anything build by them is a temporary step, will be completed when these are referenced from the methods of MLGraphBuilder. So it is there many of the things described in your later comments would happen.

All in all, I think we need a revamp of the programming model, MLGraphBuilder etc. Should I do that in this PR?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All in all, I think we need a revamp of the programming model, MLGraphBuilder etc. Should I do that in this PR?

@zolkis yes, the smaller the PRs the easier to review and discuss. I'm not sure if stacked PRs work here but that could be one solution.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have experimented how these slots would play out.

I ended up making minimal changes for this, removing the unneeded slots, but did not introduce new slots for platform objects. Will do that later if needed - at the moment they are not needed and can be referred to in prose.

index.bs Outdated
1. Set [=this=]'s {{MLOperand/[[dimensions]]}} to |desc|.{{MLOperandDescriptor/dimensions}}.
1. Make a request to the underlying platform to register [=this=] as an input.
1. If that fails, throw a "{{TypeError}}" {{DOMException}} and abort these steps.
1. Otherwise, of |kind| is `"output"`:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An "output" operand should be created from one of the operator build methods. I think the "platform operator" (or the node of the platform computational graph) that produces this operand should be passed as the next argument and it should be kept in the [[operator]] internal slot.

index.bs Outdated
: <dfn>\[[builder]]</dfn> of type {{MLGraphBuilder}}
::
The {{MLOperand}}'s associated builder object.
: <dfn>\[[operator]]</dfn> of type [=function=]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not familiar with [=function=]. Does it mean a JavaScript function? Would operator be the underlying platform operator object (or the node of the platform computational graph)?

Copy link
Collaborator Author

@zolkis zolkis Mar 20, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I meant the latter and this needs some rework. For denoting a platform object ('s reference), the internal slot will be a generic object (that can be a function as well).

index.bs Outdated
: <dfn>\[[name]]</dfn> of type [=string=]
::
The {{MLOperand}}'s name (only for input operands).
: <dfn>\[[tensorData]]</dfn> of type {{ArrayBufferView}}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is [[tensorData]] needed to be an internal slot? I suppose the values of ArrayBufferViews should be passed to platform graph builder when "register" the constant. What's the use case of it?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, that is the use case for it, AFAICT. The "create MLOperand" steps are continued in the builder methods, but they might need the slot for tensor data. But if something is not needed (no use case), will be removed.

index.bs Outdated
1. If |dimensions| is not an array of positive numbers, return `false`;
1. If |dimensions|.length is 0, return `false`.
1. If |dimensions|.length is too large to be supported by the implementation, return `false`.
1. If any element of |dimensions| is too large to be supported by the implementation, return `false`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The range should be [1, ULONG_MAX].

index.bs Outdated
Objects implementing the {{MLActivation}} interface represent activation function types.

<script type=idl>
typedef object MLActivationOptions;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the type MLActivationOptions be an union of all supported options type, say

typedef (MLClampOptions or MLLeakyReluOptions or ...) MLActivationOptions;

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it's the union of all supported options.
Should we explicitly enumerate all of them in a typedef (that would cover a gap in the Web IDL), or should we use a generic dictionary and specify in prose the current meaning? (that would not change the Web IDL, but would clarify the prose).
I do see value in both approaches.
@anssiko do you have a preference?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@zolkis in general if we can define something in Web IDL we should prefer that way over prose. Web IDL is machine-readable and allows for bindings code generation and testing.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SGTM. It's a bit unusual to have such long unions, currently 12 of them, but we can easily revert any time, in the case an external reviewer finds that awkward.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Filed #363 to track this, if we want to.
For now I will go with the explicit union then.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think you can have a WebIDL union of dictionaries, since dictionaries aren't distinguishable and union members must be distinguishable.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks Dom for that reminder. Looks like we are going with option 1, i.e. generic dictionary + specific spec prose in algorithms.

Copy link
Collaborator

@wchao1115 wchao1115 Apr 13, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need to define a new type called MLActivationOptions? An MLActivation is already an abstract interface that can sufficiently represent all available activation types (that are available for operator fusions) e.g. the clamp activation as an MLActivation interface is already created wtih the specific MLClampOptions accordingly.

Also a union of all relevant activation options is unnecessary since the use case for each will only always require just one concrete activation option type e.g. MLClampOptions for clamp activation, etc.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Chai, are you saying that instead of a union of MLActivationOptions we should define a separate type for each respective activation option?

I sympathize with that, and removing the generic object typedef - it doesn't add much value indeed. It is like specifying function interface with generic object parameters.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed MLActivationOptions.

@zolkis
Copy link
Collaborator Author

zolkis commented Mar 20, 2023

@huningxin
I made a simplified minimal version and fixed the things you commented.
When we will need the extra internal slots, for instance for platform objects, we can add later, from the PRs that will need those. In this PR we have the generic minimal version.

Next, I will do input() and constant() and will also attempt the build() steps, at least a start, to see how it plays out with MLOperand and MLActivation slots. But that needs this PR merged.

@zolkis zolkis force-pushed the operand-activation-improvements branch from 13fd3c5 to 37e02db Compare March 21, 2023 08:44
@zolkis
Copy link
Collaborator Author

zolkis commented Mar 21, 2023

I am preparing the PR for input() and constant(), and that enables simplifying this PR. Moving it back to WiP.

@zolkis zolkis changed the title Add internal slots to MLOperand and MLActivation WiP: Add internal slots to MLOperand and MLActivation Mar 21, 2023
…or aligning with builder's upcoming input(), constant() and MLGraph steps/improvements.

Signed-off-by: Zoltan Kis <[email protected]>
@zolkis
Copy link
Collaborator Author

zolkis commented Mar 22, 2023

Quite a lot of changes, but now it works with the upcoming builder/input() and constant() steps.
Removing WiP, now it can be reviewed/merged. @huningxin PTAL.

@zolkis zolkis changed the title WiP: Add internal slots to MLOperand and MLActivation Add internal slots to MLOperand and MLActivation Mar 22, 2023
@zolkis
Copy link
Collaborator Author

zolkis commented Mar 22, 2023

Added a "copy MLOperand" and "validate MLOperand" steps since needed in other algorithms.

@zolkis zolkis mentioned this pull request Mar 22, 2023
zolkis pushed a commit to zolkis/webnn that referenced this pull request Mar 24, 2023
zolkis pushed a commit to zolkis/webnn that referenced this pull request Mar 24, 2023
Zoltan Kis added 2 commits April 3, 2023 22:03
…OperandKind typedef from the IDL

Signed-off-by: Zoltan Kis <[email protected]>
index.bs Outdated
Objects implementing the {{MLActivation}} interface represent activation function types.

<script type=idl>
typedef object MLActivationOptions;
Copy link
Collaborator

@wchao1115 wchao1115 Apr 13, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need to define a new type called MLActivationOptions? An MLActivation is already an abstract interface that can sufficiently represent all available activation types (that are available for operator fusions) e.g. the clamp activation as an MLActivation interface is already created wtih the specific MLClampOptions accordingly.

Also a union of all relevant activation options is unnecessary since the use case for each will only always require just one concrete activation option type e.g. MLClampOptions for clamp activation, etc.

zolkis pushed a commit to zolkis/webnn that referenced this pull request May 14, 2023
Squashed the following commits:
Enclose arg + return descriptions to separate from normative algorithms
Change manual link to autolink
Use the 'get a copy' reference for buffer source
Factor our validating bufferview with descriptor
Fix initialization typo
Add reference to the platform operand object  MLOperand/[[operand]]
Lift dependency changes from webmachinelearning#337
Fix typos, remove unneeded dependencies from webmachinelearning#337
Add dependency for buffer validation from webmachinelearning#329
Fix the scalar algorithm / comments
Discern between scalar and tensor constant, fix typos
Fix review comments. Add stylistic boxes for algorithm steps, informal steps, internal slots
Fix typo. Remove stylistic boxes for now.
Address reviews comments. Remove MLOperandKind typedef from the IDL.
Move note to text. Make the check on kind an assert.
Remove the MLOperand/[[kind]] internal slot and creation parameter.
Remove back quotes from title

Signed-off-by: Zoltan Kis <[email protected]>
zolkis pushed a commit to zolkis/webnn that referenced this pull request May 14, 2023
Squashed the following commits:
    Enclose arg + return descriptions to separate from normative algorithms
    Change manual link to autolink
    Use the 'get a copy' reference for buffer source
    Factor our validating bufferview with descriptor
    Fix initialization typo
    Add reference to the platform operand object  MLOperand/[[operand]]
    Lift dependency changes from webmachinelearning#337
    Fix typos, remove unneeded dependencies from webmachinelearning#337
    Add dependency for buffer validation from webmachinelearning#329
    Fix the scalar algorithm / comments
    Discern between scalar and tensor constant, fix typos
    Fix review comments. Add stylistic boxes for algorithm steps, informal steps, internal slots
    Fix typo. Remove stylistic boxes for now.
    Address reviews comments. Remove MLOperandKind typedef from the IDL.
    Move note to text. Make the check on kind an assert.
    Remove the MLOperand/[[kind]] internal slot and creation parameter.
    Remove back quotes from title

Signed-off-by: Zoltan Kis <[email protected]>
zolkis pushed a commit to zolkis/webnn that referenced this pull request May 15, 2023
Squashed the following commits:
    Enclose arg + return descriptions to separate from normative algorithms
    Change manual link to autolink
    Use the 'get a copy' reference for buffer source
    Factor our validating bufferview with descriptor
    Fix initialization typo
    Add reference to the platform operand object  MLOperand/[[operand]]
    Lift dependency changes from webmachinelearning#337
    Fix typos, remove unneeded dependencies from webmachinelearning#337
    Add dependency for buffer validation from webmachinelearning#329
    Fix the scalar algorithm / comments
    Discern between scalar and tensor constant, fix typos
    Fix review comments. Add stylistic boxes for algorithm steps, informal steps, internal slots
    Fix typo. Remove stylistic boxes for now.
    Address reviews comments. Remove MLOperandKind typedef from the IDL.
    Move note to text. Make the check on kind an assert.
    Remove the MLOperand/[[kind]] internal slot and creation parameter.
    Remove back quotes from title

Signed-off-by: Zoltan Kis <[email protected]>
anssiko pushed a commit that referenced this pull request May 15, 2023
Squashed the following commits:
    Enclose arg + return descriptions to separate from normative algorithms
    Change manual link to autolink
    Use the 'get a copy' reference for buffer source
    Factor our validating bufferview with descriptor
    Fix initialization typo
    Add reference to the platform operand object  MLOperand/[[operand]]
    Lift dependency changes from #337
    Fix typos, remove unneeded dependencies from #337
    Add dependency for buffer validation from #329
    Fix the scalar algorithm / comments
    Discern between scalar and tensor constant, fix typos
    Fix review comments. Add stylistic boxes for algorithm steps, informal steps, internal slots
    Fix typo. Remove stylistic boxes for now.
    Address reviews comments. Remove MLOperandKind typedef from the IDL.
    Move note to text. Make the check on kind an assert.
    Remove the MLOperand/[[kind]] internal slot and creation parameter.
    Remove back quotes from title

Signed-off-by: Zoltan Kis <[email protected]>
@zolkis zolkis marked this pull request as draft May 17, 2023 10:20
@zolkis
Copy link
Collaborator Author

zolkis commented May 17, 2023

Marked as a draft because some parts have been lifted to merged PRs, and some other parts could be used by other PRs, in the pace they will be needed.

@zolkis
Copy link
Collaborator Author

zolkis commented Jun 13, 2023

Moved to #400 with new target branch.

@zolkis zolkis closed this Jun 13, 2023
@zolkis zolkis deleted the operand-activation-improvements branch November 12, 2024 13:58
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

Successfully merging this pull request may close these issues.

Add internal slots to MLOperand, MLActivation and basic algorithms

5 participants