From 647efdc24fecd0fe23dded81d1cf253c675b6549 Mon Sep 17 00:00:00 2001 From: Hannes Vogt Date: Tue, 7 Mar 2023 14:35:52 +0000 Subject: [PATCH 1/7] Cartesian vs Next example --- examples/lap_cartesian_vs_next.ipynb | 155 +++++++++++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 examples/lap_cartesian_vs_next.ipynb diff --git a/examples/lap_cartesian_vs_next.ipynb b/examples/lap_cartesian_vs_next.ipynb new file mode 100644 index 0000000000..e42e41ed3e --- /dev/null +++ b/examples/lap_cartesian_vs_next.ipynb @@ -0,0 +1,155 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "GT4Py - GridTools for Python\n", + "\n", + "Copyright (c) 2014-2023, ETH Zurich\n", + "All rights reserved.\n", + "\n", + "This file is part the GT4Py project and the GridTools framework.\n", + "GT4Py is free software: you can redistribute it and/or modify it under\n", + "the terms of the GNU General Public License as published by the\n", + "Free Software Foundation, either version 3 of the License, or any later\n", + "version. See the LICENSE.txt file at the top-level directory of this\n", + "distribution for a copy of the license or check .\n", + "\n", + "SPDX-License-Identifier: GPL-3.0-or-later" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Comparison gt4py.cartesian vs. gt4py.next" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Imports" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "\n", + "nx = 32\n", + "ny = 32\n", + "nz = 1\n", + "dtype = np.float64" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "gt4py.cartesian\n", + "--" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "import gt4py.storage as storage\n", + "import gt4py.cartesian.gtscript as gtscript\n", + "\n", + "backend = \"numpy\"\n", + "# backend = \"gt:cpu_ifirst\"\n", + "\n", + "@gtscript.stencil(backend=backend)\n", + "def lap_cartesian(\n", + " inp: gtscript.Field[dtype],\n", + " out: gtscript.Field[dtype],\n", + "):\n", + " with computation(PARALLEL), interval(...):\n", + " out = -4.0 * inp[0, 0, 0] + inp[-1, 0, 0] + inp[1, 0, 0] + inp[0, -1, 0] + inp[0, 1, 0]\n", + "\n", + "inp = storage.from_array(np.fromfunction(lambda x, y, z: x**2+y**2, shape=(nx, ny, nz)), dtype, backend=backend)\n", + "out_cartesian = storage.zeros((nx, ny, nz), dtype, backend=backend)\n", + "\n", + "lap_cartesian(inp=inp, out=out_cartesian, origin=(1, 1, 0), domain=(nx-2, ny-2, nz))" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "from gt4py.next.common import Dimension, Field\n", + "from gt4py.next.ffront.decorator import field_operator, program\n", + "from gt4py.next.ffront.fbuiltins import FieldOffset\n", + "from gt4py.next.iterator.embedded import np_as_located_field as with_dimensions\n", + "from gt4py.next.program_processors.runners.roundtrip import executor as itir_embedded\n", + "from gt4py.next.program_processors.runners.gtfn_cpu import run_gtfn as cpu_backend\n", + "\n", + "backend = itir_embedded\n", + "# backend = cpu_backend\n", + "\n", + "IDim = Dimension(\"IDim\")\n", + "JDim = Dimension(\"JDim\")\n", + "KDim = Dimension(\"KDim\")\n", + "\n", + "I = FieldOffset(\"I\", source=IDim, target=(IDim,))\n", + "J = FieldOffset(\"J\", source=JDim, target=(JDim,))\n", + "\n", + "@field_operator\n", + "def lap_next(inp: Field[[IDim, JDim, KDim], dtype]) -> Field[[IDim, JDim, KDim], dtype]:\n", + " return -4.0 * inp + inp(I[-1]) + inp(I[1]) + inp(J[-1]) + inp(J[1])\n", + "\n", + "@program(backend=backend)\n", + "def lap_next_program(inp: Field[[IDim, JDim, KDim], dtype], out: Field[[IDim, JDim, KDim], dtype]):\n", + " lap_next(inp, out=out[1:-1, 1:-1, :])\n", + "\n", + "inp_next = with_dimensions(IDim,JDim,KDim)(inp)\n", + "out_next = with_dimensions(IDim, JDim, KDim)(np.zeros(shape=(nx, ny, nz)))\n", + "\n", + "lap_next_program(inp_next, out_next, offset_provider={\"I\": IDim, \"J\": JDim})" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "assert np.allclose(out_cartesian, out_next)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.2" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} From ee54718b83d060312afd20b5bb43092498706d13 Mon Sep 17 00:00:00 2001 From: Hannes Vogt Date: Wed, 20 Dec 2023 09:51:53 +0100 Subject: [PATCH 2/7] make gtx.Fields compatible with gt4py.cartesian --- examples/lap_cartesian_vs_next.ipynb | 117 ++++++++++++------ src/gt4py/next/__init__.py | 9 ++ src/gt4py/next/common.py | 33 ++--- src/gt4py/next/embedded/nd_array_field.py | 4 - src/gt4py/next/iterator/embedded.py | 33 +++-- src/gt4py/next/iterator/tracing.py | 2 +- .../next/type_system/type_translation.py | 2 +- src/gt4py/storage/cartesian/utils.py | 2 + 8 files changed, 127 insertions(+), 75 deletions(-) diff --git a/examples/lap_cartesian_vs_next.ipynb b/examples/lap_cartesian_vs_next.ipynb index e42e41ed3e..495a6e3bbf 100644 --- a/examples/lap_cartesian_vs_next.ipynb +++ b/examples/lap_cartesian_vs_next.ipynb @@ -37,7 +37,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ @@ -49,6 +49,49 @@ "dtype = np.float64" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Storages\n", + "--" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import gt4py.next as gtx\n", + "\n", + "allocator = gtx.itir_embedded # should match the executor\n", + "\n", + "I = gtx.Dimension(\"I\")\n", + "J = gtx.Dimension(\"J\")\n", + "K = gtx.Dimension(\"K\")\n", + "\n", + "domain = gtx.domain({I: nx, J: ny, K: nz})\n", + "\n", + "inp = gtx.as_field(domain, np.fromfunction(lambda x, y, z: x**2+y**2, shape=(nx, ny, nz)), dtype, allocator=allocator)\n", + "out_cartesian = gtx.zeros(domain, dtype, allocator=allocator)\n", + "out_next = gtx.zeros(domain, dtype, allocator=allocator)" + ] + }, { "attachments": {}, "cell_type": "markdown", @@ -60,17 +103,16 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ - "import gt4py.storage as storage\n", "import gt4py.cartesian.gtscript as gtscript\n", "\n", - "backend = \"numpy\"\n", - "# backend = \"gt:cpu_ifirst\"\n", + "cartesian_backend = \"numpy\"\n", + "# cartesian_backend = \"gt:cpu_ifirst\"\n", "\n", - "@gtscript.stencil(backend=backend)\n", + "@gtscript.stencil(backend=cartesian_backend)\n", "def lap_cartesian(\n", " inp: gtscript.Field[dtype],\n", " out: gtscript.Field[dtype],\n", @@ -78,56 +120,57 @@ " with computation(PARALLEL), interval(...):\n", " out = -4.0 * inp[0, 0, 0] + inp[-1, 0, 0] + inp[1, 0, 0] + inp[0, -1, 0] + inp[0, 1, 0]\n", "\n", - "inp = storage.from_array(np.fromfunction(lambda x, y, z: x**2+y**2, shape=(nx, ny, nz)), dtype, backend=backend)\n", - "out_cartesian = storage.zeros((nx, ny, nz), dtype, backend=backend)\n", - "\n", "lap_cartesian(inp=inp, out=out_cartesian, origin=(1, 1, 0), domain=(nx-2, ny-2, nz))" ] }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ - "from gt4py.next.common import Dimension, Field\n", - "from gt4py.next.ffront.decorator import field_operator, program\n", - "from gt4py.next.ffront.fbuiltins import FieldOffset\n", - "from gt4py.next.iterator.embedded import np_as_located_field as with_dimensions\n", - "from gt4py.next.program_processors.runners.roundtrip import executor as itir_embedded\n", - "from gt4py.next.program_processors.runners.gtfn_cpu import run_gtfn as cpu_backend\n", - "\n", - "backend = itir_embedded\n", - "# backend = cpu_backend\n", + "from gt4py.next import Field\n", "\n", - "IDim = Dimension(\"IDim\")\n", - "JDim = Dimension(\"JDim\")\n", - "KDim = Dimension(\"KDim\")\n", + "backend = gtx.itir_embedded\n", + "# backend = cpu_backend\n", "\n", - "I = FieldOffset(\"I\", source=IDim, target=(IDim,))\n", - "J = FieldOffset(\"J\", source=JDim, target=(JDim,))\n", + "Ioff = gtx.FieldOffset(\"I\", source=I, target=(I,))\n", + "Joff = gtx.FieldOffset(\"J\", source=J, target=(J,))\n", "\n", - "@field_operator\n", - "def lap_next(inp: Field[[IDim, JDim, KDim], dtype]) -> Field[[IDim, JDim, KDim], dtype]:\n", - " return -4.0 * inp + inp(I[-1]) + inp(I[1]) + inp(J[-1]) + inp(J[1])\n", + "@gtx.field_operator\n", + "def lap_next(inp: Field[[I, J, K], dtype]) -> Field[[I, J, K], dtype]:\n", + " return -4.0 * inp + inp(Ioff[-1]) + inp(Ioff[1]) + inp(Joff[-1]) + inp(Joff[1])\n", "\n", - "@program(backend=backend)\n", - "def lap_next_program(inp: Field[[IDim, JDim, KDim], dtype], out: Field[[IDim, JDim, KDim], dtype]):\n", + "@gtx.program(backend=backend)\n", + "def lap_next_program(inp: Field[[I, J, K], dtype], out: Field[[I, J, K], dtype]):\n", " lap_next(inp, out=out[1:-1, 1:-1, :])\n", "\n", - "inp_next = with_dimensions(IDim,JDim,KDim)(inp)\n", - "out_next = with_dimensions(IDim, JDim, KDim)(np.zeros(shape=(nx, ny, nz)))\n", - "\n", - "lap_next_program(inp_next, out_next, offset_provider={\"I\": IDim, \"J\": JDim})" + "lap_next_program(inp, out_next, offset_provider={\"Ioff\": I, \"Joff\": J})" ] }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 5, "metadata": {}, - "outputs": [], + "outputs": [ + { + "ename": "TypeError", + "evalue": "ufunc 'isfinite' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[5], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[38;5;28;01massert\u001b[39;00m \u001b[43mnp\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mallclose\u001b[49m\u001b[43m(\u001b[49m\u001b[43mout_cartesian\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mout_next\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m<__array_function__ internals>:200\u001b[0m, in \u001b[0;36mallclose\u001b[0;34m(*args, **kwargs)\u001b[0m\n", + "File \u001b[0;32m~/git/gt4py/.venv/lib64/python3.10/site-packages/numpy/core/numeric.py:2270\u001b[0m, in \u001b[0;36mallclose\u001b[0;34m(a, b, rtol, atol, equal_nan)\u001b[0m\n\u001b[1;32m 2199\u001b[0m \u001b[38;5;129m@array_function_dispatch\u001b[39m(_allclose_dispatcher)\n\u001b[1;32m 2200\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mallclose\u001b[39m(a, b, rtol\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m1.e-5\u001b[39m, atol\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m1.e-8\u001b[39m, equal_nan\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mFalse\u001b[39;00m):\n\u001b[1;32m 2201\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[1;32m 2202\u001b[0m \u001b[38;5;124;03m Returns True if two arrays are element-wise equal within a tolerance.\u001b[39;00m\n\u001b[1;32m 2203\u001b[0m \n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 2268\u001b[0m \n\u001b[1;32m 2269\u001b[0m \u001b[38;5;124;03m \"\"\"\u001b[39;00m\n\u001b[0;32m-> 2270\u001b[0m res \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mall\u001b[39m(\u001b[43misclose\u001b[49m\u001b[43m(\u001b[49m\u001b[43ma\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mb\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mrtol\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mrtol\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43matol\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43matol\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mequal_nan\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mequal_nan\u001b[49m\u001b[43m)\u001b[49m)\n\u001b[1;32m 2271\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mbool\u001b[39m(res)\n", + "File \u001b[0;32m<__array_function__ internals>:200\u001b[0m, in \u001b[0;36misclose\u001b[0;34m(*args, **kwargs)\u001b[0m\n", + "File \u001b[0;32m~/git/gt4py/.venv/lib64/python3.10/site-packages/numpy/core/numeric.py:2377\u001b[0m, in \u001b[0;36misclose\u001b[0;34m(a, b, rtol, atol, equal_nan)\u001b[0m\n\u001b[1;32m 2374\u001b[0m dt \u001b[38;5;241m=\u001b[39m multiarray\u001b[38;5;241m.\u001b[39mresult_type(y, \u001b[38;5;241m1.\u001b[39m)\n\u001b[1;32m 2375\u001b[0m y \u001b[38;5;241m=\u001b[39m asanyarray(y, dtype\u001b[38;5;241m=\u001b[39mdt)\n\u001b[0;32m-> 2377\u001b[0m xfin \u001b[38;5;241m=\u001b[39m \u001b[43misfinite\u001b[49m\u001b[43m(\u001b[49m\u001b[43mx\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 2378\u001b[0m yfin \u001b[38;5;241m=\u001b[39m isfinite(y)\n\u001b[1;32m 2379\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mall\u001b[39m(xfin) \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;28mall\u001b[39m(yfin):\n", + "\u001b[0;31mTypeError\u001b[0m: ufunc 'isfinite' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''" + ] + } + ], "source": [ - "assert np.allclose(out_cartesian, out_next)" + "assert np.allclose(out_cartesian.asnumpy(), out_next.asnumpy())" ] } ], @@ -147,7 +190,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.2" + "version": "3.10.13" } }, "nbformat": 4, diff --git a/src/gt4py/next/__init__.py b/src/gt4py/next/__init__.py index cbd5735949..a81b61e63d 100644 --- a/src/gt4py/next/__init__.py +++ b/src/gt4py/next/__init__.py @@ -39,6 +39,11 @@ index_field, np_as_located_field, ) +from .program_processors.runners.gtfn import ( + run_gtfn_cached as gtfn_cpu, + run_gtfn_gpu_cached as gtfn_gpu, +) +from .program_processors.runners.roundtrip import backend as itir_embedded __all__ = [ @@ -74,5 +79,9 @@ "field_operator", "program", "scan_operator", + # from program_processor + "gtfn_cpu", + "gtfn_gpu", + "itir_embedded", *fbuiltins.__all__, ] diff --git a/src/gt4py/next/common.py b/src/gt4py/next/common.py index 29d606ccc0..cef2a3db94 100644 --- a/src/gt4py/next/common.py +++ b/src/gt4py/next/common.py @@ -574,22 +574,7 @@ def __call__(self, func: fbuiltins.BuiltInFunction[_R, _P], /) -> Callable[_P, _ ... -# TODO(havogt): replace this protocol with the new `GTFieldInterface` protocol -class NextGTDimsInterface(Protocol): - """ - Protocol for objects providing the `__gt_dims__` property, naming :class:`Field` dimensions. - - The dimension names are objects of type :class:`Dimension`, in contrast to - :mod:`gt4py.cartesian`, where the labels are `str` s with implied semantics, - see :class:`~gt4py._core.definitions.GTDimsInterface` . - """ - - @property - def __gt_dims__(self) -> tuple[Dimension, ...]: - ... - - -# TODO(egparedes): add support for this new protocol in the cartesian module +# TODO(havogt): we need to specify when we should use this interface vs the `Field` protocol. class GTFieldInterface(Protocol): """Protocol for object providing the `__gt_domain__` property, specifying the :class:`Domain` of a :class:`Field`.""" @@ -599,13 +584,23 @@ def __gt_domain__(self) -> Domain: @extended_runtime_checkable -class Field(NextGTDimsInterface, core_defs.GTOriginInterface, Protocol[DimsT, core_defs.ScalarT]): +class Field( + core_defs.GTDimsInterface, core_defs.GTOriginInterface, Protocol[DimsT, core_defs.ScalarT] +): __gt_builtin_func__: ClassVar[GTBuiltInFuncDispatcher] @property def domain(self) -> Domain: ... + @property + def __gt_domain__(self) -> Domain: + return self.domain + + @property + def __gt_dims__(self) -> tuple[str, ...]: + return tuple(d.value for d in self.domain.dims) + @property def codomain(self) -> type[core_defs.ScalarT] | Dimension: ... @@ -923,10 +918,6 @@ def asnumpy(self) -> Never: def domain(self) -> Domain: return Domain(dims=(self.dimension,), ranges=(UnitRange.infinite(),)) - @property - def __gt_dims__(self) -> tuple[Dimension, ...]: - return self.domain.dims - @property def __gt_origin__(self) -> Never: raise TypeError("'CartesianConnectivity' does not support this operation.") diff --git a/src/gt4py/next/embedded/nd_array_field.py b/src/gt4py/next/embedded/nd_array_field.py index 8bd2673db9..9fc1b42038 100644 --- a/src/gt4py/next/embedded/nd_array_field.py +++ b/src/gt4py/next/embedded/nd_array_field.py @@ -107,10 +107,6 @@ def domain(self) -> common.Domain: def shape(self) -> tuple[int, ...]: return self._ndarray.shape - @property - def __gt_dims__(self) -> tuple[common.Dimension, ...]: - return self._domain.dims - @property def __gt_origin__(self) -> tuple[int, ...]: assert common.Domain.is_finite(self._domain) diff --git a/src/gt4py/next/iterator/embedded.py b/src/gt4py/next/iterator/embedded.py index ef70a2e645..503836ef10 100644 --- a/src/gt4py/next/iterator/embedded.py +++ b/src/gt4py/next/iterator/embedded.py @@ -172,7 +172,7 @@ class LocatedField(Protocol): @property @abc.abstractmethod - def __gt_dims__(self) -> tuple[common.Dimension, ...]: + def __gt_domain__(self) -> common.Domain: ... # TODO(havogt): define generic Protocol to provide a concrete return type @@ -182,7 +182,7 @@ def field_getitem(self, indices: NamedFieldIndices) -> Any: @property def __gt_origin__(self) -> tuple[int, ...]: - return tuple([0] * len(self.__gt_dims__)) + return tuple([0] * len(self.__gt_domain__.dims)) @runtime_checkable @@ -680,7 +680,18 @@ def _get_axes( assert all(first == _get_axes(f) for f in field_or_tuple) return first else: - return field_or_tuple.__gt_dims__ + return field_or_tuple.__gt_domain__.dims + + +def _get_domain( + field_or_tuple: LocatedField | tuple, +) -> common.Domain: # arbitrary nesting of tuples of LocatedField + if isinstance(field_or_tuple, tuple): + first = _get_domain(field_or_tuple[0]) + assert all(first == _get_domain(f) for f in field_or_tuple) + return first + else: + return field_or_tuple.__gt_domain__ def _single_vertical_idx( @@ -894,14 +905,14 @@ class NDArrayLocatedFieldWrapper(MutableLocatedField): _ndarrayfield: common.Field @property - def __gt_dims__(self) -> tuple[common.Dimension, ...]: - return self._ndarrayfield.__gt_dims__ + def __gt_domain__(self) -> common.Domain: + return self._ndarrayfield.__gt_domain__ def _translate_named_indices( self, _named_indices: NamedFieldIndices ) -> common.AbsoluteIndexSequence: named_indices: Mapping[common.Dimension, FieldIndex | SparsePositionEntry] = { - d: _named_indices[d.value] for d in self._ndarrayfield.__gt_dims__ + d: _named_indices[d.value] for d in self._ndarrayfield.__gt_domain__.dims } domain_slice: list[common.NamedRange | common.NamedIndex] = [] for d, v in named_indices.items(): @@ -1046,8 +1057,8 @@ class IndexField(common.Field): _dimension: common.Dimension @property - def __gt_dims__(self) -> tuple[common.Dimension, ...]: - return (self._dimension,) + def __gt_domain__(self) -> common.Domain: + return self.domain @property def __gt_origin__(self) -> tuple[int, ...]: @@ -1165,8 +1176,8 @@ class ConstantField(common.Field[Any, core_defs.ScalarT]): _value: core_defs.ScalarT @property - def __gt_dims__(self) -> tuple[common.Dimension, ...]: - return tuple() + def __gt_domain__(self) -> common.Domain: + return self.domain @property def __gt_origin__(self) -> tuple[int, ...]: @@ -1452,7 +1463,7 @@ def _tuple_assign(field: tuple | MutableLocatedField, value: Any, named_indices: class TupleOfFields(TupleField): def __init__(self, data): self.data = data - self.__gt_dims__ = _get_axes(data) + self.__gt_domain__ = _get_domain(data) def field_getitem(self, named_indices: NamedFieldIndices) -> Any: return _build_tuple_result(self.data, named_indices) diff --git a/src/gt4py/next/iterator/tracing.py b/src/gt4py/next/iterator/tracing.py index 30fec1f9fd..05ebd02352 100644 --- a/src/gt4py/next/iterator/tracing.py +++ b/src/gt4py/next/iterator/tracing.py @@ -254,7 +254,7 @@ def _contains_tuple_dtype_field(arg): # other `np.int32`). We just ignore the error here and postpone fixing this to when # the new storages land (The implementation here works for LocatedFieldImpl). - return common.is_field(arg) and any(dim is None for dim in arg.__gt_dims__) + return common.is_field(arg) and any(dim is None for dim in arg.domain.dims) def _make_fencil_params(fun, args, *, use_arg_types: bool) -> list[Sym]: diff --git a/src/gt4py/next/type_system/type_translation.py b/src/gt4py/next/type_system/type_translation.py index 88a8347fe4..12649bf620 100644 --- a/src/gt4py/next/type_system/type_translation.py +++ b/src/gt4py/next/type_system/type_translation.py @@ -184,7 +184,7 @@ def from_value(value: Any) -> ts.TypeSpec: elif isinstance(value, common.Dimension): symbol_type = ts.DimensionType(dim=value) elif common.is_field(value): - dims = list(value.__gt_dims__) + dims = list(value.domain.dims) dtype = from_type_hint(value.dtype.scalar_type) symbol_type = ts.FieldType(dims=dims, dtype=dtype) elif isinstance(value, tuple): diff --git a/src/gt4py/storage/cartesian/utils.py b/src/gt4py/storage/cartesian/utils.py index 0f7cf5d0ab..bf4ebd20bf 100644 --- a/src/gt4py/storage/cartesian/utils.py +++ b/src/gt4py/storage/cartesian/utils.py @@ -192,6 +192,8 @@ def cpu_copy(array: Union[np.ndarray, "cp.ndarray"]) -> np.ndarray: def asarray( array: FieldLike, *, device: Literal["cpu", "gpu", None] = None ) -> np.ndarray | cp.ndarray: + if hasattr(array, "ndarray"): + array = array.ndarray if device == "gpu" or (not device and hasattr(array, "__cuda_array_interface__")): return cp.asarray(array) if device == "cpu" or ( From 4281e70f22d46ebc0d26d3b38710e5e12aac7e8c Mon Sep 17 00:00:00 2001 From: Hannes Vogt Date: Wed, 20 Dec 2023 09:54:14 +0100 Subject: [PATCH 3/7] add note about dimension names --- examples/lap_cartesian_vs_next.ipynb | 76 +++++++++++++--------------- 1 file changed, 35 insertions(+), 41 deletions(-) diff --git a/examples/lap_cartesian_vs_next.ipynb b/examples/lap_cartesian_vs_next.ipynb index 495a6e3bbf..9bf695d41d 100644 --- a/examples/lap_cartesian_vs_next.ipynb +++ b/examples/lap_cartesian_vs_next.ipynb @@ -37,7 +37,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ @@ -59,28 +59,15 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 7, "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - "\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "import gt4py.next as gtx\n", "\n", "allocator = gtx.itir_embedded # should match the executor\n", "\n", + "# Note: for gt4py.next, names don't matter, for gt4py.cartesian they have to be \"I\", \"J\", \"K\"\n", "I = gtx.Dimension(\"I\")\n", "J = gtx.Dimension(\"J\")\n", "K = gtx.Dimension(\"K\")\n", @@ -103,14 +90,25 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 8, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/vogtha/git/gt4py/src/gt4py/cartesian/stencil_object.py:420: UserWarning: The layout of the field 'inp' is not recommended for this backend.This may lead to performance degradation. Please consider using theprovided allocators in `gt4py.storage`.\n", + " warnings.warn(\n", + "/home/vogtha/git/gt4py/src/gt4py/cartesian/stencil_object.py:420: UserWarning: The layout of the field 'out' is not recommended for this backend.This may lead to performance degradation. Please consider using theprovided allocators in `gt4py.storage`.\n", + " warnings.warn(\n" + ] + } + ], "source": [ "import gt4py.cartesian.gtscript as gtscript\n", "\n", "cartesian_backend = \"numpy\"\n", - "# cartesian_backend = \"gt:cpu_ifirst\"\n", + "cartesian_backend = \"gt:cpu_ifirst\"\n", "\n", "@gtscript.stencil(backend=cartesian_backend)\n", "def lap_cartesian(\n", @@ -125,14 +123,26 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 9, "metadata": {}, - "outputs": [], + "outputs": [ + { + "ename": "AttributeError", + "evalue": "module 'gt4py.next' has no attribute 'cpu_backend'", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[9], line 4\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mgt4py\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mnext\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m Field\n\u001b[1;32m 3\u001b[0m backend \u001b[38;5;241m=\u001b[39m gtx\u001b[38;5;241m.\u001b[39mitir_embedded\n\u001b[0;32m----> 4\u001b[0m backend \u001b[38;5;241m=\u001b[39m \u001b[43mgtx\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcpu_backend\u001b[49m\n\u001b[1;32m 6\u001b[0m Ioff \u001b[38;5;241m=\u001b[39m gtx\u001b[38;5;241m.\u001b[39mFieldOffset(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mI\u001b[39m\u001b[38;5;124m\"\u001b[39m, source\u001b[38;5;241m=\u001b[39mI, target\u001b[38;5;241m=\u001b[39m(I,))\n\u001b[1;32m 7\u001b[0m Joff \u001b[38;5;241m=\u001b[39m gtx\u001b[38;5;241m.\u001b[39mFieldOffset(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mJ\u001b[39m\u001b[38;5;124m\"\u001b[39m, source\u001b[38;5;241m=\u001b[39mJ, target\u001b[38;5;241m=\u001b[39m(J,))\n", + "\u001b[0;31mAttributeError\u001b[0m: module 'gt4py.next' has no attribute 'cpu_backend'" + ] + } + ], "source": [ "from gt4py.next import Field\n", "\n", "backend = gtx.itir_embedded\n", - "# backend = cpu_backend\n", + "backend = gtx.gtfn_cpu\n", "\n", "Ioff = gtx.FieldOffset(\"I\", source=I, target=(I,))\n", "Joff = gtx.FieldOffset(\"J\", source=J, target=(J,))\n", @@ -150,25 +160,9 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "ename": "TypeError", - "evalue": "ufunc 'isfinite' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[5], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[38;5;28;01massert\u001b[39;00m \u001b[43mnp\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mallclose\u001b[49m\u001b[43m(\u001b[49m\u001b[43mout_cartesian\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mout_next\u001b[49m\u001b[43m)\u001b[49m\n", - "File \u001b[0;32m<__array_function__ internals>:200\u001b[0m, in \u001b[0;36mallclose\u001b[0;34m(*args, **kwargs)\u001b[0m\n", - "File \u001b[0;32m~/git/gt4py/.venv/lib64/python3.10/site-packages/numpy/core/numeric.py:2270\u001b[0m, in \u001b[0;36mallclose\u001b[0;34m(a, b, rtol, atol, equal_nan)\u001b[0m\n\u001b[1;32m 2199\u001b[0m \u001b[38;5;129m@array_function_dispatch\u001b[39m(_allclose_dispatcher)\n\u001b[1;32m 2200\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mallclose\u001b[39m(a, b, rtol\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m1.e-5\u001b[39m, atol\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m1.e-8\u001b[39m, equal_nan\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mFalse\u001b[39;00m):\n\u001b[1;32m 2201\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[1;32m 2202\u001b[0m \u001b[38;5;124;03m Returns True if two arrays are element-wise equal within a tolerance.\u001b[39;00m\n\u001b[1;32m 2203\u001b[0m \n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 2268\u001b[0m \n\u001b[1;32m 2269\u001b[0m \u001b[38;5;124;03m \"\"\"\u001b[39;00m\n\u001b[0;32m-> 2270\u001b[0m res \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mall\u001b[39m(\u001b[43misclose\u001b[49m\u001b[43m(\u001b[49m\u001b[43ma\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mb\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mrtol\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mrtol\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43matol\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43matol\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mequal_nan\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mequal_nan\u001b[49m\u001b[43m)\u001b[49m)\n\u001b[1;32m 2271\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mbool\u001b[39m(res)\n", - "File \u001b[0;32m<__array_function__ internals>:200\u001b[0m, in \u001b[0;36misclose\u001b[0;34m(*args, **kwargs)\u001b[0m\n", - "File \u001b[0;32m~/git/gt4py/.venv/lib64/python3.10/site-packages/numpy/core/numeric.py:2377\u001b[0m, in \u001b[0;36misclose\u001b[0;34m(a, b, rtol, atol, equal_nan)\u001b[0m\n\u001b[1;32m 2374\u001b[0m dt \u001b[38;5;241m=\u001b[39m multiarray\u001b[38;5;241m.\u001b[39mresult_type(y, \u001b[38;5;241m1.\u001b[39m)\n\u001b[1;32m 2375\u001b[0m y \u001b[38;5;241m=\u001b[39m asanyarray(y, dtype\u001b[38;5;241m=\u001b[39mdt)\n\u001b[0;32m-> 2377\u001b[0m xfin \u001b[38;5;241m=\u001b[39m \u001b[43misfinite\u001b[49m\u001b[43m(\u001b[49m\u001b[43mx\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 2378\u001b[0m yfin \u001b[38;5;241m=\u001b[39m isfinite(y)\n\u001b[1;32m 2379\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mall\u001b[39m(xfin) \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;28mall\u001b[39m(yfin):\n", - "\u001b[0;31mTypeError\u001b[0m: ufunc 'isfinite' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''" - ] - } - ], + "outputs": [], "source": [ "assert np.allclose(out_cartesian.asnumpy(), out_next.asnumpy())" ] From c670872130ca738bdfee1518455e3a049679140b Mon Sep 17 00:00:00 2001 From: Hannes Vogt Date: Mon, 15 Jan 2024 10:04:44 +0100 Subject: [PATCH 4/7] cleanup --- examples/lap_cartesian_vs_next.ipynb | 60 ++++++++++++++++------------ src/gt4py/next/common.py | 24 +++++++---- src/gt4py/storage/cartesian/utils.py | 2 + 3 files changed, 52 insertions(+), 34 deletions(-) diff --git a/examples/lap_cartesian_vs_next.ipynb b/examples/lap_cartesian_vs_next.ipynb index 9bf695d41d..7da35c16a9 100644 --- a/examples/lap_cartesian_vs_next.ipynb +++ b/examples/lap_cartesian_vs_next.ipynb @@ -24,7 +24,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Comparison gt4py.cartesian vs. gt4py.next" + "# Demonstrates gt4py.cartesian with gt4py.next compatibility" ] }, { @@ -37,7 +37,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ @@ -54,23 +54,41 @@ "metadata": {}, "source": [ "Storages\n", - "--" + "--\n", + "\n", + "We create fields using the gt4py.next constructors. These fields are compatible with gt4py.cartesian when we use \"I\", \"J\", \"K\" as the dimension names." ] }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 2, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "import gt4py.next as gtx\n", "\n", "allocator = gtx.itir_embedded # should match the executor\n", + "# allocator = gtx.gtfn_cpu\n", + "# allocator = gtx.gtfn_gpu\n", "\n", "# Note: for gt4py.next, names don't matter, for gt4py.cartesian they have to be \"I\", \"J\", \"K\"\n", "I = gtx.Dimension(\"I\")\n", "J = gtx.Dimension(\"J\")\n", - "K = gtx.Dimension(\"K\")\n", + "K = gtx.Dimension(\"K\", kind=gtx.DimensionKind.VERTICAL)\n", "\n", "domain = gtx.domain({I: nx, J: ny, K: nz})\n", "\n", @@ -90,7 +108,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 3, "metadata": {}, "outputs": [ { @@ -108,7 +126,8 @@ "import gt4py.cartesian.gtscript as gtscript\n", "\n", "cartesian_backend = \"numpy\"\n", - "cartesian_backend = \"gt:cpu_ifirst\"\n", + "# cartesian_backend = \"gt:cpu_ifirst\"\n", + "# cartesian_backend = \"gt:gpu\"\n", "\n", "@gtscript.stencil(backend=cartesian_backend)\n", "def lap_cartesian(\n", @@ -123,26 +142,15 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 4, "metadata": {}, - "outputs": [ - { - "ename": "AttributeError", - "evalue": "module 'gt4py.next' has no attribute 'cpu_backend'", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[9], line 4\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mgt4py\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mnext\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m Field\n\u001b[1;32m 3\u001b[0m backend \u001b[38;5;241m=\u001b[39m gtx\u001b[38;5;241m.\u001b[39mitir_embedded\n\u001b[0;32m----> 4\u001b[0m backend \u001b[38;5;241m=\u001b[39m \u001b[43mgtx\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcpu_backend\u001b[49m\n\u001b[1;32m 6\u001b[0m Ioff \u001b[38;5;241m=\u001b[39m gtx\u001b[38;5;241m.\u001b[39mFieldOffset(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mI\u001b[39m\u001b[38;5;124m\"\u001b[39m, source\u001b[38;5;241m=\u001b[39mI, target\u001b[38;5;241m=\u001b[39m(I,))\n\u001b[1;32m 7\u001b[0m Joff \u001b[38;5;241m=\u001b[39m gtx\u001b[38;5;241m.\u001b[39mFieldOffset(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mJ\u001b[39m\u001b[38;5;124m\"\u001b[39m, source\u001b[38;5;241m=\u001b[39mJ, target\u001b[38;5;241m=\u001b[39m(J,))\n", - "\u001b[0;31mAttributeError\u001b[0m: module 'gt4py.next' has no attribute 'cpu_backend'" - ] - } - ], + "outputs": [], "source": [ "from gt4py.next import Field\n", "\n", - "backend = gtx.itir_embedded\n", - "backend = gtx.gtfn_cpu\n", + "next_backend = gtx.itir_embedded\n", + "# next_backend = gtx.gtfn_cpu\n", + "# next_backend = gtx.gtfn_gpu\n", "\n", "Ioff = gtx.FieldOffset(\"I\", source=I, target=(I,))\n", "Joff = gtx.FieldOffset(\"J\", source=J, target=(J,))\n", @@ -151,7 +159,7 @@ "def lap_next(inp: Field[[I, J, K], dtype]) -> Field[[I, J, K], dtype]:\n", " return -4.0 * inp + inp(Ioff[-1]) + inp(Ioff[1]) + inp(Joff[-1]) + inp(Joff[1])\n", "\n", - "@gtx.program(backend=backend)\n", + "@gtx.program(backend=next_backend)\n", "def lap_next_program(inp: Field[[I, J, K], dtype], out: Field[[I, J, K], dtype]):\n", " lap_next(inp, out=out[1:-1, 1:-1, :])\n", "\n", @@ -160,7 +168,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ diff --git a/src/gt4py/next/common.py b/src/gt4py/next/common.py index cef2a3db94..a053e6f808 100644 --- a/src/gt4py/next/common.py +++ b/src/gt4py/next/common.py @@ -574,18 +574,30 @@ def __call__(self, func: fbuiltins.BuiltInFunction[_R, _P], /) -> Callable[_P, _ ... -# TODO(havogt): we need to specify when we should use this interface vs the `Field` protocol. -class GTFieldInterface(Protocol): - """Protocol for object providing the `__gt_domain__` property, specifying the :class:`Domain` of a :class:`Field`.""" +# TODO(havogt): we need to describe when this interface shouold be used instead of the `Field` protocol. +class GTFieldInterface(core_defs.GTDimsInterface, core_defs.GTOriginInterface, Protocol): + """ + Protocol for object providing the `__gt_domain__` property, specifying the :class:`Domain` of a :class:`Field`. + + Note: + - A default impolementation of the `__gt_dims__` interface from `gt4py.cartesian` is provided. + - No implementation of `__gt_origin__` is provided because of infinite fields. + """ @property def __gt_domain__(self) -> Domain: + # TODO probably should be changed to `DomainLike` (with a new concept `DimensionLike`) + # to allow implementations without having to import gtx.Domain. ... + @property + def __gt_dims__(self) -> tuple[str, ...]: + return tuple(d.value for d in self.__gt_domain__.dims) + @extended_runtime_checkable class Field( - core_defs.GTDimsInterface, core_defs.GTOriginInterface, Protocol[DimsT, core_defs.ScalarT] + GTFieldInterface, Protocol[DimsT, core_defs.ScalarT] ): __gt_builtin_func__: ClassVar[GTBuiltInFuncDispatcher] @@ -597,10 +609,6 @@ def domain(self) -> Domain: def __gt_domain__(self) -> Domain: return self.domain - @property - def __gt_dims__(self) -> tuple[str, ...]: - return tuple(d.value for d in self.domain.dims) - @property def codomain(self) -> type[core_defs.ScalarT] | Dimension: ... diff --git a/src/gt4py/storage/cartesian/utils.py b/src/gt4py/storage/cartesian/utils.py index bf4ebd20bf..4e7ebb0c21 100644 --- a/src/gt4py/storage/cartesian/utils.py +++ b/src/gt4py/storage/cartesian/utils.py @@ -193,6 +193,8 @@ def asarray( array: FieldLike, *, device: Literal["cpu", "gpu", None] = None ) -> np.ndarray | cp.ndarray: if hasattr(array, "ndarray"): + # extract the buffer from a gt4py.next.Field + # TODO(havogt): probably `Field` should provide the array interface methods when applicable array = array.ndarray if device == "gpu" or (not device and hasattr(array, "__cuda_array_interface__")): return cp.asarray(array) From 90ac591e6bb9be65957f2c3ba2edcaf8f339fb78 Mon Sep 17 00:00:00 2001 From: Hannes Vogt Date: Mon, 15 Jan 2024 10:44:00 +0100 Subject: [PATCH 5/7] cleanup --- examples/lap_cartesian_vs_next.ipynb | 13 +------------ src/gt4py/next/common.py | 4 +--- 2 files changed, 2 insertions(+), 15 deletions(-) diff --git a/examples/lap_cartesian_vs_next.ipynb b/examples/lap_cartesian_vs_next.ipynb index 7da35c16a9..cb80122570 100644 --- a/examples/lap_cartesian_vs_next.ipynb +++ b/examples/lap_cartesian_vs_next.ipynb @@ -110,18 +110,7 @@ "cell_type": "code", "execution_count": 3, "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/home/vogtha/git/gt4py/src/gt4py/cartesian/stencil_object.py:420: UserWarning: The layout of the field 'inp' is not recommended for this backend.This may lead to performance degradation. Please consider using theprovided allocators in `gt4py.storage`.\n", - " warnings.warn(\n", - "/home/vogtha/git/gt4py/src/gt4py/cartesian/stencil_object.py:420: UserWarning: The layout of the field 'out' is not recommended for this backend.This may lead to performance degradation. Please consider using theprovided allocators in `gt4py.storage`.\n", - " warnings.warn(\n" - ] - } - ], + "outputs": [], "source": [ "import gt4py.cartesian.gtscript as gtscript\n", "\n", diff --git a/src/gt4py/next/common.py b/src/gt4py/next/common.py index a053e6f808..10c3e08321 100644 --- a/src/gt4py/next/common.py +++ b/src/gt4py/next/common.py @@ -596,9 +596,7 @@ def __gt_dims__(self) -> tuple[str, ...]: @extended_runtime_checkable -class Field( - GTFieldInterface, Protocol[DimsT, core_defs.ScalarT] -): +class Field(GTFieldInterface, Protocol[DimsT, core_defs.ScalarT]): __gt_builtin_func__: ClassVar[GTBuiltInFuncDispatcher] @property From 78610d694e3c0bb8270edb71df84d75883e933a4 Mon Sep 17 00:00:00 2001 From: Hannes Vogt Date: Mon, 15 Jan 2024 10:52:10 +0100 Subject: [PATCH 6/7] Update src/gt4py/next/common.py --- src/gt4py/next/common.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gt4py/next/common.py b/src/gt4py/next/common.py index 10c3e08321..1a4f573712 100644 --- a/src/gt4py/next/common.py +++ b/src/gt4py/next/common.py @@ -580,7 +580,7 @@ class GTFieldInterface(core_defs.GTDimsInterface, core_defs.GTOriginInterface, P Protocol for object providing the `__gt_domain__` property, specifying the :class:`Domain` of a :class:`Field`. Note: - - A default impolementation of the `__gt_dims__` interface from `gt4py.cartesian` is provided. + - A default implementation of the `__gt_dims__` interface from `gt4py.cartesian` is provided. - No implementation of `__gt_origin__` is provided because of infinite fields. """ From 3e3f288e96765e0d62882a8fd3a6a5dbf61794df Mon Sep 17 00:00:00 2001 From: Hannes Vogt Date: Thu, 18 Jan 2024 09:51:43 +0000 Subject: [PATCH 7/7] address review comments --- src/gt4py/next/__init__.py | 4 ++-- src/gt4py/next/common.py | 2 +- src/gt4py/next/iterator/embedded.py | 7 +------ 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/gt4py/next/__init__.py b/src/gt4py/next/__init__.py index a81b61e63d..1398af5f03 100644 --- a/src/gt4py/next/__init__.py +++ b/src/gt4py/next/__init__.py @@ -43,7 +43,7 @@ run_gtfn_cached as gtfn_cpu, run_gtfn_gpu_cached as gtfn_gpu, ) -from .program_processors.runners.roundtrip import backend as itir_embedded +from .program_processors.runners.roundtrip import backend as itir_python __all__ = [ @@ -82,6 +82,6 @@ # from program_processor "gtfn_cpu", "gtfn_gpu", - "itir_embedded", + "itir_python", *fbuiltins.__all__, ] diff --git a/src/gt4py/next/common.py b/src/gt4py/next/common.py index 1a4f573712..6bf6858369 100644 --- a/src/gt4py/next/common.py +++ b/src/gt4py/next/common.py @@ -574,7 +574,7 @@ def __call__(self, func: fbuiltins.BuiltInFunction[_R, _P], /) -> Callable[_P, _ ... -# TODO(havogt): we need to describe when this interface shouold be used instead of the `Field` protocol. +# TODO(havogt): we need to describe when this interface should be used instead of the `Field` protocol. class GTFieldInterface(core_defs.GTDimsInterface, core_defs.GTOriginInterface, Protocol): """ Protocol for object providing the `__gt_domain__` property, specifying the :class:`Domain` of a :class:`Field`. diff --git a/src/gt4py/next/iterator/embedded.py b/src/gt4py/next/iterator/embedded.py index 503836ef10..390bec4312 100644 --- a/src/gt4py/next/iterator/embedded.py +++ b/src/gt4py/next/iterator/embedded.py @@ -675,12 +675,7 @@ def _is_concrete_position(pos: Position) -> TypeGuard[ConcretePosition]: def _get_axes( field_or_tuple: LocatedField | tuple, ) -> Sequence[common.Dimension]: # arbitrary nesting of tuples of LocatedField - if isinstance(field_or_tuple, tuple): - first = _get_axes(field_or_tuple[0]) - assert all(first == _get_axes(f) for f in field_or_tuple) - return first - else: - return field_or_tuple.__gt_domain__.dims + return _get_domain(field_or_tuple).dims def _get_domain(