-
Notifications
You must be signed in to change notification settings - Fork 6
Describe levels of Op equality #94
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
Changes from all commits
f925982
5aedf49
282b3ef
24e52a6
f681ff1
26ca8a5
a0fd104
bf1a935
3094161
1989410
9a2d230
5439fa9
a178f2c
7424ab6
d10b3bf
f8eda92
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,62 @@ | ||
| /** | ||
| * This module contains the API necessary to retrieve, execute, and reason about Ops. | ||
| * | ||
| * <h1>What is the SciJava Ops Library?</h1> | ||
| * SciJava Ops arose from a desire for simplicity - there are lots of different algorithmic libraries, each with their own data structures, algorithm syntax, and other requirements. With all of these differences, library interoperability can be a daunting task. This can lead to algorithm reimplementations, unmaintained code, and a lack of cooperation between open-source communitites. SciJava Ops seeks to unify different libraries under a single framework, separating the development of new algorithms from the way they are executed. | ||
| * | ||
| * Put more succinctly, the goals of SciJava Ops are the following: | ||
| * <ul> | ||
| * <li><b>Usability</b> All Ops should be called in the same way, and implementation details should be hidden - this means that the user should call an Op the same way, whether the algorithm is written in Java, Python, or as a CUDA kernel.</li> | ||
| * <li><b>Extensibility</b> New Ops should be accommodated in a variety of programming languages, and each language should provide minimally-invasive methods for declaring code blocks as Ops. This also means that Ops should accommodate writing Ops in one language, and then calling Ops using data structures from a different language.</li> | ||
| * <li><b>Generality</b> Ops should allow any number of typed inputs, without restriction on input types. With no restrictions on input types, the library can seamlessly adapt new data structures tailored to performance or expressiveness as they are developed.</li> | ||
| * <li><b>Speed</b> Calling Ops should be approximately as performant as invocation in their natural setting (such as Python, C++, Java, or another language entirely).</li> | ||
| * </ul> | ||
| * | ||
| * <h1>What is an Op?</h1> | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We talked recently about writing up the "philosophy of Ops" or some such, to explain the purpose of the library, design goals, etc. Perhaps this javadoc block would be a good place to put that? There is some material in that direction at https://imagej.net/libs/imagej-ops. I don't love that page though; I think we could do a better job describing the intent of the library from a broader and more easily understood perspective.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wrote a little more, aligned with the bullets in https://imagej.net/libs/imagej-ops, in d723b0e. Let me know what you think @ctrueden |
||
| * | ||
| * An Op is an algorithm adhering to the following traits: | ||
| * <ol> | ||
| * <li>Ops are stateless and deterministic - with no internal state, calling an Op two times on the same inputs will produce the same output.</li> | ||
| * <li>Ops are named - this name conveys an Op's purpose, and allows us to find all Ops implementing a particular operation</li> | ||
| * </ol> | ||
| * Using the name and the combination of input and output parameters, we can retrieve, or "match", any Op from within an {@link org.scijava.ops.api.OpEnvironment}. Op calls with the same name and specified inputs/outputs will be reproducible within a particular Op environment. | ||
| * | ||
| * <h1>Op Equivalence</h1> | ||
| * To support the Op matching paradigm, we establish three types of equivalence: | ||
| * <ol> | ||
| * <li><b>Form Equivalence</b></li> Form Equivalence implies that two objects (which could be Ops, or Op parameters) theoretically draw from the same shared idea (such as an addition operation, or an image, etc.) | ||
| * <li><b>Structural Equivalence</b></li> Structural Equivalence means that two Ops: | ||
| * <ol> | ||
| * <li>Are Form Equivalent</li> | ||
| * <li>Have the same number of inputs and the same number of outputs</li> | ||
| * <li>For each input position, accept form-equivalent inputs</li> | ||
| * <li>Return form-equivalent outputs</li> | ||
| * </ol> | ||
| * <li><b>Result Equivalence</b></li> Result Equivalence means that {@code o1.equals(o2)} for two outputs {@code o1} and {@code o2} from two Ops. | ||
| * </ol> | ||
| * Within the Ops API, each type of equivalence is utilized in the following ways: | ||
| * <ol> | ||
| * <li><b>Form Equivalence</b></li> If two Ops are form-equivalent, they are defined under the same name. | ||
| * <li><b>Structural Equivalence</b></li> If two Ops are structural-equivalent, they share a common form-reduced description, searchable using {@link org.scijava.ops.api.OpEnvironment#descriptions(java.lang.String)}. For example, an Op "math.add" that produces an ImgLib2 Img from Img operands, and another Op "math.add" that produces a NumPy ndarray from ndarray operands, will reduce to a single description "math.add" that produces an image from image operands. | ||
| * <li><b>Result Equivalence</b></li> If two Ops are result-equivalent, they produce equivalent values, using the primary language-specific definition of equality (e.g. `Object.equals`, for Java usage). | ||
| * </ol> | ||
| * | ||
| * For example, consider three Ops: | ||
| * <ol> | ||
| * <li> filter.gauss(net.imglib2.img.Img, net.imglib2.type.numeric.real.FloatType) -> net.imglib2.img.Img</li> | ||
| * <li> filter.gauss(ij.ImagePlus, java.lang.Double) -> ij.ImagePlus</li> | ||
| * <li> filter.gauss(net.imglib2.img.Img, net.imglib2.algorithm.neighborhood.Shape) -> net.imglib2.img.Img</li> | ||
| * </ol> | ||
| * Ops 1 and 2 are considered form-equivalent, as they have the same name, and structural-equivalent, as they both take in an image data structure and a floating point number and return an image data structure, but may not be result-equivalent due to implementation differences between the two Ops, or precision loss of the data structures. | ||
| * <p> | ||
| * Ops 1 and 3 are also form-equivalent, as they have the same name, but are not structural-equivalent, as one has an implicit Shape over which to perform a gaussian blur, while the other uses an explicitly specified shape. | ||
| * <p> | ||
| * These definitions of equivalence provide clarity when articulating the Ops framework's benefits: | ||
| * <ol> | ||
| * <li>Form-equivalence in Ops allows a comprehensive search of the available algorithms for accomplishing a particular algorithm, by searching its name</li> | ||
| * <li>Form-equivalence in data inputs allows us to consider algorithm inputs in a library-agnostic way, making it easier to understand and use algorithms</li> | ||
| * <li>Structural-equivalence in Ops allows us to consider similar Ops in different languages as one, and to delegate to the proper Op using user inputs. In other words, you can call structural-equivalent Ops identically, and Scijava Ops will take care to call the correct Op based on the concrete inputs provided.</li> | ||
| * <li>Result-equivalence, and therefore reproducability, in Ops, is guaranteed within an OpEnvironment and a set of input objects, but not for Op calls. This allows us to ensure reproducible pipelines, but also allows us to introduce new Ops into the pipeline or to run pipelines on different inputs without changing the pipeline itself.</li> | ||
| * </ol> | ||
| */ | ||
| package org.scijava.ops.api; | ||
Uh oh!
There was an error while loading. Please reload this page.