Skip to content
Snippets Groups Projects
Select Git revision
  • bd544df8c1b3e0916f26641896acfe4372dd3808
  • master default
  • trunk
  • RELEASE_6_5_DRIVEDB
  • RELEASE_6_6_DRIVEDB
  • RELEASE_7_0_DRIVEDB
  • RELEASE_7_2_DRIVEDB
  • RELEASE_7_3_DRIVEDB
  • RELEASE_6_0_DRIVEDB
  • RELEASE_6_1_DRIVEDB
  • RELEASE_6_2_DRIVEDB
  • RELEASE_6_3_DRIVEDB
  • RELEASE_6_4_DRIVEDB
  • tags/RELEASE_7_4
  • tags/RELEASE_7_3
  • RELEASE_5_41_DRIVEDB
  • RELEASE_5_42_DRIVEDB
  • RELEASE_5_43_DRIVEDB
  • tags/RELEASE_7_2
  • tags/RELEASE_7_1
  • tags/RELEASE_7_0
  • RELEASE_5_40_DRIVEDB
22 results

smartd.cpp

Blame
  • reduce_main.cpp 4.61 KiB
    // This file is part of BOINC.
    // http://boinc.berkeley.edu
    // Copyright (C) 2008 University of California
    //
    // BOINC is free software; you can redistribute it and/or modify it
    // under the terms of the GNU Lesser General Public License
    // as published by the Free Software Foundation,
    // either version 3 of the License, or (at your option) any later version.
    //
    // BOINC is distributed in the hope that it will be useful,
    // but WITHOUT ANY WARRANTY; without even the implied warranty of
    // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    // See the GNU Lesser General Public License for more details.
    //
    // You should have received a copy of the GNU Lesser General Public License
    // along with BOINC.  If not, see <http://www.gnu.org/licenses/>.
    
    #if defined(_WIN32) && !defined(__STDWX_H__) && !defined(_BOINC_WIN_) && !defined(_AFX_STDAFX_H_)
    #include "boinc_win.h"
    #else
    #include "config.h"
    #endif
    
    
    #ifndef _WIN32
    #include <cstring>
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <assert.h>
    #include <algorithm>
    #endif
    
    #include "reduce.h"
    
    // Prepare to receive a source array.
    // (sx, sy) are dimensions of source array
    //
    void REDUCED_ARRAY_GEN::init_data(int sx, int sy) {
        sdimx = sx;
        sdimy = sy;
        rdimx = sx;
        rdimy = sy;
        if (rdimx > 256) rdimx = 256;
        if (rdimy > 128) rdimy = 128;
        while (rdimx*rdimy > MAX_DATA) {
            if (rdimx>1) rdimx /= 2;
            if (rdimy>1) rdimy /= 2;
        }
        nvalid_rows = 0;
        scury = 0;
        last_ry = 0;
        last_ry_count = 0;
        rdata_max = 0;
        rdata_min = (float)1e20;
    }
    
    bool REDUCED_ARRAY_GEN::full() {
        return nvalid_rows==rdimy;
    }
    
    #if 0
    void REDUCED_ARRAY_GEN::reset() {
        nvalid_rows = 0;
        ndrawn_rows = 0;
        scury = 0;
        last_ry = 0;
        last_ry_count = 0;
    }
    #endif
    
    
    // reduce a single row.  This is called only if sdimx > rdimx;
    //
    void REDUCED_ARRAY_GEN::reduce_source_row(float* in, float* out) {
        int i, ri;
    
        memset(out, 0, rdimx*sizeof(float));
        memset(itemp, 0, rdimx*sizeof(int));
        for (i=0; i<sdimx; i++) {
            ri = (i*rdimx)/sdimx;
            switch (reduce_method) {
            case REDUCE_METHOD_AVG:
                out[ri] += in[i];
                itemp[ri]++;
                break;
            case REDUCE_METHOD_SUM:
                out[ri] += in[i];
                break;
            case REDUCE_METHOD_MIN:
                out[ri] = std::min(out[ri], in[i]);
                break;
            case REDUCE_METHOD_MAX:
                out[ri] = std::max(out[ri], in[i]);
                break;
            }
        }
        if (reduce_method==REDUCE_METHOD_AVG) {
            for (i=0; i<rdimx; i++) {
                if (itemp[i] > 1) out[i] /= itemp[i];
            }
        }
    }
    
    void REDUCED_ARRAY_GEN::update_max(int row) {
        int i;
        float* p = rrow(row);
    
        for (i=0; i<rdimx; i++) {
            if (p[i] > rdata_max) rdata_max = p[i];
            if (p[i] < rdata_min) rdata_min = p[i];
        }
    }
    
    // Add a row of data from the source array
    //
    void REDUCED_ARRAY_GEN::add_source_row(float* in) {
        float* p;
        int i, ry;
    
        if (scury >= sdimy) {
            // printf("too many calls to add_source_row()!\n");
            // Crashing is not an appropriate response in release code.
            assert(scury<sdimy);
            return;
        }
        if (rdimy == sdimy) {
            ry = scury;
            if (rdimx == sdimx) {
                memcpy(rrow(ry), in, rdimx*sizeof(float));
            } else {
                reduce_source_row(in, rrow(ry));
            }
            update_max(ry);
            nvalid_rows++;
        } else {
            ry = (scury*rdimy)/sdimy;
            if (scury == 0) memset(rrow(0), 0, rdimx*sizeof(float));
    
            // if we've moved into a new row, finish up the previous one
            //
            if (ry > last_ry) {
                p = rrow(last_ry);
                if (last_ry_count > 1) {
                    for (i=0; i<rdimx; i++) {
                        p[i] /= last_ry_count;
                    }
                }
                update_max(last_ry);
                nvalid_rows++;
                last_ry = ry;
                last_ry_count = 0;
                memset(rrow(ry), 0, rdimx*sizeof(float));
            }
    
            last_ry_count++;
            p = rrow(ry);
            if (rdimx == sdimx) {
                for (i=0; i<sdimx; i++) {
                    p[i] += in[i];
                }
            } else {
                reduce_source_row(in, ftemp);
                for (i=0; i<rdimx; i++) {
                    p[i] += ftemp[i];
                }
            }
    
            // if this is last row, finish up
            //
            if (scury == sdimy-1) {
                p = rrow(last_ry);
                if (last_ry_count > 1) {
                    for (i=0; i<rdimx; i++) {
                        p[i] /= last_ry_count;
                    }
                }
                update_max(ry);
                nvalid_rows++;
            }
        }
        scury++;
    }