Skip to content

[Upcoming] Version 1.2.0 Release Notes #473

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

Closed
dmed256 opened this issue Jan 21, 2021 · 0 comments
Closed

[Upcoming] Version 1.2.0 Release Notes #473

dmed256 opened this issue Jan 21, 2021 · 0 comments

Comments

@dmed256
Copy link
Member

dmed256 commented Jan 21, 2021

Table of Contents

πŸ”₯ Exciting News

We introduce 3 awesome new features to the OCCA library. They are still in the πŸƒ experimental stage, mainly due to performance reasons. We found an initial approach to enabling inlined lambdas and wanted to see how far we could go with them.

Future work includes profiling and optimizing build + launch of the inlined lambdas. How we cache kernel builds and fetch from the cache is still up in the air, but looking forward to tacking this fun problem πŸ˜ƒ.

πŸƒ occa::forLoop and inlined kernels

Basic Example

Here we generate a for-loop that goes through [0, N) and tiled by tileSize

occa::forLoop()
  .tile({N, tileSize})
  .run(scope, OCCA_FUNCTION([=](const int index) -> void {
    // ...
  }));

We can do it manually by calling .outer and .inner

occa::forLoop()
  .outer(occa::range(0, N, tileSize))
  .inner(tileSize)
  .run(scope, OCCA_FUNCTION([=](const int outerIndex, const int innerIndex) -> void {
    const int index = innerIndex + (tileSize * innerIndex);
    // ...
  }));

Indices + Multiple Dimensions

We give an example where an index array is passed rather than a simple occa::range
Additionally, this @inner loop has 2 dimensions so the expected OCCA_FUNCTION should be taking in an int2 for the inner indices

occa::array<int> indices;
// ...
occa::forLoop()
  .outer(indices)
  .inner(X, Y)
  .run(scope, OCCA_FUNCTION([=](const int outerIndex, const int2 innerIndex) -> void {
    // ...
  }));

πŸƒ occa::array and Functional Programming

We introduce a simple wrapper on occa::memory which is typed and contains some of the core map and reduce functional methods.

Example

const double dynamicValue = 10;
const double compileTimeValue = 100;

occa::scope scope({
  // Passed as arguments
    {"dynamicValue", dynamicValue}
  }, {
  // Passed as compile-time #defines
    {"defines/compileTimeValue", compileTimeValue}
});

occa::array<double> doubleValues = (
  values.map(OCCA_FUNCTION(scope, [](int value) -> double {
    return compileTimeValue + (dynamicValue * value);
  }));
);

We also include a helper method occa::range which implements most of the occa::array methods but can be used without allocating data before iteration. It's useful if there is no specific input/output but still need to call a generic map or reduce function.

// Iterates through [0, 1, 2]
occa::range(3).map(...);

// Iterates through [3, 4, 5]
occa::range(3, 6).map(...);

// Iterates through [6, 5, 4]
occa::range(6, 3).map(...);

// Iterates through [0, 2, 4]
occa::range(0, 6, 2).map(...);

// Iterates through [6, 4, 2]
occa::range(6, 0, -2).map(...);

// No-op since there isn't anything to iterate through
occa::range(6, 0, 1).map(...);
Core methods
  • forEach
  • mapTo
  • map
  • reduce
Reduction
  • every
  • max
  • min
  • some
Re-indexing
  • reverse
  • shiftLeft
  • shiftRight
Utility methods
  • cast
  • clamp
  • clampMax
  • clampMin
  • concat
  • dot
  • fill
  • slice
Search
  • findIndex
  • find
  • includes
  • indexOf
  • lastIndexOf

πŸƒ Atomics

It's still in it's πŸƒ experimental stage, but OKL now allows for basic atomic operations!

ℹ️ Β  @atomic should be fully available for Serial and OpenMP modes. There is probably still room for improvement in the OpenMP implementation!

⚠️   GPU modes (HIP, CUDA, OpenCL) don't have general atomics implemented, only have the following basic updates:

  • @atomic value += update;
  • @atomic value -= update;
  • @atomic value &= update;
  • @atomic value |= update;
  • @atomic value ^= update;

Inlined @atomic

@atomic *ptr += value;

Block @atomic

If you prefer, you can use blocks which will be equivalent to inlined @atomic use if possible

@atomic {
  *ptr += value;
}

However, generic @atomic blocks are also possible

@atomic {
  *ptr  += value;
  *ptr2 += value2;
}

πŸƒ DPC++ Backend

The DPC++ backend was added by the great work completed jointly by ALCF and Intel, with contributions from:

  • Anoop Madhusoodhanan Prabha (Intel)
  • Cedric Andreolli (Intel)
  • Kris Rowe (ALCF)
  • Phillipe Thierry (Intel)
  • Saumil Patel (ALCF)

Notes

Currently only building with CMake is supported.

Code Transformation Rewrite

The way statement and expression code transformations are done have been fully rewritten!

A functional occa::lang::array class was introduced to help with statement (statement_t) and expression (exprNode) iteration and transformation. More information on PR #404.

Additionally the occa::lang::expr class helps create expressions easily without having to worry about pointers or underlying node objects. More information on PR #407.

⚠️ Breaking Changes

  • This is more of a potential breaking change but in a series of commits, we finally split up the public/private API!

  • occa::properties is now deprecated and replaced with occa::json

occa::properties wasn't adding much on top of occa::json, instead making auto-casting harder since we had to handle both json and prop objects. We still keep the properties and props naming convention throughout the library, since that's what they are but have transitioned the types to occa::json.

We still have a

typedef json properties;

so there shouldn't be any type-breaking changes for C++. The big difference is how std::string is being cast to json/properties:

  • std::string ? occa::properties: The std::string value is parsed into its JSON value. For example, we can pass {key: 1} or key: 1
  • std::string ? occa::json: The occa::json value is a literal string value. For example, if we pass {key: 1} then the occa::json value will be a string whose value is "{key: 1}".

Details about the refactor:
- [C++] The only breaking change is property strings now need to have the surrounding braces ({}) to make it valid JSON
- [C] All property methods have been removed and should be replaced with the Json methods
- [Fortran] All property methods have been removed and should be replaced with the Json methods

⭐ Features

πŸ› Bugs Fixed

πŸŽ‰ Contributors

@dmed256 dmed256 pinned this issue Jan 21, 2021
@dmed256 dmed256 changed the title Version 1.2.0 Release Notes [Upcoming] Version 1.2.0 Release Notes Jan 21, 2021
@kris-rowe kris-rowe unpinned this issue Mar 23, 2022
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