Qpnc (Q parallel numerical computations)



  • I have been developing a high level library for parallel numerical computations that uses the signal and slot system provided by Qt. It's goal was to simplify the code one needs to write in order to make use of the power provided by multiprocessor systems. It is still in the need of a code clean up but I would really like to show You its current API.

    A part of the Conjugate Gradients method written using Qpnc.
    @
    void QpncConjugateGradients::buildOperationTree()
    {
    delete operation;

    QpncAbstractOperation<double>* qOperation =
            QpncOperationFactory<double>::produceOperation
    

    (QpncOperations::MULTIPLY,A,d,q);
    QpncAbstractOperation<double>* fakeD =
    QpncOperationFactory<double>::produceOperation
    (QpncOperations::FAKE,d,0,0,0);

    QpncAbstractOperation<double>* fakeDelta =
            QpncOperationFactory<double>::produceOperation
    

    (QpncOperations::FAKE,deltaNew,0,0,0);
    QpncAbstractOperation<double>* dq =
    QpncOperationFactory<double>::produceOperation
    (QpncOperations::COMPOSITE_DOT_PRODUCT,
    fakeD,qOperation);

    QpncAbstractOperation<double>* alphaOperation =
            QpncOperationFactory<double>::produceOperation
    

    (QpncOperations::COMPOSITE_SIGNLE_DIVIDE,fakeDelta,dq,alpha);
    QpncAbstractOperation<double>* fakeQ =
    QpncOperationFactory<double>::produceOperation
    (QpncOperations::FAKE,q,0,0,0);

    QpncAbstractOperation<double>* fakeR =
            QpncOperationFactory<double>::produceOperation
    

    (QpncOperations::FAKE,r,0,0,0);
    QpncAbstractOperation<double>* alphaQ =
    QpncOperationFactory<double>::produceOperation
    (QpncOperations::COMPOSITE_SINGLE_MULTIPLY,fakeQ,alphaOperation);

    QpncAbstractOperation<double>* fakeR2 =
            QpncOperationFactory<double>::produceOperation
    

    (QpncOperations::FAKE,r,0,0,0);
    QpncAbstractOperation<double>* rOperation =
    QpncOperationFactory<double>::produceOperation
    (QpncOperations::COMPOSITE_SUBSTRACT,fakeR,alphaQ,r);

    QpncAbstractOperation<double>* deltaNewOperation =
            QpncOperationFactory<double>::produceOperation
    

    (QpncOperations::COMPOSITE_DOT_PRODUCT,fakeR2,rOperation,deltaNew);
    QpncAbstractOperation<double>* fakeDeltaOld =
    QpncOperationFactory<double>::produceOperation
    (QpncOperations::FAKE,deltaOld,0,0,0);

    QpncAbstractOperation<double>* betaOperation =
            QpncOperationFactory<double>::produceOperation
    

    (QpncOperations::COMPOSITE_SIGNLE_DIVIDE,deltaNewOperation,
    fakeDeltaOld,beta);
    QpncAbstractOperation<double>* fakeD2 =
    QpncOperationFactory<double>::produceOperation
    (QpncOperations::FAKE,d,0,0,0);

    QpncAbstractOperation<double>* fakeR3 =
            QpncOperationFactory<double>::produceOperation
    

    (QpncOperations::FAKE,r,0,0,0);
    QpncAbstractOperation<double>* betaD =
    QpncOperationFactory<double>::produceOperation
    (QpncOperations::COMPOSITE_SINGLE_MULTIPLY,
    fakeD2,betaOperation);

    operation =
            QpncOperationFactory<double>::produceOperation
    

    (QpncOperations::COMPOSITE_ADD,fakeR3,betaD,dNew);

    connect(operation,SIGNAL(finished(int)),this,SLOT(calculateX(int)));
    
    operation->start();
    

    }
    @

    And the same written using POSIX
    @
    void* ThreadFunction(void* in)//rewrite
    {
    ThreadData* data = (ThreadData*)in;
    unsigned iteration = 0;
    unsigned pack = data->rowCount / data->threadCount;
    unsigned startIndex = data->threadNum * pack;
    unsigned endIndex = startIndex + pack;
    if(data->threadNum == data->threadCount - 1)
    endIndex = data->rowCount;
    for(unsigned i = startIndex; i < endIndex; ++i)
    {
    double AxValue = 0.0;
    for(unsigned j = 0; j < data->collumnCount; ++j)
    AxValue += data->A[i][j] * data->x[j][0];

        data->r[i][0] = data->b[i][0] - AxValue;
    }
    pthread_barrier_wait(data->barrier);
    for(unsigned i = startIndex; i < endIndex; ++i)
        data->d[i][0] = data->r[i][0];
    pthread_barrier_wait(data->barrier);
    double localDelta = 0.0;
    for(unsigned i = startIndex; i < endIndex; ++i)
        localDelta += data->r[i][0] * data->r[i][0];
    
    pthread_mutex_lock(data->mutex);
    *data->deltaNew += localDelta;
    pthread_mutex_unlock(data->mutex);
    pthread_barrier_wait(data->barrier);
    if(data->threadNum == 0)
    {
        *data->deltaOld = *data->deltaNew;
        *data->prec = (*data->eps * *data->eps) * *data->deltaOld;
    }
    pthread_barrier_wait(data->globalBarrier);
    while(iteration < data->iterations && *data->deltaNew > *data->prec)
    {
        for(unsigned i = startIndex; i < endIndex; ++i)
        {
            double AdValue = 0.0;
            for(unsigned j  = 0; j < data->collumnCount; ++j)
                AdValue += data->A[i][j] * data->d[j][0];
            data->q[i][0] = AdValue;
        }
        pthread_barrier_wait(data->barrier);
        double localValue = 0.0;
        for(unsigned i = startIndex; i < endIndex; ++i)
            localValue += data->d[i][0] * data->q[i][0];
        pthread_mutex_lock(data->mutex);
        *data->dq += localValue;
        pthread_mutex_unlock(data->mutex);
    

    //...
    ++iteration;
    }
    return NULL;
    }
    @

    When dealing with a task of calculating a system of linear equations composed of a matrix 15000x15000, Qpnc has an efficiency rate of 92%, witch compared to POSIX witch has an efficiency rate of 95% is not a bad result.



  • are you planned to release this soon???



  • As this is a part of my Master's Thesis, witch I'll be hopefully defending somewhere next month. I'm planning to release it by July.



  • Ok so I successfully defended my masters thesis, but couldn't find the time to make an API clean-up. I would like to know if there is someone interested in trying to use my work under an GPL or BSD-like licence. I would also by thankful if someone could point me to a place where I could publish it.



  • [quote author="kkrzewniak" date="1282920261"]I would like to know if there is someone interested in trying to use my work under an GPL or BSD-like licence.[/quote]

    Sometimes supply creates demand

    [quote author="kkrzewniak" date="1282920261"]I would also by thankful if someone could point me to a place where I could publish it.[/quote]

    gitorious.org
    github.org
    sourceforge.net




Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.