AsyncDepGraph.cpp

// AsyncDepGraph.cpp
//
// Author David Barrett-Lennard
// (C)opyright Cedanet Pty Ltd 2018

@import "Ceda/cxObject/DGAsyncNode.h"
@import "ExampleUtils.h"
@import "Ceda/cxObject/Memory.h"
#include "Ceda/cxUtils/HPTime.h"
#include <cmath>

// std::optional doesn't seem to be available in the Android NDK r19
@if (!CEDA_IS_ANDROID_PLATFORM)
{

namespace AsyncIndepExample
{
    $struct X isa ceda::IObject
    {
        $cache-^ <<async>> std::optional<int> f0() const
        {
            Tracer() << "[Calculating f0()]\n";
            double sum = 0.0;
            for (int i=0 ; i < 10000000 ; ++i)
                 sum += std::sin(i);
            return (int) (1000.0 * sum);
        }
        
        $cache-^ <<async>> std::optional<int> f1(int x) const
        { 
            Tracer() << "[Calculating f1(" << x << ")]\n";
            double sum = 0.0;
            for (int i=1000*x ; i < 10000000 ; ++i)
                 sum += std::sin(i);
            return (int) (10.0 * sum);
        }
    };

    void Run()
    {
        ceda::TraceGroup g("AsyncIndepExample");

        ceda::CSpaceCreator cspace;
        X* p;
        {
            ceda::CSpaceTxn txn;
            p = $new X();
        }

        while(1)
        {
            bool allFound = true;
            {
                ceda::CSpaceTxn txn;
                ceda::TracerX os;

                auto z = p->f0();
                os << ' ' << z;
                if (!z) allFound = false;

                for (int x=0 ; x < 10 ; ++x)
                {
                    auto y = p->f1(x);
                    os << ' ' << y;
                    if (!y) allFound = false;
                }
                os << '\n';
            }
            if (allFound) break;
            Sleep(1);
        }
    }
}

namespace AsyncFactorialExample
{
    $struct X isa ceda::IObject
    {
        $cache-^ <<async>> std::optional<int> factorial(int n) const
            with std::optional<int> prev = (n == 0) ? 1 : factorial(n-1);
        { 
            Tracer() << "[Calculating factorial(" << n << ")]\n";
            if (n == 0) return 1;
            if (prev) return n * prev.value();
            return std::nullopt;
        }
    };

    void Run()
    {
        ceda::TraceGroup g("AsyncIndepExample");

        ceda::CSpaceCreator cspace;

        X* p;
        {
            ceda::CSpaceTxn txn;
            p = $new X();
        }

        while(1)
        {
            {
                ceda::CSpaceTxn txn;
                auto f = p->factorial(10);
                Tracer() << "factorial(10) = " << f << '\n';
                if (f) break;
            }
            Sleep(1);
        }
    }
}


namespace AsyncCacheFunctionExample
{
    $struct X isa ceda::IObject :
        model
        {
            int x;
        }
    {
        $cache-^ <<async>> std::optional<int> f0() const : [metadata]
            with double i = x;
        { 
            return (int)(std::sqrt(i));
        }

        $cache-^ <<async>> std::optional<int> y(int a, int b) const : [metadata]
            //with double c { c = x+a; }
            with double c = 2*x+a;
        { 
            return a + b + (int)c;
        }

        $dep int z =
        {
            auto v = y(1,2);
            z = v ? v.value() : -1;
        };
    };

    void Run()
    {
        ceda::TraceGroup g("AsyncCacheFunctionExample");

        ceda::CSpaceCreator cspace;

        {
            X* obj;
            {
                ceda::CSpaceTxn txn;

                // Objects containing async $cache functions must be $new'd (or embedded in objects which are $new'd)
                obj = $new X();
                obj->x = 100;
            }

            Tracer() << "-------------------------------------------------------------------\n";
            for (int i=0 ; i < 1000 ; ++i)
            {
                if (i % 7 == 0) Sleep(1);
                ceda::CSpaceTxn txn;
                if (i % 100 == 0)
                {
                    Tracer() << "\n\nSetting x to " << i << '\n';
                    obj->x = i;
                }
                //Tracer() << "obj->y(1,2) = " << obj->y(1,2) << ' ';
                Tracer() << obj->z << ' ';
                //Tracer() << obj->f0() << ' ';
            }

            /*
            Tracer() << "-------------------------------------------------------------------\n";
            {
                ceda::CSpaceTxn txn;
                obj->EvictDgsNodes();
            }
            */
            Tracer() << "-------------------------------------------------------------------\n";
        }
    }
} // namespace AsyncCacheFunctionExample

} // !CEDA_IS_ANDROID_PLATFORM

namespace AsyncDepGraph
{
    void Run() 
    {
        @if (!CEDA_IS_ANDROID_PLATFORM)
        {
            AsyncIndepExample::Run();
            AsyncFactorialExample::Run();
            AsyncCacheFunctionExample::Run();
        }
    }
}