Strumenti Utente

Strumenti Sito

/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/* ***************************************************************************
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2 as 
 *  published by the Free Software Foundation.
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  GNU General Public License for more details.
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *  As a special exception, you may use this file as part of a free software
 *  library without restriction.  Specifically, if other files instantiate
 *  templates or use macros or inline functions from this file, or you compile
 *  this file and link it with other files to produce an executable, this
 *  file does not by itself cause the resulting executable to be covered by
 *  the GNU General Public License.  This exception does not however
 *  invalidate any other reasons why the executable file might be covered by
 *  the GNU General Public License.
 * NxN square matrix multiplication: C = A x B
 * Let's suppose B is memorized trasposed
 * Author: Massimo Torquati <>
#include <vector>
#include <iostream>
#include <cmath>
#include <ff/mdf.hpp>
using namespace ff;
// it initialises one single row of the matrix A
void initA(const size_t N, size_t i, double *A) {
    for(size_t j=0;j<N;++j) 
        A[j] = (i+j); 
// it initialises one single column (row) of the matrix B
void initB(const size_t N, size_t i, double *B) {
    for(size_t j=0;j<N;++j) 
        B[j] = i*j; 
// vector multiplication
void mm(const size_t N, double *Cij, const double *A, const double *B) {
    double C=0;
    for(size_t k=0;k<N;++k) {
        C += A[k]*B[k];
    *Cij = C;
void printarray(const double *A, const size_t N) {
    for (size_t i=0; i<N; i++) {
        for (size_t j=0; j<N; j++)
            printf("%g\t", A[i*N+j]);
// used to pass all parameters needed by the taskGen function
template<typename T>
struct Parameters {
    double *A,*B,*C;
    size_t N;
    T* mdf;
void taskGen(Parameters<ff_mdf > *const P){
    std::vector<param_info> Param;
    auto mdf = P->mdf;
    double *A = P->A;
    double *B = P->B;
    double *C = P->C;
    const size_t N = P->N;
    for(size_t i=0;i<N; ++i) {
        double *Ai         = &A[i*N];
        const param_info _1={(uintptr_t)Ai,OUTPUT};
        mdf->AddTask(Param, initA, N, i, Ai);
        double *Bi       = &B[i*N];
        const param_info _11={(uintptr_t)Bi,OUTPUT};
        mdf->AddTask(Param, initB, N, i, Bi);
    for(size_t i=0;i<N; ++i)
        for(size_t j=0;j<N;++j) {
            double *Cij       = &C[i*N+j];
            double *Ai        = &A[i*N];
            double *Bi        = &B[j*N];
            const param_info _1 ={(uintptr_t)Ai, INPUT};
            const param_info _2 ={(uintptr_t)Bi, INPUT};
            Param.push_back(_1); Param.push_back(_2); 
            mdf->AddTask(Param, mm, N, Cij, Ai, Bi);            
int main(int argc, char * argv[]) {
    if (argc<3) {
        std::cerr << "use: " << argv[0] << " nworkers size [check=0]\n";
        return -1;
    bool   check    = false;  
    int    nworkers =atoi(argv[1]);
    size_t N        =atol(argv[2]);
    if (argc==4)      check=true;  // checks result
    double *A = new double[N*N];
    double *B = new double[N*N];
    double *C = new double[N*N];
    assert(A && B && C);
    Parameters<ff_mdf > P;
    ff_mdf mm(taskGen, &P, 1024, nworkers);
    P.mdf = &mm;
    //printarray(A,N); printf("\n");
    //printarray(B,N); printf("\n");
    printarray(C,N);  printf("\n");
    // checking the result
    if (check) {
        double R=0;
        for(size_t i=0;i<N;++i)
            for(size_t j=0;j<N;++j) {
                for(size_t k=0;k<N;++k)
                    R += A[i*N+k]*B[j*N+k];
                if (abs(C[i*N+j]-R)>1e-06) {
                    std::cerr << "Wrong result\n";                    
                    return -1;
        std::cout << "OK\n";
    // to check for memory leaks
    //delete [] A; delete [] B; delete [] C;
    return 0;
magistraleinformaticanetworking/spm/sample_mmmdf14.txt · Ultima modifica: 16/12/2014 alle 10:21 (4 anni fa) da Massimo Torquati