示例#1
0
    def test_subslice_shape_i(self):
        """Subslice shape reduced by one dimension (two remain)"""

        ND, S0, S1 = range(3)

        @function(x=self.DataSlice, i=Long, v=Slice(Long))
        def get_i(x, i, v):
            s = x[i]
            v[ND] = s.ndim
            v[S0] = s.shape[0]
            v[S1] = s.shape[1]

        m = module([get_i])
        v = (Long.c_type * 3)()

        # Shape and dimensions should not depend on indices.
        for i in range(5):
            m.get_i(self.data, i, v)
            self.assertEqual(v[ND], 2)
            self.assertEqual(v[S0], 2)
            self.assertEqual(v[S1], 3)
示例#2
0
    def test_reference_arg(self):
        """Slice is treated as reference type."""
        from nitrous.types import is_aggregate

        self.assertTrue(is_aggregate(Slice(Long)))
示例#3
0
import unittest

from nitrous.module import module
from nitrous.function import function
from nitrous.types import Double, Long, Structure
from nitrous.types.array import Slice, Any

Coord = Structure("Coord", ("x", Double), ("y", Double), ("z", Double))
Coords = Slice(Coord)


class StructureTests(unittest.TestCase):
    def test_repr(self):
        self.assertEqual(repr(Coord), "<Structure 'Coord', 3 fields>")

    def test_load_fields(self):
        import ctypes

        # Attribute load from subscript
        @function(Double, a=Coords, i=Long)
        def sum_1(a, i):
            return a[i].x + a[i].y + a[i].z

        # Subscript, reference assignment, then attribute load
        @function(Double, a=Coords, i=Long)
        def sum_2(a, i):
            ai = a[i]
            return ai.x + ai.y + ai.z

        m = module([sum_1, sum_2])
        a = (Coord.c_type * 2)((1, 2, 3), (4, 5, 6))
示例#4
0
import unittest

from nitrous.module import module
from nitrous.function import function
from nitrous.types import Float
from nitrous.types.array import Slice
from nitrous.exp.vector import Vector, load, store, get_element, set_element, fill

FloatP = Slice(Float, (4, ))
Float4 = Vector(Float, 4)

load4f = load(Float4)
store4f = store(Float4)

get4f = get_element(Float4)
set4f = set_element(Float4)

fill4f = fill(Float4)


@function(Float, a=Float, b=Float, c=Float, d=Float)
def hadd4(a, b, c, d):
    v = Float4()

    v = set4f(v, 0, a)
    v = set4f(v, 1, b)
    v = set4f(v, 2, c)
    v = set4f(v, 3, d)

    return get4f(v, 0) + get4f(v, 1) + get4f(v, 2) + get4f(v, 3)
示例#5
0
import unittest
import numpy as np

from nitrous.function import function
from nitrous.types import Double, Index
from nitrous.types.array import Array, FastSlice, Slice, Any

DoubleNx3 = Slice(Double, shape=(Any, 3))
DoubleN = Slice(Double)
DoubleNArray = FastSlice(Double)

Double3 = Array(Double, (3, ))

X, Y, Z = range(3)


@function(d=DoubleNx3, out=DoubleNArray, n=Index, m=Index)
def sum_1(d, out, n, m):

    for k in range(m):
        for i in range(n):
            for j in range(i + 1, n):
                out[X] += d[i, X] * d[j, X]
                out[Y] += d[i, Y] * d[j, Y]
                out[Z] += d[i, Z] * d[j, Z]


@function(d=DoubleNx3, out=DoubleN, n=Index, m=Index)
def sum_2(d, out, n, m):

    for k in range(m):
示例#6
0
    def test(self):
        """N-body benchmark adaptation from http://shootout.alioth.debian.org"""
        from nitrous.module import module
        from nitrous.function import function
        from nitrous.types import Long, Double
        from nitrous.types.array import Slice, Any
        from nitrous.lib.math import sqrt

        X, Y, Z = range(3)

        PI = 3.14159265358979323
        SOLAR_MASS = 4 * PI * PI
        DAYS_PER_YEAR = 365.24

        # In the following sequence
        # - Sun
        # - Jupiter
        # - Saturn
        # - Uranus
        # - Neptune

        DoubleNx3 = Slice(Double, shape=(Any, 3))
        DoubleN = Slice(Double)

        common_args = {
            "xyz": DoubleNx3,
            "vxyz": DoubleNx3,
            "mass": DoubleN,
            "n_bodies": Long
        }

        @function(vxyz=DoubleNx3, mass=DoubleN, n_bodies=Long)
        def offset_momentum(vxyz, mass, n_bodies):
            px = 0.0
            py = 0.0
            pz = 0.0

            for i in range(n_bodies):
                px -= vxyz[i, X] * mass[i]
                py -= vxyz[i, Y] * mass[i]
                pz -= vxyz[i, Z] * mass[i]

            vxyz[0, X] = px / SOLAR_MASS
            vxyz[0, Y] = py / SOLAR_MASS
            vxyz[0, Z] = pz / SOLAR_MASS

        @function(Double, **common_args)
        def energy(xyz, vxyz, mass, n_bodies):

            e = 0.0

            for i in range(n_bodies):
                vx = vxyz[i, X]
                vy = vxyz[i, Y]
                vz = vxyz[i, Z]

                e += 0.5 * mass[i] * (vx * vx + vy * vy + vz * vz)

                for j in range(i + 1, n_bodies):
                    dx = xyz[i, X] - xyz[j, X]
                    dy = xyz[i, Y] - xyz[j, Y]
                    dz = xyz[i, Z] - xyz[j, Z]

                    d2 = dx * dx + dy * dy + dz * dz
                    e -= mass[i] * mass[j] / sqrt(Double)(d2)

            return e

        @function(dt=Double, **common_args)
        def advance(xyz, vxyz, mass, n_bodies, dt):
            for i in range(n_bodies):
                for j in range(i + 1, n_bodies):
                    dx = xyz[i, X] - xyz[j, X]
                    dy = xyz[i, Y] - xyz[j, Y]
                    dz = xyz[i, Z] - xyz[j, Z]

                    d2 = dx * dx + dy * dy + dz * dz
                    mag = dt / (d2 * sqrt(Double)(d2))

                    vxyz[i, X] -= dx * mass[j] * mag
                    vxyz[i, Y] -= dy * mass[j] * mag
                    vxyz[i, Z] -= dz * mass[j] * mag

                    vxyz[j, X] += dx * mass[i] * mag
                    vxyz[j, Y] += dy * mass[i] * mag
                    vxyz[j, Z] += dz * mass[i] * mag

            for i in range(n_bodies):
                xyz[i, X] += dt * vxyz[i, X]
                xyz[i, Y] += dt * vxyz[i, Y]
                xyz[i, Z] += dt * vxyz[i, Z]

        @function(n_steps=Long, **common_args)
        def loop(xyz, vxyz, mass, n_bodies, n_steps):
            for i in range(n_steps):
                advance(xyz, vxyz, mass, n_bodies, 0.01)

        m = module([offset_momentum, energy, loop])

        xyz = np.genfromtxt("tests/data/nbody-position")
        vxyz = np.genfromtxt("tests/data/nbody-velocity") * DAYS_PER_YEAR
        mass = np.genfromtxt("tests/data/nbody-mass") * SOLAR_MASS

        m.offset_momentum(vxyz, mass, 5)

        # from time import time
        # t0 = time()

        e0 = m.energy(xyz, vxyz, mass, 5)
        self.assertAlmostEqual(e0, -0.169075164)
        # print " e=", e0, "Elapsed", time() - t0

        m.loop(xyz, vxyz, mass, 5, 50000000)

        e1 = m.energy(xyz, vxyz, mass, 5)
        self.assertAlmostEqual(e1, -0.169059907)