Ejemplo n.º 1
0
 private void FillStartZeros(PackedSpace space)
 {
     for (var x = 0; x < spaceSize; x++)
     {
         space[x] = 0;
     }
 }
Ejemplo n.º 2
0
    public PackedSpace EmulateInPlace()
    {
        var packer = rule.packer;

        var prevPrevSpace = new PackedSpace(packer, spaceSize);

        fillStart(prevPrevSpace);

        var prevSpace = new PackedSpace(packer, spaceSize);

        fillStart(prevSpace);

        var space = new PackedSpace(packer, spaceSize);

        for (var t = 2; t < timeSize; t++)
        {
            rule.FillSpace(space, prevSpace, prevPrevSpace);
            fillBorder(space);

            var tmpSpace = prevPrevSpace;
            prevPrevSpace = prevSpace;
            prevSpace     = space;
            space         = prevPrevSpace;
        }

        return(space);
    }
Ejemplo n.º 3
0
    public IEnumerable <PackedSpace> Emulate()
    {
        var packer = rule.packer;

        var prevPrevSpace = new PackedSpace(packer, spaceSize);

        fillStart(prevPrevSpace);
        yield return(prevPrevSpace);

        var prevSpace = new PackedSpace(packer, spaceSize);

        fillStart(prevSpace);
        yield return(prevSpace);

        for (var t = 2; t < timeSize; t++)
        {
            var space = new PackedSpace(packer, spaceSize);
            rule.FillSpace(space, prevSpace, prevPrevSpace);
            fillBorder(space);
            yield return(space);

            prevPrevSpace = prevSpace;
            prevSpace     = space;
        }
    }
Ejemplo n.º 4
0
    private void FillStartRandom(PackedSpace space)
    {
        var stateCount = rule.stateCount;

        for (var x = 0; x < spaceSize; x++)
        {
            space[x] = random.Next(stateCount);
        }
    }
Ejemplo n.º 5
0
    public void FillBorderZeros(PackedSpace space)
    {
        var snr = Rule.spaceNeighbourhoodRadius;

        for (var x = 0; x < snr; x++)
        {
            space[x] = 0;
            space[spaceSize - snr + x] = 0;
        }
    }
Ejemplo n.º 6
0
    public void FillBorderRandom(PackedSpace space)
    {
        var snr        = Rule.spaceNeighbourhoodRadius;
        var stateCount = rule.stateCount;

        for (var x = 0; x < snr; x++)
        {
            space[x] = random.Next(stateCount);
            space[spaceSize - snr + x] = random.Next(stateCount);
        }
    }
Ejemplo n.º 7
0
    public void Emulate()
    {
        using (var measureTime = new MeasureTime()) {
            var random = useSeed ? new Random(seed) : new Random();

            var packer = new Packer(stateCount);
            var rule   = new Rule(packer, BigInteger.Parse(ruleCode), tablePackN);

            measureTime.Mark("After rule inst");
            if (spacetime == null || spacetime.Length != timeSize || spacetime[0].spaceSize != spaceSize)
            {
                spacetime = new PackedSpace[timeSize];
                for (var t = 0; t < spacetime.Length; t++)
                {
                    spacetime[t] = new PackedSpace(packer, spaceSize);
                }
            }
            var emulator = new Emulator(
                rule, timeSize, spaceSize, startFill, borderFill, random);

            measureTime.Mark("After raw spacetime creation");
            emulator.Emulate(spacetime);

            measureTime.Mark("After emulate itself");

            var material = GetComponent <Renderer>().material;

            material.SetInt("_TimeSize", timeSize);
            material.SetInt("_SpaceSize", spaceSize);

            var spaceSizePacked = spacetime[0].packedSize;
            var bufferSize      = timeSize * spaceSizePacked;
            if (buffer is null || buffer.count != bufferSize)
            {
                buffer?.Dispose();
                buffer = new ComputeBuffer(bufferSize, sizeof(UInt32));
            }
            for (var t = 0; t < spacetime.Length; t++)
            {
                buffer.SetData(spacetime[t].packed, 0, t * spaceSizePacked, spaceSizePacked);
            }
            material.SetBuffer("_SpacetimePacked", buffer);
            measureTime.Mark("After shader");
        }
    }
Ejemplo n.º 8
0
    public void Test()
    {
        if (shader is null || shader.shader != shaderRef)
        {
            shader?.DisposeBuffers();
            shader = new EmulateComputeShader(shaderRef);
        }
        using (var measureTime = new MeasureTime()) {
            // if (rules == null) {
            // UpdateRules();
            // measureTime.Mark("After UpdateRules");
            // }

            shader.Emulate(stateCount, spaceSize, timeSize, randSeed, rules, inPlace);


            measureTime.Mark("After Dispatch");

            var fs = new float[parallelRules];

            var packer          = rules[0].packer;
            var timeSize1       = inPlace ? 2 : timeSize;
            var packedSpaceSize = packer.GetPackedSize(spaceSize);
            var layerSize       = packedSpaceSize * timeSize1;
            for (var i = 0; i < parallelRules; i++)
            {
                var space = new PackedSpace(packer, spaceSize);
                shader.spacetimePackedBuffer.GetData(
                    space.packed,
                    0,
                    layerSize * i + packedSpaceSize * (timeSize1 - 1),
                    packedSpaceSize);
                fs[i] = RuleSpacetimeAnalyzer.RenderAnalyze(packer, spaceSize, space.Convolute(), patternLength);
            }

            measureTime.Mark("After Analyze");

            SetDisplays(rules.Select(rule => rule.code.ToString()).ToArray(), fs);

            measureTime.Mark("After SetDisplays");
        }
    }
Ejemplo n.º 9
0
    public void FillSpace(
        PackedSpace t0Space,
        PackedSpace tm1Space,
        PackedSpace tm2Space
        )
    {
        var cellSizeBits = packer.cellSizeBits;
        var cellsPerPack = packer.cellsPerPack;

        var ss = t0Space.spaceSize;
        var ps = t0Space.packedSize;

        var n      = tablePackN;
        var tableN = tablePackedNCell;

        var nCellShift   = n * cellSizeBits;
        var np2CellShift = (n + 2) * cellSizeBits;
        var np2CellMask  = (1 << np2CellShift) - 1;

        var indexSize          = n + n + 2;
        var combinedStateShift = indexSize * cellSizeBits;
        var combinedStateMask  = ~(-1 << combinedStateShift);

        int GetStateNCell(int _pcn, int _n1cnn2)
        {
            var combinedState =
                ((_pcn << np2CellShift) | (_n1cnn2 & np2CellMask))
                & combinedStateMask;

            return(tableN[combinedState]);
        }

        for (var px = 0; px < ps; px++)
        {
            var ptm1n1 = (px - 1 >= 0) ? tm1Space.packed[px - 1] : 0;
            var ptm1c  = tm1Space.packed[px];
            var ptm1n2 = (px + 1 < ps) ? tm1Space.packed[px + 1] : 0;
            var ptm2c  = tm2Space.packed[px];

            int pack = 0;

            var _ptm1c = packer.AppendToPack(ptm1n1, ptm1c, cellsPerPack - 1);

            for (var sx = 0; sx < cellsPerPack - 2; sx += n)
            {
                var shift = sx * cellSizeBits;
                var state = GetStateNCell(ptm2c >> shift, _ptm1c >> shift);
                pack |= state << shift;
            }

            _ptm1c = packer.AppendToPack(ptm1c, ptm1n2, 1);
            pack   = pack & ~(-1 << ((cellsPerPack - 2) * cellSizeBits));

            for (var sx = cellsPerPack - 2; sx < cellsPerPack; sx += n)
            {
                var shift = sx * cellSizeBits;
                var state = GetStateNCell(
                    ptm2c >> shift, _ptm1c >> (shift - 2 * cellSizeBits));
                pack |= state << shift;
            }

            t0Space.packed[px] = pack;
        }
    }
Ejemplo n.º 10
0
    public void Emulate(
        int stateCount,
        int spaceSize,
        int timeSize,
        int randSeed,
        Rule[] rules,
        bool inPlace
        )
    {
        Debug.Assert(rules[0].tablePackN == tablePackN);

        var packer          = rules[0].packer;
        var spaceSizePacked = packer.GetPackedSize(spaceSize);

        var timestepsPerCall = (timeSize - Rule.timeNeighbourhoodRadius);

        if (usePackedPacked)
        {
            var packedRule = new PackedSpace(
                new Packer(4 * 4),
                rules[0].tablePackedNCell.Length);
            ComputeShaderEx.EnsureBuffer(
                ref ruleTablePackedNCellBuffer,
                rules.Length * packedRule.packed.Length,
                sizeof(int));

            for (var i = 0; i < rules.Length; i++)
            {
                var rule = rules[i];
                for (var j = 0; j < rule.tablePackedNCell.Length; j++)
                {
                    packedRule[j] = rule.tablePackedNCell[j];
                }
                ruleTablePackedNCellBuffer.SetData(
                    packedRule.packed,
                    0,
                    i * packedRule.packed.Length,
                    packedRule.packed.Length);
            }
        }
        else
        {
            ComputeShaderEx.EnsureBuffer(
                ref ruleTablePackedNCellBuffer,
                rules.Length * rules[0].tablePackedNCell.Length,
                sizeof(int));

            for (var i = 0; i < rules.Length; i++)
            {
                var rule = rules[i];
                ruleTablePackedNCellBuffer.SetData(
                    rule.tablePackedNCell,
                    0,
                    i * rule.tablePackedNCell.Length,
                    rule.tablePackedNCell.Length);
            }
        }

        var spacetimePackedBufferSize =
            rules.Length * spaceSizePacked * (inPlace ? 2 : timeSize);

        ComputeShaderEx.EnsureBuffer(
            ref spacetimePackedBuffer, spacetimePackedBufferSize, sizeof(int));
        ComputeShaderEx.EnsureBuffer(
            ref flagBuffer, 1, sizeof(int));

        shader.Set("_RandSeed", randSeed);
        shader.Set("_SpaceSize", spaceSize);
        shader.Set("_TimeSize", inPlace ? 2 : timeSize);
        shader.Set("_TimeTo", timeSize);

        var fillStartRandomKernel = this.fillStartRandomKernel;

        fillStartRandomKernel.SetBuffer(
            "_SpacetimePacked", spacetimePackedBuffer);
        fillStartRandomKernel.Dispatch(spaceSizePacked, rules.Length);

        var emulateKernelName = "CSEmulate";
        var emulateKernel     =
            new ShaderKernel(shader, emulateKernelName);

        emulateKernel.Set(
            "_SpacetimePacked", spacetimePackedBuffer);
        emulateKernel.Set(
            "_Flag", flagBuffer);
        emulateKernel.Set(
            "_RuleTablePackedNCell", ruleTablePackedNCellBuffer);
        var tnr = Rule.timeNeighbourhoodRadius;

        for (var t = tnr; t < timeSize; t += timestepsPerCall)
        {
            shader.SetInt("_TimeStep", t);
            emulateKernel.Dispatch(
                spaceSizePacked,
                rules.Length);
        }

        var data = new int[1];

        flagBuffer.GetData(data);
    }
Ejemplo n.º 11
0
 public static float RenderAnalyze(PackedSpace space, int[] convolution, int size)
 => RenderAnalyze(space.packer, space.spaceSize, convolution, size);