Loading repository data…
Loading repository data…
mrnorman / repository
YAKL is A Kokkos Layer: A simple C++ framework for performance portability and Fortran code porting
A transparent discovery signal based on current public GitHub metadata.
This score does not audit code, security, maintainers, documentation quality, or suitability. Verify the repository and its current documentation before adoption.
yakl::Array now derived from Kokkos:View, yakl::DeviceSpace is now a Kokkos::MemorySpace, and YAKL now uses C++20KOKKOS_IMPL_SHARED_ALLOCATION_SPECIALIZATION, KOKKOS_IMPL_HOST_INACCESSIBLE_SHARED_ALLOCATION_SPECIALIZATION, KOKKOS_IMPL_SHARED_ALLOCATION_RECORD_EXPLICIT_INSTANTIATION, KOKKOS_IMPL_HOST_INACCESSIBLE_SHARED_ALLOCATION_RECORD_EXPLICIT_INSTANTIATION macro functions are defined and behave as they have from 2024-2026.yakl::Array (formally yakl::CArray) and yakl::Array_F (formally yakl::FArray) are now derived from Kokkos::View and, by default, use View member functions, data, constructors, and destructors. Further, yakl::DeviceSpace is now formally a Kokkos::MemorySpace and can be used as such for yakl::Array, yakl::Array_F, and Kokkos::View class objects.
yakl::Array and yakl::Array_F template parameters: (1) The Kokkos-like data_type, e.g., float ** that replaces the previous templates of value_type, T, and rank integer, N; and (2) the memory space, e.g. yakl::DeviceSpace or Kokkos::HostSpce. All YAKL objects are assumed to take on one of these two memory spaces, meaning it is host or device resident just like before.
data_type (e.g., int ***) using the template <class T, int N> yakl::ViewType struct. E.g., using my_view_type = typename yakl::ViewType<float,4>::type, which set float **** as my_view_type.template <class KT, class MemSpace = yakl::DeviceSpace> yakl::Array[_F]: The yakl::Array class assumes Kokkos::LayoutRight (row-major indexing where the last index varies the fastest), and the yakl::Array_F class assumes Kokkos::LayoutLeft (column-major indexing where the first index varies the fastest).yakl::Array are derived directly from Kokkos::View. Because yakl::Array inherits ctors, dtors, assignment operator= and operator() directly from the , it should for all intents and purposes behave just like a in the Kokkos ecosystem with the traditional YAKL bells and whistles like: , , , , , , , , , , , , , , , , and . The same is not guaranteed to be true for because it was prudent to include the ctors and copy and move assignment operators to avoid accidentally creating an object without the lower bounds properly specified.Kokkos::ViewViewArray::deep_copy_tooperator=(T rhs) requires std::is_arithmetic_v<T>slicesubset_slowest_dimensionreshapecollapsecreateDeviceObjectcreateHostObjectcreateDeviceCopycreateHostCopyasextentsuboundslboundsbeginendoperator<<Array_FViewArray_Fyakl::Array_F (the Fortran-style Array class) you need to use the constructors: Array_F(std::string label, {lower1,upper1}[, ...]) and Array_F( value_type * ptr, {lower1,upper1}[, ...]), where the initializer lists populate yakl::Array_F::AB struct objects that contain a lower (inclusive) and upper bound (inclusive) for each dimension of the array.yakl::Array and yakl::Array_F objects now use Kokkos's SharedAllocationRecord internals, which means behavior changes a bit now
Array or Array_F class.slice, reshape, collapse or subset_slowest_dimension on the host, it is no longer reference counted with the creating object like it was before but is rather a non-owning View that is purely at the mercy of the user making sure the owning Array object that created it does not deallocate its memory by falling out of scope before the non-owning object is finished being used.Style template parameter for yakl::Array objects no longer exists. Rather the user needs to explicitly create an Array or Array_F object for a C-style or Fortran-style Array object, respectively._F suffix appended to a class or function name is now used to indicate that it is Fortran-style, and the ommision of that suffix indicates that it is C-style. This is true for Array[_F], SArray[_F], parallel_for[_F], Bounds[_F], and SimpleBounds[_F]. The Style template parameter is removed in lieu of this clearer syntax.yakl::DeviceSpace, which satisfies the concepts of a Kokkos::MemorySpace. It is assumed that if compiling for a GPU device target that the host space is not accessible. This may be relaxed in the future, but since paging memory automatically to and from device memory with CUDA / HIP Managed Memory or Linux kernel memory paging is so much less performant than user-managed memory, it is being disabled for now so that users can more easily see when they are accidentally accessing host memory on the device or device memory on the host. The core yakl::DeviceSpace class is extremely simple and merely calls YAKL's alloc_device and free_device routines that automatically use the YAKL memory pool when it is enabled. You can deep_copy between yakl::DeviceSpace and KokkosHostSpace as well as between yakl::DeviceSpace and Kokkos::DefaultExecutionSpace::memory_space. In fact, yakl::DeviceSpace uses Kokkos::DefaultExecutionSpace::memory_space behind the scenes.yakl::SArray class (formerly aliased from yakl::CSArray) for small, local stack-based arrays in the memory space of the execution space being used in a parallel_for call has changed its template parameters. You no longer specify the rank explicitly but rather just specify the type and the dimensions directly. Therefore, a 2-D SArray object will now be specified as template <class T, std::integral auto dimensions...> SArray, meaning the user will now declare something like, yakl::SArray<float,nx,ny> my_local_stack_array;, and YAKL can infer from the constructor template parameters what the rank of the array is. The same is true for the yakl::SArray_F class (previously yakl::FSArray), except that the user needs to use the yakl::Bnds class to specify the lower (inclusive) and upper (inclusive) bounds of the array. E.g., using yakl::Bnds; yakl::SArray_F<double,Bnds{1,nx},Bnds{1,nz}> my_fortran_stack_array;. I trid to get rid of the need for specifying Bnds in that syntax, but not all compiler play nicely with Non-Type Template Parameters (NTTPs) resulting from the initializer list syntax. So, we're stuck with it. You can obtain the rank of an SArray or SArray_F object with the static constexpr int rank class data member.
SArray and SArray_F classes both define the Kokkos::View's value_type, const_value_type, non_const_value_type types. They also define is_SArray=true, rank, is_cstyle, and is_fstyle as static constexpr class data members. As before, they both define operator=(T rhs) requires std:is_arithmetic_v<T>, operator() const, data(), begin(), end(), size(), span_is_contiguous() {return true;}, is_allocated() {return true;}, extent(int i), extent<I>(), operator<<, extents(), lbounds(), ubounds().Array, Array_F, SArray, or SArray_F object to a function is to declare a generic template parameter, template <class ArrayLike> and add a requires clause to constrain the properties of the object such as requires yakl::is_Array<ArrayLike> && (ArrayLike::rank()==3) && ArrayLike::is_cstyle or requires yakl::is_SArray<ArrayLike> && (ArrayLike::rank==2) && ArrayLike::is_fstyle && std::is_integral_v<ArrayLike::value_type>.parallel_for launcher is largely the same as before with a slightly more performant implementation under the hood, which still ultimately uses Kokkos::parallel_for for all launches but still avoids using MDPolicyRange due to some performance issues. The biggest changes is that if you want Fortran-style parallel_for and Bounds, you need to append the _F suffix to the functions to declare that rather than relying on a Style parameter.
using yakl::parallel_for and pass a size_t argument as the bounds to a parallel_for call without an explicit namespace. One compiler pass will resolve yakl::parallel_for, and another will resolve Kokkos::parallel_for, and you will get an invalid device kernel error at runtime. Please always code yakl::parallel_for explicitly rather than coding using yakl::parallel_for followed by a call to parallel_for without a namespace if you want to avoid this. The size() member function of Kokkos View objects (and therefore of YAKL Array objects) returns a size_t type and will trigger this issue as well. Please see this documentation for more information on this Argument Dependent Lookup (ADL) issue with CUDA.yakl::componentwise namespace now has functions for any combination of [arithmetic_type || SArray[_F]] or [arithmetic_type || Array[_F]] parameter for binary operators: operator[+-/*<>], operator<=, operator>=, operator==, operator!=, operator&&, operator||. It also has functions for Array[_F] or SArray[_F] inputs to unary operators: operator[!+-], abs,sqrt,cbrt,pow(arr,arithmetic),sin,cos,tan,asin,acos,atan,exp,log,log10,log2,floor,ceil,round,isnan,isinf. Each of these will launch a kernel to run the operation componentwise on the input(s) and return the result in a new Array or SArray object of the correction operation result type depending on the input(s). These are intended mainly to help users write debug and unit testing code more quickly, since each function/operator launches a separate kernel.yakl::intrinsics namespace is the same as before except that pack has been removed because it was never running on the device anyway, and matinv_ge has been renamed to matinv and now includes partial pivoting.Toney the timer is still in there for quick and easy timer values that are queryable and given to you via std::cout upon yakl::finalize(). It's been simplified, and you now have access to the following control/lookup functions in the yakl:: namesapce based on timer's std::string label: timer_start(label), timer_stop(label), timer_get_last_duration(label), timer_get_accumulated_duration(label), timer_get_min_duration(label), timer_get_max_duration(label), and timer_get_count(label). You can also call the timer_print() function at any point to send the user the current timer count,min,max,accumulated values. All timers must still be perfectly nested so the class can identify parent and child timers and format the output appropriately.Array[_F] classes now accept any integral type for ctors and operator(), and the Array_F class accepts ptrdiff_t types for the dimension bounds. The parallel_for[_F] and [Simple]Bounds[_F] classes use size_t and ptrdiff_t types. So indexing arrays larger than 2B indices and looping over more than 2B indices is technically allowed now. However, be aware that individual GPU backends often limit these sizes to unsigned int types, so I still do not advise this.int yakl::memHost --> class Kokkos::HostSpaceint yakl::memDevice --> class yakl::DeviceSpace