<commit_before>// Copyright Hugh Perkins 2014,2015 hughperkins at gmail
//
// This Source Code Form is subject to the terms of the Mozilla Public License,
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
// obtain one at http://mozilla.org/MPL/2.0/.

#include <algorithm>

#include "Propagate3.h"
#include "stringhelper.h"
#include "StatefulTimer.h"

using namespace std;

#undef VIRTUAL
#undef STATIC
#define VIRTUAL
#define STATIC

VIRTUAL Propagate3::~Propagate3() {
    delete kernel;
    delete repeatedAdd;
    delete activate;
}
VIRTUAL void Propagate3::propagate( int batchSize, CLWrapper *dataWrapper, CLWrapper *weightsWrapper, CLWrapper *biasWeightsWrapper,
    CLWrapper *resultsWrapper ) {
    StatefulTimer::timeCheck("Propagate3::propagate begin");
    const int maxWorkgroupSize = cl->getMaxWorkgroupSize();
    int maxglobalId = 0;

    kernel->in(batchSize);
    kernel->input( dataWrapper );
    kernel->input( weightsWrapper);
//    if( dim.biased ) kernel->input( biasWeightsWrapper );
    kernel->output( resultsWrapper );
//    cout << "square(dim.outputBoardSize) " << square( dim.outputBoardSize ) << endl;
    kernel->localFloats( square( dim.inputBoardSize ) );
    kernel->localFloats( square( dim.filterSize ) * dim.inputPlanes );

    int workgroupsize = std::max( 32, square( dim.outputBoardSize ) ); // no point in wasting threads....
    int numWorkgroups = dim.numFilters * batchSize;
    int globalSize = workgroupsize * numWorkgroups;
//    cout << "propagate3 numworkgroups " << numWorkgroups << " globalsize " << globalSize << " workgroupsize " << workgroupsize << endl;
    kernel->run_1d( globalSize, workgroupsize );
    cl->finish();
    StatefulTimer::timeCheck("Propagate3::propagate after kernel1");

//    {
//        resultsWrapper->copyToHost();
//        float const *results = reinterpret_cast< float const *>( resultsWrapper->getHostArray() );
//        for( int i = 0; i < min( 64, resultsWrapper->size() ); i++ ) {
//            cout << "results[" << i << "]=" << results[i] << endl;
//        }
//    }

    if( dim.biased ) {
        repeatedAdd->in( batchSize * dim.numFilters * dim.outputBoardSize * dim.outputBoardSize )
            ->in( dim.numFilters )
            ->in( dim.outputBoardSize * dim.outputBoardSize )
            ->inout( resultsWrapper )->in( biasWeightsWrapper );
        maxglobalId = batchSize * dim.numFilters * dim.outputBoardSize * dim.outputBoardSize;
        numWorkgroups = ( maxglobalId + maxWorkgroupSize - 1 ) / maxWorkgroupSize;
        repeatedAdd->run_1d( numWorkgroups * maxWorkgroupSize, maxWorkgroupSize );
        cl->finish();
        StatefulTimer::timeCheck("Propagate3::propagate after repeatedAdd");
    }

    activate->in( batchSize * dim.numFilters * dim.outputBoardSize * dim.outputBoardSize )
        ->inout( resultsWrapper );
    maxglobalId = batchSize * dim.numFilters * dim.outputBoardSize * dim.outputBoardSize;
    numWorkgroups = ( maxglobalId + maxWorkgroupSize - 1 ) / maxWorkgroupSize;
    activate->run_1d( numWorkgroups * maxWorkgroupSize, maxWorkgroupSize );
    cl->finish();
    StatefulTimer::timeCheck("Propagate3::propagate after activate");

    StatefulTimer::timeCheck("Propagate3::propagate after call propagate");
}
Propagate3::Propagate3( OpenCLHelper *cl, LayerDimensions dim, ActivationFunction const*fn ) :
        Propagate( cl, dim, fn )
            {

    if( square( dim.outputBoardSize ) > cl->getMaxWorkgroupSize() ) {
        throw runtime_error("cannot use propagate3, since outputboardsize * outputboardsize > maxworkgroupsize");
    }

    std::string options = "-D " + fn->getDefineName();
    options += dim.buildOptionsString();

    // [[[cog
    // import stringify
    // stringify.write_kernel3( "kernel", "cl/propagate3.cl", "propagate_3_by_n_outplane", 'options' )
    // stringify.write_kernel3( "repeatedAdd", "cl/per_element_add.cl", "repeated_add", 'options' )
    // stringify.write_kernel3( "activate", "cl/activate.cl", "activate", 'options' )
    // ]]]
    // generated using cog:
    const char * kernelSource =  R"DELIM(

    // Copyright Hugh Perkins 2014, 2015 hughperkins at gmail
    //
    // This Source Code Form is subject to the terms of the Mozilla Public License,
    // v. 2.0. If a copy of the MPL was not distributed with this file, You can
    // obtain one at http://mozilla.org/MPL/2.0/.

    // concept: each workgroup handles convolving one input example with one filtercube
    // and writing out one single output plane
    //
    // workgroup id organized like: [imageid][outplane]
    // local id organized like: [outrow][outcol]
    // each thread iterates over: [upstreamplane][filterrow][filtercol]
    // number workgroups = 32
    // one filter plane takes up 5 * 5 * 4 = 100 bytes
    // one filter cube (corresponding to one outplane) = 5*5 * 32 * 4 = 3.2KB (ok)
    // all filter cubes = 3.2KB * 32 = 102KB (too big)
    // results are organized like [imageid][filterid][row][col]
    void kernel propagate_3_by_n_outplane( const int batchSize,
          global const float *images, global const float *filters,
        global float *results,
        local float *_upstreamBoard, local float *_filterCube ) {
        const int globalId = get_global_id(0);

        const int workgroupId = get_group_id(0);
        const int workgroupSize = get_local_size(0);
        const int n = workgroupId / gNumFilters;
        const int outPlane = workgroupId % gNumFilters;

        const int localId = get_local_id(0);
        const int outputRow = localId / gOutputBoardSize;
        const int outputCol = localId % gOutputBoardSize;

        const int minu = gPadZeros ? max( -gHalfFilterSize, -outputRow ) : -gHalfFilterSize;
        const int maxu = gPadZeros ? min( gHalfFilterSize - gEven, gOutputBoardSize - 1 - outputRow  - gEven) : gHalfFilterSize - gEven;
        const int minv = gPadZeros ? max( -gHalfFilterSize, -outputCol ) : - gHalfFilterSize;
        const int maxv = gPadZeros ? min( gHalfFilterSize - gEven, gOutputBoardSize - 1 - outputCol - gEven) : gHalfFilterSize - gEven;

        const int numUpstreamsPerThread = ( gInputBoardSizeSquared + workgroupSize - 1 ) / workgroupSize;

        const int filterCubeLength = gInputPlanes * gFilterSizeSquared;
        const int filterCubeGlobalOffset = outPlane * filterCubeLength;
        const int numPixelsPerThread = ( filterCubeLength + workgroupSize - 1 ) / workgroupSize;
        for( int i = 0; i < numPixelsPerThread; i++ ) {
            int thisOffset = localId + i * workgroupSize;
            if( thisOffset < filterCubeLength ) {
                _filterCube[thisOffset] = filters[filterCubeGlobalOffset + thisOffset];
            }
        }
        // dont need a barrier, since we'll just run behind the barrier from the upstream board download

        float sum = 0;
        for( int upstreamPlane = 0; upstreamPlane < gInputPlanes; upstreamPlane++ ) {
            int thisUpstreamBoardOffset = ( n * gInputPlanes + upstreamPlane ) * gInputBoardSizeSquared;
            barrier(CLK_LOCAL_MEM_FENCE);
            for( int i = 0; i < numUpstreamsPerThread; i++ ) {
                int thisOffset = workgroupSize * i + localId;
                if( thisOffset < gInputBoardSizeSquared ) {
                    _upstreamBoard[ thisOffset ] = images[ thisUpstreamBoardOffset + thisOffset ];
                }
            }
            barrier(CLK_LOCAL_MEM_FENCE);
            int filterBoardOffset = upstreamPlane * gFilterSizeSquared;
            for( int u = minu; u <= maxu; u++ ) {
                int inputRow = outputRow + u;
                #if gPadZeros == 0
                    inputRow += gHalfFilterSize;
                #endif
                int inputboardrowoffset = inputRow * gInputBoardSize;
                int filterrowoffset = filterBoardOffset + (u+gHalfFilterSize) * gFilterSize + gHalfFilterSize;
                for( int v = minv; v <= maxv; v++ ) {
                    int inputCol = outputCol + v;
                    #if gPadZeros == 0
                        inputCol += gHalfFilterSize;
                    #endif
                    if( localId < gOutputBoardSizeSquared ) {
                        sum += _upstreamBoard[ inputboardrowoffset + inputCol] * _filterCube[ filterrowoffset + v ];
                    }
                }
            }
        }

        // results are organized like [imageid][filterid][row][col]
        int resultIndex = ( n * gNumFilters + outPlane ) * gOutputBoardSizeSquared + localId;
        if( localId < gOutputBoardSizeSquared ) {
            results[resultIndex ] = sum;
        }
    }

    )DELIM";
    kernel = cl->buildKernelFromString( kernelSource, "propagate_3_by_n_outplane", options, "cl/propagate3.cl" );
    // generated using cog:
    const char * repeatedAddSource =  R"DELIM(

    // Copyright Hugh Perkins 2015 hughperkins at gmail
    //
    // This Source Code Form is subject to the terms of the Mozilla Public License,
    // v. 2.0. If a copy of the MPL was not distributed with this file, You can
    // obtain one at http://mozilla.org/MPL/2.0/.

    kernel void per_element_add( const int N, global float *target, global const float *source ) {
        const int globalId = get_global_id(0);
        if( globalId >= N ) {
            return;
        }
        target[globalId] += source[globalId];
    }

    // adds source to target
    // tiles source as necessary, according to tilingSize
    kernel void per_element_tiled_add( const int N, const int tilingSize, global float *target, global const float *source ) {
        const int globalId = get_global_id(0);
        if( globalId >= N ) {
            return;
        }
        target[globalId] += source[globalId % tilingSize];
    }

    kernel void repeated_add( const int N, const int sourceSize, const int repeatSize, global float *target, global const float *source ) {
        const int globalId = get_global_id(0);
        if( globalId >= N ) {
            return;
        }
        target[globalId] += source[ ( globalId / repeatSize ) % sourceSize ];
    }

    )DELIM";
    repeatedAdd = cl->buildKernelFromString( repeatedAddSource, "repeated_add", options, "cl/per_element_add.cl" );
    // generated using cog:
    const char * activateSource =  R"DELIM(

    // Copyright Hugh Perkins 2015 hughperkins at gmail
    //
    // This Source Code Form is subject to the terms of the Mozilla Public License,
    // v. 2.0. If a copy of the MPL was not distributed with this file, You can
    // obtain one at http://mozilla.org/MPL/2.0/.

    // expected defines:
    // one of: [ TANH | RELU | LINEAR | SIGMOID | SCALEDTANH ]

    #ifdef TANH
        #define ACTIVATION_FUNCTION(output) (tanh(output))
    #elif defined SCALEDTANH
        #define ACTIVATION_FUNCTION(output) ( 1.7159f * tanh( 0.66667f * output))
    #elif SIGMOID
        #define ACTIVATION_FUNCTION(output) (1.0f / (1 + exp(-output)))
    #elif defined RELU
        #define ACTIVATION_FUNCTION(output) (output> 0 ? output : 0)
    #elif defined LINEAR
        #define ACTIVATION_FUNCTION(output) (output)
    #endif

    #ifdef ACTIVATION_FUNCTION // protect against not defined
    kernel void activate( const int N, global float *inout ) {
        const int globalId = get_global_id(0);
        if( globalId >= N ) {
            return;
        }
        inout[globalId] = ACTIVATION_FUNCTION( inout[globalId] );
    }
    #endif

    )DELIM";
    activate = cl->buildKernelFromString( activateSource, "activate", options, "cl/activate.cl" );
    // [[[end]]]
}

<commit_msg>switch back to stringify2 for now<commit_after>// Copyright Hugh Perkins 2014,2015 hughperkins at gmail
//
// This Source Code Form is subject to the terms of the Mozilla Public License,
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
// obtain one at http://mozilla.org/MPL/2.0/.

#include <algorithm>

#include "Propagate3.h"
#include "stringhelper.h"
#include "StatefulTimer.h"

using namespace std;

#undef VIRTUAL
#undef STATIC
#define VIRTUAL
#define STATIC

VIRTUAL Propagate3::~Propagate3() {
    delete kernel;
    delete repeatedAdd;
    delete activate;
}
VIRTUAL void Propagate3::propagate( int batchSize, CLWrapper *dataWrapper, CLWrapper *weightsWrapper, CLWrapper *biasWeightsWrapper,
    CLWrapper *resultsWrapper ) {
    StatefulTimer::timeCheck("Propagate3::propagate begin");
    const int maxWorkgroupSize = cl->getMaxWorkgroupSize();
    int maxglobalId = 0;

    kernel->in(batchSize);
    kernel->input( dataWrapper );
    kernel->input( weightsWrapper);
//    if( dim.biased ) kernel->input( biasWeightsWrapper );
    kernel->output( resultsWrapper );
//    cout << "square(dim.outputBoardSize) " << square( dim.outputBoardSize ) << endl;
    kernel->localFloats( square( dim.inputBoardSize ) );
    kernel->localFloats( square( dim.filterSize ) * dim.inputPlanes );

    int workgroupsize = std::max( 32, square( dim.outputBoardSize ) ); // no point in wasting threads....
    int numWorkgroups = dim.numFilters * batchSize;
    int globalSize = workgroupsize * numWorkgroups;
//    cout << "propagate3 numworkgroups " << numWorkgroups << " globalsize " << globalSize << " workgroupsize " << workgroupsize << endl;
    kernel->run_1d( globalSize, workgroupsize );
    cl->finish();
    StatefulTimer::timeCheck("Propagate3::propagate after kernel1");

//    {
//        resultsWrapper->copyToHost();
//        float const *results = reinterpret_cast< float const *>( resultsWrapper->getHostArray() );
//        for( int i = 0; i < min( 64, resultsWrapper->size() ); i++ ) {
//            cout << "results[" << i << "]=" << results[i] << endl;
//        }
//    }

    if( dim.biased ) {
        repeatedAdd->in( batchSize * dim.numFilters * dim.outputBoardSize * dim.outputBoardSize )
            ->in( dim.numFilters )
            ->in( dim.outputBoardSize * dim.outputBoardSize )
            ->inout( resultsWrapper )->in( biasWeightsWrapper );
        maxglobalId = batchSize * dim.numFilters * dim.outputBoardSize * dim.outputBoardSize;
        numWorkgroups = ( maxglobalId + maxWorkgroupSize - 1 ) / maxWorkgroupSize;
        repeatedAdd->run_1d( numWorkgroups * maxWorkgroupSize, maxWorkgroupSize );
        cl->finish();
        StatefulTimer::timeCheck("Propagate3::propagate after repeatedAdd");
    }

    activate->in( batchSize * dim.numFilters * dim.outputBoardSize * dim.outputBoardSize )
        ->inout( resultsWrapper );
    maxglobalId = batchSize * dim.numFilters * dim.outputBoardSize * dim.outputBoardSize;
    numWorkgroups = ( maxglobalId + maxWorkgroupSize - 1 ) / maxWorkgroupSize;
    activate->run_1d( numWorkgroups * maxWorkgroupSize, maxWorkgroupSize );
    cl->finish();
    StatefulTimer::timeCheck("Propagate3::propagate after activate");

    StatefulTimer::timeCheck("Propagate3::propagate after call propagate");
}
Propagate3::Propagate3( OpenCLHelper *cl, LayerDimensions dim, ActivationFunction const*fn ) :
        Propagate( cl, dim, fn )
            {

    if( square( dim.outputBoardSize ) > cl->getMaxWorkgroupSize() ) {
        throw runtime_error("cannot use propagate3, since outputboardsize * outputboardsize > maxworkgroupsize");
    }

    std::string options = "-D " + fn->getDefineName();
    options += dim.buildOptionsString();

    // [[[cog
    // import stringify
    // stringify.write_kernel2( "kernel", "cl/propagate3.cl", "propagate_3_by_n_outplane", 'options' )
    // stringify.write_kernel2( "repeatedAdd", "cl/per_element_add.cl", "repeated_add", 'options' )
    // stringify.write_kernel2( "activate", "cl/activate.cl", "activate", 'options' )
    // ]]]
    // generated using cog:
    const char * kernelSource =
    "// Copyright Hugh Perkins 2014, 2015 hughperkins at gmail\n"
    "//\n"
    "// This Source Code Form is subject to the terms of the Mozilla Public License,\n"
    "// v. 2.0. If a copy of the MPL was not distributed with this file, You can\n"
    "// obtain one at http://mozilla.org/MPL/2.0/.\n"
    "\n"
    "// concept: each workgroup handles convolving one input example with one filtercube\n"
    "// and writing out one single output plane\n"
    "//\n"
    "// workgroup id organized like: [imageid][outplane]\n"
    "// local id organized like: [outrow][outcol]\n"
    "// each thread iterates over: [upstreamplane][filterrow][filtercol]\n"
    "// number workgroups = 32\n"
    "// one filter plane takes up 5 * 5 * 4 = 100 bytes\n"
    "// one filter cube (corresponding to one outplane) = 5*5 * 32 * 4 = 3.2KB (ok)\n"
    "// all filter cubes = 3.2KB * 32 = 102KB (too big)\n"
    "// results are organized like [imageid][filterid][row][col]\n"
    "void kernel propagate_3_by_n_outplane( const int batchSize,\n"
    "      global const float *images, global const float *filters,\n"
    "    global float *results,\n"
    "    local float *_upstreamBoard, local float *_filterCube ) {\n"
    "    const int globalId = get_global_id(0);\n"
    "\n"
    "    const int workgroupId = get_group_id(0);\n"
    "    const int workgroupSize = get_local_size(0);\n"
    "    const int n = workgroupId / gNumFilters;\n"
    "    const int outPlane = workgroupId % gNumFilters;\n"
    "\n"
    "    const int localId = get_local_id(0);\n"
    "    const int outputRow = localId / gOutputBoardSize;\n"
    "    const int outputCol = localId % gOutputBoardSize;\n"
    "\n"
    "    const int minu = gPadZeros ? max( -gHalfFilterSize, -outputRow ) : -gHalfFilterSize;\n"
    "    const int maxu = gPadZeros ? min( gHalfFilterSize - gEven, gOutputBoardSize - 1 - outputRow  - gEven) : gHalfFilterSize - gEven;\n"
    "    const int minv = gPadZeros ? max( -gHalfFilterSize, -outputCol ) : - gHalfFilterSize;\n"
    "    const int maxv = gPadZeros ? min( gHalfFilterSize - gEven, gOutputBoardSize - 1 - outputCol - gEven) : gHalfFilterSize - gEven;\n"
    "\n"
    "    const int numUpstreamsPerThread = ( gInputBoardSizeSquared + workgroupSize - 1 ) / workgroupSize;\n"
    "\n"
    "    const int filterCubeLength = gInputPlanes * gFilterSizeSquared;\n"
    "    const int filterCubeGlobalOffset = outPlane * filterCubeLength;\n"
    "    const int numPixelsPerThread = ( filterCubeLength + workgroupSize - 1 ) / workgroupSize;\n"
    "    for( int i = 0; i < numPixelsPerThread; i++ ) {\n"
    "        int thisOffset = localId + i * workgroupSize;\n"
    "        if( thisOffset < filterCubeLength ) {\n"
    "            _filterCube[thisOffset] = filters[filterCubeGlobalOffset + thisOffset];\n"
    "        }\n"
    "    }\n"
    "    // dont need a barrier, since we'll just run behind the barrier from the upstream board download\n"
    "\n"
    "    float sum = 0;\n"
    "    for( int upstreamPlane = 0; upstreamPlane < gInputPlanes; upstreamPlane++ ) {\n"
    "        int thisUpstreamBoardOffset = ( n * gInputPlanes + upstreamPlane ) * gInputBoardSizeSquared;\n"
    "        barrier(CLK_LOCAL_MEM_FENCE);\n"
    "        for( int i = 0; i < numUpstreamsPerThread; i++ ) {\n"
    "            int thisOffset = workgroupSize * i + localId;\n"
    "            if( thisOffset < gInputBoardSizeSquared ) {\n"
    "                _upstreamBoard[ thisOffset ] = images[ thisUpstreamBoardOffset + thisOffset ];\n"
    "            }\n"
    "        }\n"
    "        barrier(CLK_LOCAL_MEM_FENCE);\n"
    "        int filterBoardOffset = upstreamPlane * gFilterSizeSquared;\n"
    "        for( int u = minu; u <= maxu; u++ ) {\n"
    "            int inputRow = outputRow + u;\n"
    "            #if gPadZeros == 0\n"
    "                inputRow += gHalfFilterSize;\n"
    "            #endif\n"
    "            int inputboardrowoffset = inputRow * gInputBoardSize;\n"
    "            int filterrowoffset = filterBoardOffset + (u+gHalfFilterSize) * gFilterSize + gHalfFilterSize;\n"
    "            for( int v = minv; v <= maxv; v++ ) {\n"
    "                int inputCol = outputCol + v;\n"
    "                #if gPadZeros == 0\n"
    "                    inputCol += gHalfFilterSize;\n"
    "                #endif\n"
    "                if( localId < gOutputBoardSizeSquared ) {\n"
    "                    sum += _upstreamBoard[ inputboardrowoffset + inputCol] * _filterCube[ filterrowoffset + v ];\n"
    "                }\n"
    "            }\n"
    "        }\n"
    "    }\n"
    "\n"
    "    // results are organized like [imageid][filterid][row][col]\n"
    "    int resultIndex = ( n * gNumFilters + outPlane ) * gOutputBoardSizeSquared + localId;\n"
    "    if( localId < gOutputBoardSizeSquared ) {\n"
    "        results[resultIndex ] = sum;\n"
    "    }\n"
    "}\n"
    "\n"
    "";
    kernel = cl->buildKernelFromString( kernelSource, "propagate_3_by_n_outplane", options, "cl/propagate3.cl" );
    // generated using cog:
    const char * repeatedAddSource =
    "// Copyright Hugh Perkins 2015 hughperkins at gmail\n"
    "//\n"
    "// This Source Code Form is subject to the terms of the Mozilla Public License,\n"
    "// v. 2.0. If a copy of the MPL was not distributed with this file, You can\n"
    "// obtain one at http://mozilla.org/MPL/2.0/.\n"
    "\n"
    "kernel void per_element_add( const int N, global float *target, global const float *source ) {\n"
    "    const int globalId = get_global_id(0);\n"
    "    if( globalId >= N ) {\n"
    "        return;\n"
    "    }\n"
    "    target[globalId] += source[globalId];\n"
    "}\n"
    "\n"
    "// adds source to target\n"
    "// tiles source as necessary, according to tilingSize\n"
    "kernel void per_element_tiled_add( const int N, const int tilingSize, global float *target, global const float *source ) {\n"
    "    const int globalId = get_global_id(0);\n"
    "    if( globalId >= N ) {\n"
    "        return;\n"
    "    }\n"
    "    target[globalId] += source[globalId % tilingSize];\n"
    "}\n"
    "\n"
    "kernel void repeated_add( const int N, const int sourceSize, const int repeatSize, global float *target, global const float *source ) {\n"
    "    const int globalId = get_global_id(0);\n"
    "    if( globalId >= N ) {\n"
    "        return;\n"
    "    }\n"
    "    target[globalId] += source[ ( globalId / repeatSize ) % sourceSize ];\n"
    "}\n"
    "\n"
    "";
    repeatedAdd = cl->buildKernelFromString( repeatedAddSource, "repeated_add", options, "cl/per_element_add.cl" );
    // generated using cog:
    const char * activateSource =
    "// Copyright Hugh Perkins 2015 hughperkins at gmail\n"
    "//\n"
    "// This Source Code Form is subject to the terms of the Mozilla Public License,\n"
    "// v. 2.0. If a copy of the MPL was not distributed with this file, You can\n"
    "// obtain one at http://mozilla.org/MPL/2.0/.\n"
    "\n"
    "// expected defines:\n"
    "// one of: [ TANH | RELU | LINEAR | SIGMOID | SCALEDTANH ]\n"
    "\n"
    "#ifdef TANH\n"
    "    #define ACTIVATION_FUNCTION(output) (tanh(output))\n"
    "#elif defined SCALEDTANH\n"
    "    #define ACTIVATION_FUNCTION(output) ( 1.7159f * tanh( 0.66667f * output))\n"
    "#elif SIGMOID\n"
    "    #define ACTIVATION_FUNCTION(output) (1.0f / (1 + exp(-output)))\n"
    "#elif defined RELU\n"
    "    #define ACTIVATION_FUNCTION(output) (output> 0 ? output : 0)\n"
    "#elif defined LINEAR\n"
    "    #define ACTIVATION_FUNCTION(output) (output)\n"
    "#endif\n"
    "\n"
    "#ifdef ACTIVATION_FUNCTION // protect against not defined\n"
    "kernel void activate( const int N, global float *inout ) {\n"
    "    const int globalId = get_global_id(0);\n"
    "    if( globalId >= N ) {\n"
    "        return;\n"
    "    }\n"
    "    inout[globalId] = ACTIVATION_FUNCTION( inout[globalId] );\n"
    "}\n"
    "#endif\n"
    "\n"
    "";
    activate = cl->buildKernelFromString( activateSource, "activate", options, "cl/activate.cl" );
    // [[[end]]]
}

<|endoftext|>


<commit_before>#include <stdlib.h>
#include <errno.h>
#include <QtWidgets>

#include "p6vxapp.h"

#ifndef NOJOYSTICK
//SDL使用時にビルドを通すのに必要
#undef main
#endif

///////////////////////////////////////////////////////////
// メイン
///////////////////////////////////////////////////////////
int main( int argc, char *argv[] )
{
	//X11の場合用
	QCoreApplication::setAttribute(Qt::AA_X11InitThreads);
#if QT_VERSION >= 0x050700
#ifndef ANDROID
	// AndroidではAA_EnableHighDpiScalingを設定するとメニューの座標がおかしくなる
	QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
#endif
	P6VXApp app(argc, argv);

	QCommandLineParser parser;
	QCommandLineOption safeModeOption(QStringList() << "s" << "safemode", "Safe Mode");
	parser.addOption(safeModeOption);
	parser.process(app);
	bool safeMode = parser.isSet(safeModeOption);
	app.enableSafeMode(safeMode);

#ifdef ANDROID
	// AndroidではFusion以外のスタイルでは表示が崩れるので明示的に指定する。
	app.setStyle(QStyleFactory::create("Fusion"));
	app.setCustomRomPath(CUSTOMROMPATH);
#endif

	QLocale locale;
	QString lang = locale.uiLanguages()[0];
	QTranslator myappTranslator;

	//表示言語が日本語でない場合は英語リソースを読み込む
	if(lang != "ja-JP" && lang != "ja"){
		qDebug() << "LANG = " << lang;
		myappTranslator.load(":/translation/PC6001VX_en");
		app.installTranslator(&myappTranslator);
	} else {
#ifdef ANDROID
		QFontDatabase database;
		auto list = database.families(QFontDatabase::Japanese);
		for (auto& f : list){
			// 日本語で検索して最初に見つかったフォントを使う
			auto font = QApplication::font();
			qDebug() << "using " << f;
			font.setFamily(f);
			app.setFont(font);
			break;
		}
#endif
	}

	//イベントループが始まったらp6vxapp::startup()を実行
	QMetaObject::invokeMethod(&app, "startup", Qt::QueuedConnection);

	//イベントループを開始
	return app.exec();
}
<commit_msg>XPERIAでNoto Sans CJK JPが正しく選択されない問題への姑息的対応<commit_after>#include <stdlib.h>
#include <errno.h>
#include <QtWidgets>

#include "p6vxapp.h"

#ifndef NOJOYSTICK
//SDL使用時にビルドを通すのに必要
#undef main
#endif

///////////////////////////////////////////////////////////
// メイン
///////////////////////////////////////////////////////////
int main( int argc, char *argv[] )
{
	//X11の場合用
	QCoreApplication::setAttribute(Qt::AA_X11InitThreads);
#if QT_VERSION >= 0x050700
#ifndef ANDROID
	// AndroidではAA_EnableHighDpiScalingを設定するとメニューの座標がおかしくなる
	QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
#endif
	P6VXApp app(argc, argv);

	QCommandLineParser parser;
	QCommandLineOption safeModeOption(QStringList() << "s" << "safemode", "Safe Mode");
	parser.addOption(safeModeOption);
	parser.process(app);
	bool safeMode = parser.isSet(safeModeOption);
	app.enableSafeMode(safeMode);

#ifdef ANDROID
	// AndroidではFusion以外のスタイルでは表示が崩れるので明示的に指定する。
	app.setStyle(QStyleFactory::create("Fusion"));
	app.setCustomRomPath(CUSTOMROMPATH);
#endif

	QLocale locale;
	QTranslator myappTranslator;

	//表示言語が日本語でない場合は英語リソースを読み込む
	if(locale.language() != QLocale::Japanese){
		qDebug() << "LANG = " << locale;
		myappTranslator.load(":/translation/PC6001VX_en");
		app.installTranslator(&myappTranslator);
	} else {
#ifdef ANDROID
		QFontDatabase database;
		// 日本語に対応したフォントを検索
		auto list = database.families(QFontDatabase::Japanese);
		QString family;
		if(!list.isEmpty()){
			for (auto& f : list){
				qDebug() << "listing " << f;

				// 一般に知られているAndroidのデフォルト日本語フォント
				QStringList jpFontList = QStringList()
						<< "Sony Mobile UD Gothic Regular"
						<< "Noto Sans CJK JP"
						<< "MotoyaLMaru";
				for (auto& c : jpFontList){
					if (f == c){
						family = f;
						break;
					}
				}
			}
			if (family.isEmpty()){
				// 既知のフォントが見つからなかった場合は
				// 最初に見つかったフォントを使う
				family = list.first();
			}
			auto font = QApplication::font();
			qDebug() << "using " << family;
			font.setFamily(family);
			app.setFont(font);
		}
#endif
	}

	//イベントループが始まったらp6vxapp::startup()を実行
	QMetaObject::invokeMethod(&app, "startup", Qt::QueuedConnection);

	//イベントループを開始
	return app.exec();
}
<|endoftext|>


<commit_before>#include "RCoRoutine.h"
#include "RThread.h"
#include "REventLoop.h"
#include "RLimits.h"

RCoRoutine::RCoRoutine(void *impl) : mImpl(impl), mType(Attached)
{
  PT_INIT(&mPt);
  thread()->eventLoop()->_attachCR(this);
}

RCoRoutine::~RCoRoutine()
{
  // Detached coroutines will be remove automatically while coroutine finished.
  if(type() == Attached)
  {
    thread()->eventLoop()->_detachCR(this);
  }
}

void
RCoRoutine::setType(RCoRoutine::Type aType)
{
  mType = aType;
}

RCoRoutine::Type
RCoRoutine::type()
{
  return static_cast<Type>(mType);
}

void
RCoRoutine::terminate()
{
  mPt.lc = RNumericLimits<R_RAW_TYPE_OF(mPt.lc)>::sMax;
}

bool
RCoRoutine::_isTerminated()
{
  return (RNumericLimits<R_RAW_TYPE_OF(mPt.lc)>::sMax == mPt.lc);
}

class A : public RObject
{
public:
};

RCR_BEGIN(A, rcTest, (int, Var))
RCR_IMPL()
RCR_END()
<commit_msg>Removed junk codes<commit_after>#include "RCoRoutine.h"
#include "RThread.h"
#include "REventLoop.h"
#include "RLimits.h"

RCoRoutine::RCoRoutine(void *impl) : mImpl(impl), mType(Attached)
{
  PT_INIT(&mPt);
  thread()->eventLoop()->_attachCR(this);
}

RCoRoutine::~RCoRoutine()
{
  // Detached coroutines will be remove automatically while coroutine finished.
  if(type() == Attached)
  {
    thread()->eventLoop()->_detachCR(this);
  }
}

void
RCoRoutine::setType(RCoRoutine::Type aType)
{
  mType = aType;
}

RCoRoutine::Type
RCoRoutine::type()
{
  return static_cast<Type>(mType);
}

void
RCoRoutine::terminate()
{
  mPt.lc = RNumericLimits<R_RAW_TYPE_OF(mPt.lc)>::sMax;
}

bool
RCoRoutine::_isTerminated()
{
  return (RNumericLimits<R_RAW_TYPE_OF(mPt.lc)>::sMax == mPt.lc);
}
<|endoftext|>


<commit_before>#include "Row_DH_IOE.h"

const bool Scanner_Port::STROBE_ON = HIGH; //active high

void Row_DH_IOE::process()
{
    //these variables are all bitwise, one bit per key
    uint8_t readState;                       //1 means pressed, 0 means released
    uint8_t debouncedChanged;               //1 means debounced changed
    //ReadPort* ptrReadPort;

    //ptrReadPort = scanner.scan();
    //readState = ptrReadPort->getPortState() >> (6-READ_PIN_COUNT);
    readState = scanner.scan() >> (6-READ_PIN_COUNT);
/*
if (READ_PIN_COUNT == 6)
{
    Keyboard.print(" readState=");
    Keyboard.print(readState);
}*/
    debouncedChanged = debouncer.debounce(readState, debounced);
    pressRelease(READ_PIN_COUNT, debouncedChanged);
}
<commit_msg>add StrobePort_PCA9655E::write() and const bool Scanner_Port::STROBE_OFF<commit_after>#include "Row_DH_IOE.h"

const bool Scanner_Port::STROBE_ON = HIGH; //active high
const bool Scanner_Port::STROBE_OFF = LOW;

void Row_DH_IOE::process()
{
    //these variables are all bitwise, one bit per key
    uint8_t readState;                       //1 means pressed, 0 means released
    uint8_t debouncedChanged;               //1 means debounced changed

    readState = scanner.scan() >> (6-READ_PIN_COUNT);
    debouncedChanged = debouncer.debounce(readState, debounced);
    pressRelease(READ_PIN_COUNT, debouncedChanged);
}
<|endoftext|>


<commit_before>#ifdef __unix__

#include <iostream>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>

#include "Types.h"

#include "Tools.h"

void StartBotProcess(const BotConfig &Agent, const std::string& CommandLine, void **ProcessId)
{
    FILE* pipe = popen(CommandLine.c_str(), "r");
    if (!pipe)
    {
        std::cerr << "Can't launch command '" <<
            CommandLine << "'" << std::endl;
        return;
    }
	*ProcessId = pipe;
    int returnCode = pclose(pipe);
    if (returnCode != 0)
    {
        std::cerr << "Failed to finish command '" <<
            CommandLine << "', code: " << returnCode << std::endl;
    }
}

void SleepFor(int seconds)
{
    sleep(seconds);
}

void KillSc2Process(unsigned long pid)
{
    kill(pid, SIGKILL);
}

bool MoveReplayFile(const char* lpExistingFileName, const  char* lpNewFileName)
{
	// todo
	throw "MoveFile is not implemented for linux yet.";
}

void KillBotProcess(void *ProcessStruct);
{
	// This needs to be implemented
}

#endif<commit_msg>Fix Tools compilation under OS X<commit_after>#if defined(__unix__) || defined(__APPLE__)

#include <iostream>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>

#include "Types.h"

#include "Tools.h"

void StartBotProcess(const BotConfig &Agent, const std::string& CommandLine, void **ProcessId)
{
    FILE* pipe = popen(CommandLine.c_str(), "r");
    if (!pipe)
    {
        std::cerr << "Can't launch command '" <<
            CommandLine << "'" << std::endl;
        return;
    }
	*ProcessId = pipe;
    int returnCode = pclose(pipe);
    if (returnCode != 0)
    {
        std::cerr << "Failed to finish command '" <<
            CommandLine << "', code: " << returnCode << std::endl;
    }
}

void SleepFor(int seconds)
{
    sleep(seconds);
}

void KillSc2Process(unsigned long pid)
{
    kill(pid, SIGKILL);
}

bool MoveReplayFile(const char* lpExistingFileName, const  char* lpNewFileName)
{
	// todo
	throw "MoveFile is not implemented for linux yet.";
}

void KillBotProcess(void *ProcessStruct);
{
	// This needs to be implemented
}

#endif<|endoftext|>


<commit_before>#include <iostream>
#include <memory>

#include <cstring>

#include <pthread.h>
#include <semaphore.h>

#include "gestion-fichiers.hpp"

constexpr size_t const TAILLEBUF = 2048;

sem_t dataLock;

struct ReadingThreadData {
	std::string filename;
	char* data;
};

void readAndStore(IFile& source, char* data) {
	char line[TAILLEBUF];
	source >> line;
	std::cout << "[Reading]: Line read." << std::endl;

	std::strncpy(data, line, TAILLEBUF);
}

void* readingThreadMain(void* voidThreadData) {
	std::cout << "[Reading]: Thread spawned." << std::endl;

	struct ReadingThreadData* threadData =
	  reinterpret_cast<struct ReadingThreadData*>(voidThreadData);

	IFile source(threadData->filename.c_str(), TAILLEBUF);

	while(!source.hasEnded()) {
		std::cout << "[Reading] Waiting..." << std::endl;
		sem_wait(&dataLock);
		readAndStore(source, threadData->data);
		sem_post(&dataLock);
	}

	std::cout << "[Reading]: Sending End-of-Transmission" << std::endl;
	threadData->data[0] = 0x04;

	std::cout << "[Reading]: Thread exiting" << std::endl;
	pthread_exit(NULL);
}

struct TransmittingThreadData {
	std::string filename;
	char* data;
};

void getAndTransmit(OFile& destination, char* data) {
	destination << data;
}

void* transmittingThreadMain(void* voidThreadData) {
	std::cout << "[Transmission]: Thread spawned." << std::endl;

	struct TransmittingThreadData* threadData =
	  reinterpret_cast<struct TransmittingThreadData*>(voidThreadData);

	OFile destination(threadData->filename.c_str(), TAILLEBUF);

	char previous[TAILLEBUF];

	std::strncpy(previous, threadData->data, TAILLEBUF);

	while(threadData->data[0] != 0x04) {
		if(std::strncmp(previous, threadData->data, TAILLEBUF)) {
			std::strncpy(previous, threadData->data, TAILLEBUF);
			sem_post(&dataLock);
			destination << previous;
			std::cout << "[Transmission]: Line transmitted." << std::endl;
		} else {
			sem_post(&dataLock);
		}
		std::cout << "[Transmission] Waiting..." << std::endl;
		sem_wait(&dataLock);
	}
	std::cout << "[Transmission]: Received End-of-Transmission" << std::endl;

	std::cout << "[Transmission]: Thread exiting" << std::endl;
	pthread_exit(NULL);
}

int main(int argc, char* argv[]) {
	if(argc != 3) {
		std::cout << "Usage: " << argv[0] << " source destination" << std::endl;
		return EINVAL;
	}

	sem_init(&dataLock, /* __pshared = */ 0, /* __value = */ 0);

	pthread_t transmittingThread, readingThread;

	std::unique_ptr<char[]> c(new char[TAILLEBUF]);
	c.get()[0] = '\0';

	std::unique_ptr<struct TransmittingThreadData> transmittingThreadData(
	  new struct TransmittingThreadData);
	transmittingThreadData->filename = argv[2];
	transmittingThreadData->data     = c.get();

	std::unique_ptr<struct ReadingThreadData> readingThreadData(new struct ReadingThreadData);
	readingThreadData->filename = argv[1];
	readingThreadData->data     = c.get();

	pthread_create(&transmittingThread, NULL, transmittingThreadMain,
	               reinterpret_cast<void*>(transmittingThreadData.get()));
	pthread_create(&readingThread, NULL, readingThreadMain,
	               reinterpret_cast<void*>(readingThreadData.get()));

	pthread_join(transmittingThread, nullptr);
	pthread_join(readingThread, nullptr);

	pthread_exit(NULL);
}
<commit_msg>No more owning raw pointers + main thread no more wait uselessly (join)<commit_after>#include <iostream>
#include <memory>

#include <cstring>

#include <pthread.h>
#include <semaphore.h>

#include "gestion-fichiers.hpp"

constexpr size_t const TAILLEBUF = 2048;

struct ReadingThreadData {
	std::string filename;
	std::shared_ptr<char> data;
	std::shared_ptr<sem_t> dataLock;
	sem_t* ready;
};

void readAndStore(IFile& source, char* data) {
	char line[TAILLEBUF];
	source >> line;
	std::cout << "[Reading]: Line read." << std::endl;

	std::strncpy(data, line, TAILLEBUF);
}

void* readingThreadMain(void* voidThreadData) {
	std::cout << "[Reading]: Thread spawned." << std::endl;

	struct ReadingThreadData* threadData =
	  reinterpret_cast<struct ReadingThreadData*>(voidThreadData);

	std::shared_ptr<sem_t> dataLock = threadData->dataLock;
	std::shared_ptr<char> data = threadData->data;
	std::cout << "[Reading]: Ready!" << std::endl;
	sem_post(threadData->ready);

	IFile source(threadData->filename.c_str(), TAILLEBUF);

	while(!source.hasEnded()) {
		std::cout << "[Reading] Waiting..." << std::endl;
		sem_wait(dataLock.get());
		readAndStore(source, data.get());
		sem_post(dataLock.get());
	}

	std::cout << "[Reading]: Sending End-of-Transmission" << std::endl;
	data.get()[0] = 0x04;

	std::cout << "[Reading]: Thread exiting" << std::endl;
	pthread_exit(NULL);
}

struct TransmittingThreadData {
	std::string filename;
	std::shared_ptr<char> data;
	std::shared_ptr<sem_t> dataLock;
	sem_t* ready;
};

void getAndTransmit(OFile& destination, char* data) {
	destination << data;
}

void* transmittingThreadMain(void* voidThreadData) {
	std::cout << "[Transmission]: Thread spawned." << std::endl;

	struct TransmittingThreadData* threadData =
	  reinterpret_cast<struct TransmittingThreadData*>(voidThreadData);

	std::shared_ptr<sem_t> dataLock = threadData->dataLock;
	std::shared_ptr<char> data = threadData->data;
	std::cout << "[Transmission]: Ready!" << std::endl;
	sem_post(threadData->ready);

	OFile destination(threadData->filename.c_str(), TAILLEBUF);

	char previous[TAILLEBUF];

	std::strncpy(previous, data.get(), TAILLEBUF);

	while(data.get()[0] != 0x04) {
		if(std::strncmp(previous, data.get(), TAILLEBUF)) {
			std::strncpy(previous, data.get(), TAILLEBUF);
			sem_post(dataLock.get());
			destination << previous;
			std::cout << "[Transmission]: Line transmitted." << std::endl;
		} else {
			sem_post(dataLock.get());
		}
		std::cout << "[Transmission]: Waiting..." << std::endl;
		sem_wait(dataLock.get());
	}
	std::cout << "[Transmission]: Received End-of-Transmission" << std::endl;

	std::cout << "[Transmission]: Thread exiting" << std::endl;
	pthread_exit(NULL);
}

int main(int argc, char* argv[]) {
	if(argc != 3) {
		std::cout << "Usage: " << argv[0] << " source destination" << std::endl;
		return EINVAL;
	}

	std::shared_ptr<sem_t> dataLock(new sem_t);
	sem_init(dataLock.get(), /* __pshared = */ 0, /* __value = */ 0);

	std::unique_ptr<sem_t> readingReady(new sem_t);
	sem_init(readingReady.get(), /* __pshared = */ 0, /* __value = */ 0);

	std::unique_ptr<sem_t> transmissionReady(new sem_t);
	sem_init(transmissionReady.get(), /* __pshared = */ 0, /* __value = */ 0);

	pthread_t transmittingThread, readingThread;

	std::shared_ptr<char> c(new char[TAILLEBUF], std::default_delete<char[]>());
	c.get()[0] = '\0';

	std::unique_ptr<struct TransmittingThreadData> transmittingThreadData(
	  new struct TransmittingThreadData);
	transmittingThreadData->filename = argv[2];
	transmittingThreadData->data     = c;
	transmittingThreadData->dataLock = dataLock;
	transmittingThreadData->ready    = readingReady.get();

	std::unique_ptr<struct ReadingThreadData> readingThreadData(new struct ReadingThreadData);
	readingThreadData->filename = argv[1];
	readingThreadData->data     = std::move(c);
	readingThreadData->dataLock = dataLock;
	readingThreadData->ready    = transmissionReady.get();

	pthread_create(&transmittingThread, NULL, transmittingThreadMain,
	               reinterpret_cast<void*>(transmittingThreadData.get()));
	pthread_create(&readingThread, NULL, readingThreadMain,
	               reinterpret_cast<void*>(readingThreadData.get()));

	std::cout << "[Main]: Waiting for Reading and Transmission to be Ready" << std::endl;
	sem_wait(readingReady.get());
	sem_wait(transmissionReady.get());

	std::cout << "[Main]: Goodbye!" << std::endl;
	pthread_exit(NULL);
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2004-2005 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <map>
#include <stack>
#include <string>

#include "targetarch/osfpal.hh"
#include "base/trace.hh"
#include "cpu/exec_context.hh"
#include "kern/kernel_stats.hh"
#include "kern/tru64/tru64_syscalls.hh"

using namespace std;
using namespace Stats;

namespace Kernel {

const char *modestr[] = { "kernel", "user", "idle", "interrupt" };

Statistics::Statistics(ExecContext *context)
    : xc(context), idleProcess((Addr)-1), themode(kernel), lastModeTick(0),
      iplLast(0), iplLastTick(0)
{
    bin_int = xc->system->params->bin_int;
}

void
Statistics::regStats(const string &_name)
{
    myname = _name;

    _arm
        .name(name() + ".inst.arm")
        .desc("number of arm instructions executed")
        ;

    _quiesce
        .name(name() + ".inst.quiesce")
        .desc("number of quiesce instructions executed")
        ;

    _ivlb
        .name(name() + ".inst.ivlb")
        .desc("number of ivlb instructions executed")
        ;

    _ivle
        .name(name() + ".inst.ivle")
        .desc("number of ivle instructions executed")
        ;

    _hwrei
        .name(name() + ".inst.hwrei")
        .desc("number of hwrei instructions executed")
        ;

    _iplCount
        .init(32)
        .name(name() + ".ipl_count")
        .desc("number of times we switched to this ipl")
        .flags(total | pdf | nozero | nonan)
        ;

    _iplGood
        .init(32)
        .name(name() + ".ipl_good")
        .desc("number of times we switched to this ipl from a different ipl")
        .flags(total | pdf | nozero | nonan)
        ;

    _iplTicks
        .init(32)
        .name(name() + ".ipl_ticks")
        .desc("number of cycles we spent at this ipl")
        .flags(total | pdf | nozero | nonan)
        ;

    _iplUsed
        .name(name() + ".ipl_used")
        .desc("fraction of swpipl calls that actually changed the ipl")
        .flags(total | nozero | nonan)
        ;

    _iplUsed = _iplGood / _iplCount;

    _callpal
        .init(256)
        .name(name() + ".callpal")
        .desc("number of callpals executed")
        .flags(total | pdf | nozero | nonan)
        ;

    for (int i = 0; i < PAL::NumCodes; ++i) {
        const char *str = PAL::name(i);
        if (str)
            _callpal.subname(i, str);
    }

    _syscall
        .init(SystemCalls<Tru64>::Number)
        .name(name() + ".syscall")
        .desc("number of syscalls executed")
        .flags(total | pdf | nozero | nonan)
        ;

    for (int i = 0; i < SystemCalls<Tru64>::Number; ++i) {
        const char *str = SystemCalls<Tru64>::name(i);
        if (str) {
            _syscall.subname(i, str);
        }
    }

/*    _faults
        .init(NumFaults)
        .name(name() + ".faults")
        .desc("number of faults")
        .flags(total | pdf | nozero | nonan)
        ;

    for (int i = 1; i < NumFaults; ++i) {
        const char *str = (*ListOfFaults[i])->name;
        if (str)
            _faults.subname(i, str);
    }*/

    _mode
        .init(cpu_mode_num)
        .name(name() + ".mode_switch")
        .desc("number of protection mode switches")
        ;

    for (int i = 0; i < cpu_mode_num; ++i)
        _mode.subname(i, modestr[i]);

    _modeGood
        .init(cpu_mode_num)
        .name(name() + ".mode_good")
        ;

    for (int i = 0; i < cpu_mode_num; ++i)
        _modeGood.subname(i, modestr[i]);

    _modeFraction
        .name(name() + ".mode_switch_good")
        .desc("fraction of useful protection mode switches")
        .flags(total)
        ;

    for (int i = 0; i < cpu_mode_num; ++i)
        _modeFraction.subname(i, modestr[i]);

    _modeFraction = _modeGood / _mode;

    _modeTicks
        .init(cpu_mode_num)
        .name(name() + ".mode_ticks")
        .desc("number of ticks spent at the given mode")
        .flags(pdf)
        ;
    for (int i = 0; i < cpu_mode_num; ++i)
        _modeTicks.subname(i, modestr[i]);

    _swap_context
        .name(name() + ".swap_context")
        .desc("number of times the context was actually changed")
        ;
}

void
Statistics::setIdleProcess(Addr idlepcbb)
{
    assert(themode == kernel || themode == interrupt);
    idleProcess = idlepcbb;
    themode = idle;
    changeMode(themode);
}

void
Statistics::changeMode(cpu_mode newmode)
{
    _mode[newmode]++;

    if (newmode == themode)
        return;

    DPRINTF(Context, "old mode=%-8s new mode=%-8s\n",
            modestr[themode], modestr[newmode]);

    _modeGood[newmode]++;
    _modeTicks[themode] += curTick - lastModeTick;

    xc->system->kernelBinning->changeMode(newmode);

    lastModeTick = curTick;
    themode = newmode;
}

void
Statistics::swpipl(int ipl)
{
    assert(ipl >= 0 && ipl <= 0x1f && "invalid IPL\n");

    _iplCount[ipl]++;

    if (ipl == iplLast)
        return;

    _iplGood[ipl]++;
    _iplTicks[iplLast] += curTick - iplLastTick;
    iplLastTick = curTick;
    iplLast = ipl;
}

void
Statistics::mode(cpu_mode newmode)
{
    Addr pcbb = xc->regs.ipr[AlphaISA::IPR_PALtemp23];

    if ((newmode == kernel || newmode == interrupt) &&
            pcbb == idleProcess)
        newmode = idle;

    if (bin_int == false && newmode == interrupt)
        newmode = kernel;

    changeMode(newmode);
}

void
Statistics::context(Addr oldpcbb, Addr newpcbb)
{
    assert(themode != user);

    _swap_context++;
    changeMode(newpcbb == idleProcess ? idle : kernel);
}

void
Statistics::callpal(int code)
{
    if (!PAL::name(code))
        return;

    _callpal[code]++;

    switch (code) {
      case PAL::callsys: {
          int number = xc->regs.intRegFile[0];
          if (SystemCalls<Tru64>::validSyscallNumber(number)) {
              int cvtnum = SystemCalls<Tru64>::convert(number);
              _syscall[cvtnum]++;
          }
      } break;

      case PAL::swpctx:
        if (xc->system->kernelBinning)
            xc->system->kernelBinning->palSwapContext(xc);
        break;
    }
}

void
Statistics::serialize(ostream &os)
{
    int exemode = themode;
    SERIALIZE_SCALAR(exemode);
    SERIALIZE_SCALAR(idleProcess);
    SERIALIZE_SCALAR(iplLast);
    SERIALIZE_SCALAR(iplLastTick);
    SERIALIZE_SCALAR(lastModeTick);
}

void
Statistics::unserialize(Checkpoint *cp, const string &section)
{
    int exemode;
    UNSERIALIZE_SCALAR(exemode);
    UNSERIALIZE_SCALAR(idleProcess);
    UNSERIALIZE_SCALAR(iplLast);
    UNSERIALIZE_SCALAR(iplLastTick);
    UNSERIALIZE_SCALAR(lastModeTick);
    themode = (cpu_mode)exemode;
}

/* end namespace Kernel */ }
<commit_msg>Fixed up some include paths.<commit_after>/*
 * Copyright (c) 2004-2005 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <map>
#include <stack>
#include <string>

#include "arch/alpha/osfpal.hh"
#include "base/trace.hh"
#include "cpu/exec_context.hh"
#include "kern/kernel_stats.hh"
#include "kern/tru64/tru64_syscalls.hh"

using namespace std;
using namespace Stats;

namespace Kernel {

const char *modestr[] = { "kernel", "user", "idle", "interrupt" };

Statistics::Statistics(ExecContext *context)
    : xc(context), idleProcess((Addr)-1), themode(kernel), lastModeTick(0),
      iplLast(0), iplLastTick(0)
{
    bin_int = xc->system->params->bin_int;
}

void
Statistics::regStats(const string &_name)
{
    myname = _name;

    _arm
        .name(name() + ".inst.arm")
        .desc("number of arm instructions executed")
        ;

    _quiesce
        .name(name() + ".inst.quiesce")
        .desc("number of quiesce instructions executed")
        ;

    _ivlb
        .name(name() + ".inst.ivlb")
        .desc("number of ivlb instructions executed")
        ;

    _ivle
        .name(name() + ".inst.ivle")
        .desc("number of ivle instructions executed")
        ;

    _hwrei
        .name(name() + ".inst.hwrei")
        .desc("number of hwrei instructions executed")
        ;

    _iplCount
        .init(32)
        .name(name() + ".ipl_count")
        .desc("number of times we switched to this ipl")
        .flags(total | pdf | nozero | nonan)
        ;

    _iplGood
        .init(32)
        .name(name() + ".ipl_good")
        .desc("number of times we switched to this ipl from a different ipl")
        .flags(total | pdf | nozero | nonan)
        ;

    _iplTicks
        .init(32)
        .name(name() + ".ipl_ticks")
        .desc("number of cycles we spent at this ipl")
        .flags(total | pdf | nozero | nonan)
        ;

    _iplUsed
        .name(name() + ".ipl_used")
        .desc("fraction of swpipl calls that actually changed the ipl")
        .flags(total | nozero | nonan)
        ;

    _iplUsed = _iplGood / _iplCount;

    _callpal
        .init(256)
        .name(name() + ".callpal")
        .desc("number of callpals executed")
        .flags(total | pdf | nozero | nonan)
        ;

    for (int i = 0; i < PAL::NumCodes; ++i) {
        const char *str = PAL::name(i);
        if (str)
            _callpal.subname(i, str);
    }

    _syscall
        .init(SystemCalls<Tru64>::Number)
        .name(name() + ".syscall")
        .desc("number of syscalls executed")
        .flags(total | pdf | nozero | nonan)
        ;

    for (int i = 0; i < SystemCalls<Tru64>::Number; ++i) {
        const char *str = SystemCalls<Tru64>::name(i);
        if (str) {
            _syscall.subname(i, str);
        }
    }

/*    _faults
        .init(NumFaults)
        .name(name() + ".faults")
        .desc("number of faults")
        .flags(total | pdf | nozero | nonan)
        ;

    for (int i = 1; i < NumFaults; ++i) {
        const char *str = (*ListOfFaults[i])->name;
        if (str)
            _faults.subname(i, str);
    }*/

    _mode
        .init(cpu_mode_num)
        .name(name() + ".mode_switch")
        .desc("number of protection mode switches")
        ;

    for (int i = 0; i < cpu_mode_num; ++i)
        _mode.subname(i, modestr[i]);

    _modeGood
        .init(cpu_mode_num)
        .name(name() + ".mode_good")
        ;

    for (int i = 0; i < cpu_mode_num; ++i)
        _modeGood.subname(i, modestr[i]);

    _modeFraction
        .name(name() + ".mode_switch_good")
        .desc("fraction of useful protection mode switches")
        .flags(total)
        ;

    for (int i = 0; i < cpu_mode_num; ++i)
        _modeFraction.subname(i, modestr[i]);

    _modeFraction = _modeGood / _mode;

    _modeTicks
        .init(cpu_mode_num)
        .name(name() + ".mode_ticks")
        .desc("number of ticks spent at the given mode")
        .flags(pdf)
        ;
    for (int i = 0; i < cpu_mode_num; ++i)
        _modeTicks.subname(i, modestr[i]);

    _swap_context
        .name(name() + ".swap_context")
        .desc("number of times the context was actually changed")
        ;
}

void
Statistics::setIdleProcess(Addr idlepcbb)
{
    assert(themode == kernel || themode == interrupt);
    idleProcess = idlepcbb;
    themode = idle;
    changeMode(themode);
}

void
Statistics::changeMode(cpu_mode newmode)
{
    _mode[newmode]++;

    if (newmode == themode)
        return;

    DPRINTF(Context, "old mode=%-8s new mode=%-8s\n",
            modestr[themode], modestr[newmode]);

    _modeGood[newmode]++;
    _modeTicks[themode] += curTick - lastModeTick;

    xc->system->kernelBinning->changeMode(newmode);

    lastModeTick = curTick;
    themode = newmode;
}

void
Statistics::swpipl(int ipl)
{
    assert(ipl >= 0 && ipl <= 0x1f && "invalid IPL\n");

    _iplCount[ipl]++;

    if (ipl == iplLast)
        return;

    _iplGood[ipl]++;
    _iplTicks[iplLast] += curTick - iplLastTick;
    iplLastTick = curTick;
    iplLast = ipl;
}

void
Statistics::mode(cpu_mode newmode)
{
    Addr pcbb = xc->regs.ipr[AlphaISA::IPR_PALtemp23];

    if ((newmode == kernel || newmode == interrupt) &&
            pcbb == idleProcess)
        newmode = idle;

    if (bin_int == false && newmode == interrupt)
        newmode = kernel;

    changeMode(newmode);
}

void
Statistics::context(Addr oldpcbb, Addr newpcbb)
{
    assert(themode != user);

    _swap_context++;
    changeMode(newpcbb == idleProcess ? idle : kernel);
}

void
Statistics::callpal(int code)
{
    if (!PAL::name(code))
        return;

    _callpal[code]++;

    switch (code) {
      case PAL::callsys: {
          int number = xc->regs.intRegFile[0];
          if (SystemCalls<Tru64>::validSyscallNumber(number)) {
              int cvtnum = SystemCalls<Tru64>::convert(number);
              _syscall[cvtnum]++;
          }
      } break;

      case PAL::swpctx:
        if (xc->system->kernelBinning)
            xc->system->kernelBinning->palSwapContext(xc);
        break;
    }
}

void
Statistics::serialize(ostream &os)
{
    int exemode = themode;
    SERIALIZE_SCALAR(exemode);
    SERIALIZE_SCALAR(idleProcess);
    SERIALIZE_SCALAR(iplLast);
    SERIALIZE_SCALAR(iplLastTick);
    SERIALIZE_SCALAR(lastModeTick);
}

void
Statistics::unserialize(Checkpoint *cp, const string &section)
{
    int exemode;
    UNSERIALIZE_SCALAR(exemode);
    UNSERIALIZE_SCALAR(idleProcess);
    UNSERIALIZE_SCALAR(iplLast);
    UNSERIALIZE_SCALAR(iplLastTick);
    UNSERIALIZE_SCALAR(lastModeTick);
    themode = (cpu_mode)exemode;
}

/* end namespace Kernel */ }
<|endoftext|>


<commit_before>// Copyright (c) 2013, Matthew Harvey. All rights reserved.

#ifndef GUARD_entry_list_panel_hpp
#define GUARD_entry_list_panel_hpp

#include "entry.hpp"
#include <boost/date_time/gregorian/gregorian.hpp>
#include <boost/noncopyable.hpp>
#include <boost/optional.hpp>
#include <wx/button.h>
#include <wx/event.h>
#include <wx/gbsizer.h>
#include <wx/panel.h>
#include <wx/stattext.h>
#include <wx/window.h>
#include <vector>

namespace phatbooks
{

// Begin forward declarations

class Account;
class OrdinaryJournal;
class PhatbooksDatabaseConnection;

namespace gui
{

class AccountCtrl;
class DateCtrl;
class EntryListCtrl;

// End forward declarations

/**
 * A panel consisting of an EntryListCtrl at the bottom, and widgets
 * at the top to enable the user to filter the displayed Entries for a
 * particular Account and/or date range.
 *
 * @todo Do we want the user to be able to view non-actual transactions?
 * If we do, then, among other things, the AccountCtrl will need to allow
 * the user to select Accounts of account_type::pure_envelope.
 *
 * @todo EntryListCtrl has zero height until such time as user
 * first clicks "Refresh". Various attempted workarounds for this
 * have been tried to no avail...
 *
 * @todo HIGH PRIORITY Incorporate the result of calling
 * m_entry_list_ctrl->summary_data() into the EntryListPanel.
 *
 * @todo Make a subclass of FilteredEntryListCtrl called
 * ReconciliationEntryList, and use that with EntryListPanel to enable
 * users to perform Account reconciliations.
 */
class EntryListPanel: public wxPanel, private boost::noncopyable
{
public:
	EntryListPanel
	(	wxWindow* p_parent,
		PhatbooksDatabaseConnection& p_database_connection,
		bool p_support_reconciliations = false
	);

	void update_for_new(OrdinaryJournal const& p_journal);
	void update_for_amended(OrdinaryJournal const& p_journal);
	void update_for_new(Account const& p_account);
	void update_for_amended(Account const& p_account);
	void update_for_deleted(std::vector<Entry::Id> const& p_doomed_ids);
	void selected_entries(std::vector<Entry>& out);

	// WARNING Hack... This should be private, but we need to call it from
	// TopPanel to ensure EntryListCtrl is properly sized, AFTER the
	// EntryListPanel has been constructed.
	void configure_entry_list_ctrl();

	void postconfigure_summary();

private:
	void preconfigure_summary();

	void on_refresh_button_click(wxCommandEvent& event);
	Account selected_account() const;
	boost::optional<boost::gregorian::date> selected_min_date() const;
	boost::optional<boost::gregorian::date> selected_max_date() const;

	static int const s_account_ctrl_id = wxID_HIGHEST + 1;
	static int const s_min_date_ctrl_id = s_account_ctrl_id + 1;
	static int const s_max_date_ctrl_id = s_min_date_ctrl_id + 1;
	static int const s_refresh_button_id = s_max_date_ctrl_id + 1;
	static int const s_entry_list_ctrl_id = s_refresh_button_id + 1;

	bool m_support_reconciliations;
	int m_next_row;

	int m_client_size_aux;
	int m_text_ctrl_height;

	wxGridBagSizer* m_top_sizer;
	AccountCtrl* m_account_ctrl;
	DateCtrl* m_min_date_ctrl;
	DateCtrl* m_max_date_ctrl;
	wxButton* m_refresh_button;
	EntryListCtrl* m_entry_list_ctrl;
	std::vector<wxStaticText*> m_summary_label_text_items;
	std::vector<wxStaticText*> m_summary_data_text_items;
	PhatbooksDatabaseConnection& m_database_connection;

	DECLARE_EVENT_TABLE()

};  // class EntryListPanel

}  // namespace gui
}  // namespace phatbooks

#endif  // GUARD_entry_list_panel_hpp
<commit_msg>Deleted an obsolete TODO from EntryListPanel.<commit_after>// Copyright (c) 2013, Matthew Harvey. All rights reserved.

#ifndef GUARD_entry_list_panel_hpp
#define GUARD_entry_list_panel_hpp

#include "entry.hpp"
#include <boost/date_time/gregorian/gregorian.hpp>
#include <boost/noncopyable.hpp>
#include <boost/optional.hpp>
#include <wx/button.h>
#include <wx/event.h>
#include <wx/gbsizer.h>
#include <wx/panel.h>
#include <wx/stattext.h>
#include <wx/window.h>
#include <vector>

namespace phatbooks
{

// Begin forward declarations

class Account;
class OrdinaryJournal;
class PhatbooksDatabaseConnection;

namespace gui
{

class AccountCtrl;
class DateCtrl;
class EntryListCtrl;

// End forward declarations

/**
 * A panel consisting of an EntryListCtrl at the bottom, and widgets
 * at the top to enable the user to filter the displayed Entries for a
 * particular Account and/or date range.
 *
 * @todo Do we want the user to be able to view non-actual transactions?
 * If we do, then, among other things, the AccountCtrl will need to allow
 * the user to select Accounts of account_type::pure_envelope.
 *
 * @todo EntryListCtrl has zero height until such time as user
 * first clicks "Refresh". Various attempted workarounds for this
 * have been tried to no avail...
 *
 * @todo Make a subclass of FilteredEntryListCtrl called
 * ReconciliationEntryList, and use that with EntryListPanel to enable
 * users to perform Account reconciliations.
 */
class EntryListPanel: public wxPanel, private boost::noncopyable
{
public:
	EntryListPanel
	(	wxWindow* p_parent,
		PhatbooksDatabaseConnection& p_database_connection,
		bool p_support_reconciliations = false
	);

	void update_for_new(OrdinaryJournal const& p_journal);
	void update_for_amended(OrdinaryJournal const& p_journal);
	void update_for_new(Account const& p_account);
	void update_for_amended(Account const& p_account);
	void update_for_deleted(std::vector<Entry::Id> const& p_doomed_ids);
	void selected_entries(std::vector<Entry>& out);

	// WARNING Hack... This should be private, but we need to call it from
	// TopPanel to ensure EntryListCtrl is properly sized, AFTER the
	// EntryListPanel has been constructed.
	void configure_entry_list_ctrl();

	void postconfigure_summary();

private:
	void preconfigure_summary();

	void on_refresh_button_click(wxCommandEvent& event);
	Account selected_account() const;
	boost::optional<boost::gregorian::date> selected_min_date() const;
	boost::optional<boost::gregorian::date> selected_max_date() const;

	static int const s_account_ctrl_id = wxID_HIGHEST + 1;
	static int const s_min_date_ctrl_id = s_account_ctrl_id + 1;
	static int const s_max_date_ctrl_id = s_min_date_ctrl_id + 1;
	static int const s_refresh_button_id = s_max_date_ctrl_id + 1;
	static int const s_entry_list_ctrl_id = s_refresh_button_id + 1;

	bool m_support_reconciliations;
	int m_next_row;

	int m_client_size_aux;
	int m_text_ctrl_height;

	wxGridBagSizer* m_top_sizer;
	AccountCtrl* m_account_ctrl;
	DateCtrl* m_min_date_ctrl;
	DateCtrl* m_max_date_ctrl;
	wxButton* m_refresh_button;
	EntryListCtrl* m_entry_list_ctrl;
	std::vector<wxStaticText*> m_summary_label_text_items;
	std::vector<wxStaticText*> m_summary_data_text_items;
	PhatbooksDatabaseConnection& m_database_connection;

	DECLARE_EVENT_TABLE()

};  // class EntryListPanel

}  // namespace gui
}  // namespace phatbooks

#endif  // GUARD_entry_list_panel_hpp
<|endoftext|>


<commit_before>#include "git.h"
#include <algorithm>
#include <sstream>

namespace git {

void clone(std::string const& _cwd, std::string const& _url, std::string const& _commit, std::string const& _dir) {
	utils::Process p({"git", "clone", _url, "-b", _commit, _dir}, _cwd);
	if (p.getStatus() != 0) {
		throw std::runtime_error("error running git clone");
	}
}
void pull(std::string const& _cwd) {
	utils::Process p({"git", "pull"}, _cwd);
	if (p.getStatus() != 0) {
		throw std::runtime_error("error running git pull");
	}
}
void push(std::string const& _cwd) {
	utils::Process p({"git", "push"}, _cwd);
	if (p.getStatus() != 0) {
		throw std::runtime_error("error running git push on " + _cwd);
	}
}
bool isDirty(std::string const& _cwd) {
	utils::Process p({"git", "status", "--porcelain"}, _cwd);

	if (p.cout() == "" && p.cerr() == "") {
		return false;
	}
	return true;
}
void checkout(std::string const& _cwd, std::string const& _commit) {
	utils::Process p({"git", "checkout", _commit}, _cwd);
	if (p.getStatus() != 0) {
		throw std::runtime_error("error running git checkout");
	}
}
auto getBranch(std::string const& _cwd) -> std::string {
	utils::Process p({"git", "rev-parse", "--abbrev-ref", "HEAD"}, _cwd);
	std::string branch = p.cout();
	branch.pop_back();
	return branch;
}

int untrackedFiles(std::string const& _cwd) {
	utils::Process p({"git", "status", "--porcelain"}, _cwd);
	auto const& s = p.cout();
	auto lines = utils::explode(s, "\n");
	int ct = 0;
	for (auto const& l : lines) {
		if (utils::isStartingWith(l, "?? ")) {
			ct += 1;
		}
	}
	return ct;
}

int changedFiles(std::string const& _cwd) {
	utils::Process p({"git", "status", "--porcelain"}, _cwd);
	auto const& s = p.cout();
	auto lines = utils::explode(s, "\n");
	int ct = 0;
	for (auto const& l : lines) {
		if (not utils::isStartingWith(l, "?? ")) {
			ct += 1;
		}
	}
	return ct;
}

int commitsAhead(std::string const& _cwd) {
	utils::Process p({"git", "status", "-u", "no"}, _cwd);
	auto const& s = p.cout();
	auto lines = utils::explode(s, "\n");
	auto pos = lines[1].find("up-to-date");
	if (pos != std::string::npos) {
		return 0;
	}
	auto posBy     = lines[1].rfind("by") + 3;
	auto posCommit = lines[1].rfind("commit") - 1;
	auto numberAsStr = lines[1].substr(posBy, posCommit);

	int ct = 0;
	std::stringstream ss;
	ss << numberAsStr;
	ss >> ct;
	return ct;
}

}
<commit_msg>better error messages on push/pull<commit_after>#include "git.h"
#include <algorithm>
#include <sstream>

namespace git {

void clone(std::string const& _cwd, std::string const& _url, std::string const& _commit, std::string const& _dir) {
	utils::Process p({"git", "clone", _url, "-b", _commit, _dir}, _cwd);
	if (p.getStatus() != 0) {
		throw std::runtime_error("error running git clone on " + _cwd);
	}
}
void pull(std::string const& _cwd) {
	utils::Process p({"git", "pull"}, _cwd);
	if (p.getStatus() != 0) {
		throw std::runtime_error("error running git pull on " + _cwd);
	}
}
void push(std::string const& _cwd) {
	utils::Process p({"git", "push"}, _cwd);
	if (p.getStatus() != 0) {
		throw std::runtime_error("error running git push on " + _cwd);
	}
}
bool isDirty(std::string const& _cwd) {
	utils::Process p({"git", "status", "--porcelain"}, _cwd);

	if (p.cout() == "" && p.cerr() == "") {
		return false;
	}
	return true;
}
void checkout(std::string const& _cwd, std::string const& _commit) {
	utils::Process p({"git", "checkout", _commit}, _cwd);
	if (p.getStatus() != 0) {
		throw std::runtime_error("error running git checkout on " + _cwd);
	}
}
auto getBranch(std::string const& _cwd) -> std::string {
	utils::Process p({"git", "rev-parse", "--abbrev-ref", "HEAD"}, _cwd);
	std::string branch = p.cout();
	branch.pop_back();
	return branch;
}

int untrackedFiles(std::string const& _cwd) {
	utils::Process p({"git", "status", "--porcelain"}, _cwd);
	auto const& s = p.cout();
	auto lines = utils::explode(s, "\n");
	int ct = 0;
	for (auto const& l : lines) {
		if (utils::isStartingWith(l, "?? ")) {
			ct += 1;
		}
	}
	return ct;
}

int changedFiles(std::string const& _cwd) {
	utils::Process p({"git", "status", "--porcelain"}, _cwd);
	auto const& s = p.cout();
	auto lines = utils::explode(s, "\n");
	int ct = 0;
	for (auto const& l : lines) {
		if (not utils::isStartingWith(l, "?? ")) {
			ct += 1;
		}
	}
	return ct;
}

int commitsAhead(std::string const& _cwd) {
	utils::Process p({"git", "status", "-u", "no"}, _cwd);
	auto const& s = p.cout();
	auto lines = utils::explode(s, "\n");
	auto pos = lines[1].find("up-to-date");
	if (pos != std::string::npos) {
		return 0;
	}
	auto posBy     = lines[1].rfind("by") + 3;
	auto posCommit = lines[1].rfind("commit") - 1;
	auto numberAsStr = lines[1].substr(posBy, posCommit);

	int ct = 0;
	std::stringstream ss;
	ss << numberAsStr;
	ss >> ct;
	return ct;
}

}
<|endoftext|>


<commit_before>/// \file ROOT/TWebWindowWSHandler.hxx
/// \ingroup WebGui ROOT7
/// \author Sergey Linev <s.linev@gsi.de>
/// \date 2018-08-20
/// \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback
/// is welcome!

/*************************************************************************
 * Copyright (C) 1995-2018, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#ifndef ROOT7_TWebWindowWSHandler
#define ROOT7_TWebWindowWSHandler

#include "THttpWSHandler.h"

#include <ROOT/TWebWindow.hxx>

namespace ROOT {
namespace Experimental {

/// just wrapper to deliver websockets call-backs to the TWebWindow class

class TWebWindowWSHandler : public THttpWSHandler {
public:
   TWebWindow &fWindow; ///<! window reference

   /// constructor
   TWebWindowWSHandler(TWebWindow &wind, const char *name)
      : THttpWSHandler(name, "TWebWindow websockets handler", kFALSE), fWindow(wind)
   {
   }

   virtual ~TWebWindowWSHandler() = default;

   /// returns content of default web-page
   /// THttpWSHandler interface
   virtual TString GetDefaultPageContent() override { return IsDisabled() ? "" : fWindow.fDefaultPage.c_str(); }

   /// Process websocket request - called from THttpServer thread
   /// THttpWSHandler interface
   virtual Bool_t ProcessWS(THttpCallArg *arg) override { return arg && !IsDisabled() ? fWindow.ProcessWS(*arg) : kFALSE; }

   /// Allow processing of WS actions in arbitrary thread
   virtual Bool_t AllowMTProcess() const { return fWindow.fProcessMT; }

   /// Allows usage of multithreading in send operations
   virtual Bool_t AllowMTSend() const { return fWindow.fSendMT; }

   /// React on completion of multithreaded send operaiotn
   virtual void CompleteWSSend(UInt_t wsid) { if (!IsDisabled()) fWindow.CompleteWSSend(wsid); }
};

} // namespace Experimental
} // namespace ROOT

#endif
<commit_msg>webgui: use override and remove virtual keywords<commit_after>/// \file ROOT/TWebWindowWSHandler.hxx
/// \ingroup WebGui ROOT7
/// \author Sergey Linev <s.linev@gsi.de>
/// \date 2018-08-20
/// \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback
/// is welcome!

/*************************************************************************
 * Copyright (C) 1995-2018, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#ifndef ROOT7_TWebWindowWSHandler
#define ROOT7_TWebWindowWSHandler

#include "THttpWSHandler.h"

#include <ROOT/TWebWindow.hxx>

namespace ROOT {
namespace Experimental {

/// just wrapper to deliver websockets call-backs to the TWebWindow class

class TWebWindowWSHandler : public THttpWSHandler {
public:
   TWebWindow &fWindow; ///<! window reference

   /// constructor
   TWebWindowWSHandler(TWebWindow &wind, const char *name)
      : THttpWSHandler(name, "TWebWindow websockets handler", kFALSE), fWindow(wind)
   {
   }

   virtual ~TWebWindowWSHandler() = default;

   /// returns content of default web-page
   /// THttpWSHandler interface
   TString GetDefaultPageContent() override { return IsDisabled() ? "" : fWindow.fDefaultPage.c_str(); }

   /// Process websocket request - called from THttpServer thread
   /// THttpWSHandler interface
   Bool_t ProcessWS(THttpCallArg *arg) override { return arg && !IsDisabled() ? fWindow.ProcessWS(*arg) : kFALSE; }

   /// Allow processing of WS actions in arbitrary thread
   Bool_t AllowMTProcess() const override { return fWindow.fProcessMT; }

   /// Allows usage of special threads for send operations
   Bool_t AllowMTSend() const override { return fWindow.fSendMT; }

   /// React on completion of multithreaded send operation
   void CompleteWSSend(UInt_t wsid) override { if (!IsDisabled()) fWindow.CompleteWSSend(wsid); }
};

} // namespace Experimental
} // namespace ROOT

#endif
<|endoftext|>


<commit_before>#include <cmath>

#include "TChain.h"
#include "TH1D.h"

#include "CLITools.hxx"

std::string InputFileDescriptor = "";

template<typename TH>
TH* ToPDF(const TH *hraw){

  const Double_t EPSILON = 1e-12;
  const Int_t x0 = 0;
  const Int_t x1 = hraw->GetNbinsX()+1;
  const Double_t Integral = hraw->Integral(x0, x1);

  TH * hist = (TH*)hraw->Clone((std::string(hraw->GetName())+"pdf").c_str());
  hist->Scale(0);

  for(Int_t ib = x0; ib <= x1; ib++){
    const Double_t BinWidth = hraw->GetBinWidth(ib);
    const Double_t BinContent = hraw->GetBinContent(ib);

    //in case of finit number of bins (i.e. eff not always small),
    //Binomial error is more accurate than Poisson error
    const Double_t Scaled = BinContent/Integral;
    const Double_t PDF = Scaled/BinWidth;

    const Double_t PDFErr = sqrt(Scaled*(1-Scaled)/Integral) / BinWidth;
    hist->SetBinContent(ib, PDF);
    hist->SetBinError(ib, PDFErr);
  }

  hist->SetEntries(Integral);

  return hist;
}

void SetOpts(){

  CLIArgs::AddOpt("-i", "--input", true,
    [&] (std::string const &opt) -> bool {
      InputFileDescriptor = opt;
      return true;
    }, true,
    [](){},
    "File to read input tree from.");
}

int main(int argc, char const * argv[]){

  try {
    SetOpts();
  } catch (std::exception const & e){
    std::cerr << "[ERROR]: " << e.what() << std::endl;
    return 1;
  }

  CLIArgs::AddArguments(argc,argv);
  if(!CLIArgs::HandleArgs()){
    CLIArgs::SayRunLike();
    return 1;
  }

  TChain *TRAPChain = new TChain("TransversitudenessPureSim");
  TRAPChain->Add(InputFileDescriptor.c_str());

  Double_t N_QE = TRAPChain->GetEntries("(TransV.NeutConventionReactionCode==1)&&(TransV.Muon_PDG==13)&&(TransV.HMProton_PDG==2212)");
  Double_t N_QE_DP = TRAPChain->GetEntries("(TransV.DeltaPTotal_HMProton_MeV.Vect().Mag()>10)&&(TransV.NeutConventionReactionCode==1)&&(TransV.Muon_PDG==13)&&(TransV.HMProton_PDG==2212)");

  Double_t N_RES = TRAPChain->GetEntries("(TransV.NeutConventionReactionCode==11)&&(TransV.Muon_PDG==13)&&(TransV.HMProton_PDG==2212)&&(TransV.HMCPion_PDG==211)");
  Double_t N_RES_DP = TRAPChain->GetEntries("(TransV.DeltaPTotal_HMProtonPion_MeV.Vect().Mag()>10)&&(TransV.NeutConventionReactionCode==11)&&(TransV.Muon_PDG==13)&&(TransV.HMProton_PDG==2212)&&(TransV.HMCPion_PDG==211)");

  std::cout << "In File: " << InputFileDescriptor << std::endl;
  std::cout << "Taus:" << std::endl;
  std::cout << "\tQE: " << (N_QE_DP/N_QE) << " = (" << N_QE_DP << "/" << N_QE << ")" << std::endl;
  std::cout << "\tRES: " << (N_RES_DP/N_RES) << " = (" << N_RES_DP << "/" << N_RES << ")" << std::endl;

  TH1D* QE_NE = new TH1D("QE_NE","",100,0,100);
  TH1D* QE = new TH1D("QE","",100,0,100);

  TRAPChain->Draw("(-1.0*(TransV.DeltaPTotal_HMProton_MeV.E()+32)) >> QE_NE","(TransV.NeutConventionReactionCode==1)&&(TransV.Muon_PDG==13)&&(TransV.HMProton_PDG==2212)&&(TransV.NFinalStateParticles!=2)");
  TRAPChain->Draw("(-1.0*(TransV.DeltaPTotal_HMProton_MeV.E()+32)) >> QE","(TransV.NeutConventionReactionCode==1)&&(TransV.Muon_PDG==13)&&(TransV.HMProton_PDG==2212)");

  TH1D* QEEtaDeltaE = ToPDF(QE);

  Double_t integral_QE = 0;
  for(Int_t i = 0; i < QE->GetNbinsX()+1; ++i){
    integral_QE = QE->GetBinWidth(i) * QE->GetBinCenter(i) * QEEtaDeltaE->GetBinContent(i) * (1.0 - (QE_NE->GetBinContent(i)/QE->GetBinContent(i)) );
  }
  integral_QE *= (N_QE_DP/N_QE);

  std::cout << "<E_invis^QE> = " << integral_QE << " MeV" << std::endl;

  TH1D* RES_NE = new TH1D("RES_NE","",100,0,100);
  TH1D* RES = new TH1D("RES","",100,0,100);

  TRAPChain->Draw("(-1.0*(TransV.DeltaPTotal_HMProton_MeV.E()+32)) >> RES_NE","(TransV.NeutConventionReactionCode==1)&&(TransV.Muon_PDG==13)&&(TransV.HMProton_PDG==2212)&&(TransV.NFinalStateParticles!=2)");
  TRAPChain->Draw("(-1.0*(TransV.DeltaPTotal_HMProton_MeV.E()+32)) >> RES","(TransV.NeutConventionReactionCode==1)&&(TransV.Muon_PDG==13)&&(TransV.HMProton_PDG==2212)");

  TH1D* RESEtaDeltaE = ToPDF(RES);

  Double_t integral_RES = 0;
  for(Int_t i = 0; i < RES->GetNbinsX()+1; ++i){
    integral_RES = RES->GetBinWidth(i) * RES->GetBinCenter(i) * RESEtaDeltaE->GetBinContent(i) * (1.0 - (RES_NE->GetBinContent(i)/RES->GetBinContent(i)) );
  }
  integral_RES *= (N_RES_DP/N_RES);

  std::cout << "<E_invis^RES> = " << integral_RES << " MeV" << std::endl;

  delete TRAPChain;
  delete QE_NE;
  delete QE;
  delete QEEtaDeltaE;
  delete RES_NE;
  delete RES;
  delete RESEtaDeltaE;
  return 0;
}
<commit_msg>Fixes failure to do basic maths in EInvisCalc.cxx<commit_after>#include <cmath>
#include <iomanip>

#include "TChain.h"
#include "TH1D.h"

#include "CLITools.hxx"

std::string InputFileDescriptor = "";

template<typename TH>
TH* ToPDF(const TH *hraw){

  const Double_t EPSILON = 1e-12;
  const Int_t x0 = 0;
  const Int_t x1 = hraw->GetNbinsX()+1;
  const Double_t Integral = hraw->Integral(x0, x1);

  TH * hist = (TH*)hraw->Clone((std::string(hraw->GetName())+"pdf").c_str());
  hist->Scale(0);

  for(Int_t ib = x0; ib <= x1; ib++){
    const Double_t BinWidth = hraw->GetBinWidth(ib);
    const Double_t BinContent = hraw->GetBinContent(ib);

    //in case of finit number of bins (i.e. eff not always small),
    //Binomial error is more accurate than Poisson error
    const Double_t Scaled = BinContent/Integral;
    const Double_t PDF = Scaled/BinWidth;

    const Double_t PDFErr = sqrt(Scaled*(1-Scaled)/Integral) / BinWidth;
    hist->SetBinContent(ib, PDF);
    hist->SetBinError(ib, PDFErr);
  }

  hist->SetEntries(Integral);

  return hist;
}

void SetOpts(){

  CLIArgs::AddOpt("-i", "--input", true,
    [&] (std::string const &opt) -> bool {
      InputFileDescriptor = opt;
      return true;
    }, true,
    [](){},
    "File to read input tree from.");
}

int main(int argc, char const * argv[]){

  try {
    SetOpts();
  } catch (std::exception const & e){
    std::cerr << "[ERROR]: " << e.what() << std::endl;
    return 1;
  }

  CLIArgs::AddArguments(argc,argv);
  if(!CLIArgs::HandleArgs()){
    CLIArgs::SayRunLike();
    return 1;
  }

  TChain *TRAPChain = new TChain("TransversitudenessPureSim");
  TRAPChain->Add(InputFileDescriptor.c_str());

  Double_t N_QE = TRAPChain->GetEntries("(TransV.NeutConventionReactionCode==1)&&(TransV.Muon_PDG==13)&&(TransV.HMProton_PDG==2212)");
  Double_t N_QE_DP = TRAPChain->GetEntries("(TransV.DeltaPTotal_HMProton_MeV.Vect().Mag()>10)&&(TransV.NeutConventionReactionCode==1)&&(TransV.Muon_PDG==13)&&(TransV.HMProton_PDG==2212)");

  Double_t N_RES = TRAPChain->GetEntries("(TransV.NeutConventionReactionCode==11)&&(TransV.Muon_PDG==13)&&(TransV.HMProton_PDG==2212)&&(TransV.HMCPion_PDG==211)");
  Double_t N_RES_DP = TRAPChain->GetEntries("(TransV.DeltaPTotal_HMProtonPion_MeV.Vect().Mag()>10)&&(TransV.NeutConventionReactionCode==11)&&(TransV.Muon_PDG==13)&&(TransV.HMProton_PDG==2212)&&(TransV.HMCPion_PDG==211)");

  std::cout << "In File: " << InputFileDescriptor << std::endl;
  std::cout << "Taus:" << std::endl;
  std::cout << "\tQE: " << (N_QE_DP/N_QE) << " = (" << N_QE_DP << "/" << N_QE << ")" << std::endl;
  std::cout << "\tRES: " << (N_RES_DP/N_RES) << " = (" << N_RES_DP << "/" << N_RES << ")" << std::endl;

  TH1D* QE_NE = new TH1D("QE_NE","",100,0,100);
  TH1D* QE = new TH1D("QE","",100,0,100);

  TRAPChain->Draw("(-1.0*(TransV.DeltaPTotal_HMProton_MeV.E()+32)) >> QE_NE","(TransV.NeutConventionReactionCode==1)&&(TransV.Muon_PDG==13)&&(TransV.HMProton_PDG==2212)&&(TransV.NFinalStateParticles!=2)");
  TRAPChain->Draw("(-1.0*(TransV.DeltaPTotal_HMProton_MeV.E()+32)) >> QE","(TransV.NeutConventionReactionCode==1)&&(TransV.Muon_PDG==13)&&(TransV.HMProton_PDG==2212)");

  TH1D* QEEtaDeltaE = ToPDF(QE);

  Double_t integral_QE = 0;
  for(Int_t i = 1; i < QE->GetNbinsX()+1; ++i){
    std::cout << "[" << std::setw(3) << i << "] BW: "
      << QE->GetBinWidth(i) << ", DeltaE: " << QE->GetBinCenter(i)
      << ", eta(DE): " << QEEtaDeltaE->GetBinContent(i)
      << ", [1-P(DE)]: "
      << (1.0 - (QE_NE->GetBinContent(i)/QE->GetBinContent(i)) ) << std::endl;
    integral_QE += QE->GetBinWidth(i) * QE->GetBinCenter(i) * QEEtaDeltaE->GetBinContent(i) * (1.0 - (QE_NE->GetBinContent(i)/QE->GetBinContent(i)) );
    std::cout << "\\int_{" << QE->GetBinLowEdge(1) << "}^{" << (QE->GetBinLowEdge(i)+QE->GetBinWidth(i)) << "} = " << integral_QE << std::endl;
  }
  integral_QE *= (N_QE_DP/N_QE);

  std::cout << "<E_invis^QE> = " << integral_QE << " MeV" << std::endl;

  TH1D* RES_NE = new TH1D("RES_NE","",100,0,100);
  TH1D* RES = new TH1D("RES","",100,0,100);

  TRAPChain->Draw("(-1.0*(TransV.DeltaPTotal_HMProton_MeV.E()+32)) >> RES_NE","(TransV.NeutConventionReactionCode==1)&&(TransV.Muon_PDG==13)&&(TransV.HMProton_PDG==2212)&&(TransV.NFinalStateParticles!=2)");
  TRAPChain->Draw("(-1.0*(TransV.DeltaPTotal_HMProton_MeV.E()+32)) >> RES","(TransV.NeutConventionReactionCode==1)&&(TransV.Muon_PDG==13)&&(TransV.HMProton_PDG==2212)");

  TH1D* RESEtaDeltaE = ToPDF(RES);

  Double_t integral_RES = 0;
  for(Int_t i = 1; i < RES->GetNbinsX()+1; ++i){
    integral_RES += RES->GetBinWidth(i) * RES->GetBinCenter(i) * RESEtaDeltaE->GetBinContent(i) * (1.0 - (RES_NE->GetBinContent(i)/RES->GetBinContent(i)) );
  }
  integral_RES *= (N_RES_DP/N_RES);

  std::cout << "<E_invis^RES> = " << integral_RES << " MeV" << std::endl;

  delete TRAPChain;
  delete QE_NE;
  delete QE;
  delete QEEtaDeltaE;
  delete RES_NE;
  delete RES;
  delete RESEtaDeltaE;
  return 0;
}
<|endoftext|>


<commit_before>/* Copyright (C) 2012-2017 IBM Corp.
 * This program is Licensed under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *   http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License. See accompanying LICENSE file.
 */
namespace std {} using namespace std;
namespace NTL {} using namespace NTL;

#include <NTL/BasicThreadPool.h>

#include "EvalMap.h"
#include "hypercube.h"
#include "powerful.h"

static bool dry = false; // a dry-run flag
static bool noPrint = false;

void  TestIt(long p, long r, long c, long _k, long w,
             long L, const Vec<long>& mvec,
             const Vec<long>& gens, const Vec<long>& ords, long useCache)
{
  if (!noPrint)
    cout << "*** TestIt"
       << (dry? " (dry run):" : ":")
       << " p=" << p
       << ", r=" << r
       << ", c=" << c
       << ", k=" << _k
       << ", w=" << w
       << ", L=" << L
       << ", mvec=" << mvec << ", "
       << ", useCache = " << useCache
       << endl;

  setTimersOn();
  setDryRun(false); // Need to get a "real context" to test EvalMap

  // mvec is supposed to include the prime-power factorization of m
  long nfactors = mvec.length();
  for (long i = 0; i < nfactors; i++)
    for (long j = i+1; j < nfactors; j++)
      assert(GCD(mvec[i], mvec[j]) == 1);

  // multiply all the prime powers to get m itself
  long m = computeProd(mvec);
  assert(GCD(p, m) == 1);

  // build a context with these generators and orders
  vector<long> gens1, ords1;
  convert(gens1, gens);
  convert(ords1, ords);
  FHEcontext context(m, p, r, gens1, ords1);
  buildModChain(context, L, c);

  if (!noPrint) {
    context.zMStar.printout(); // print structure of Zm* /(p) to cout
    cout << endl;
  }
  long d = context.zMStar.getOrdP();
  long phim = context.zMStar.getPhiM();
  long nslots = phim/d;

  setDryRun(dry); // Now we can set the dry-run flag if desired

  FHESecKey secretKey(context);
  const FHEPubKey& publicKey = secretKey;
  secretKey.GenSecKey(w); // A Hamming-weight-w secret key
  addSome1DMatrices(secretKey); // compute key-switching matrices that we need
  addFrbMatrices(secretKey); // compute key-switching matrices that we need

  // GG defines the plaintext space Z_p[X]/GG(X)
  ZZX GG;
  GG = context.alMod.getFactorsOverZZ()[0];
  EncryptedArray ea(context, GG);

  zz_p::init(context.alMod.getPPowR());
  zz_pX F;
  random(F, phim); // a random polynomial of degree phi(m)-1 modulo p

  // convert F to powerful representation: cube represents a multi-variate
  // polynomial with as many variables Xi as factors mi in mvec. cube has
  // degree phi(mi) in the variable Xi, and the coefficients are given
  // in lexicographic order.

  // compute tables for converting between powerful and zz_pX
  PowerfulTranslationIndexes ind(mvec); // indpendent of p
  PowerfulConversion pConv(ind);        // depends on p

  HyperCube<zz_p> cube(pConv.getShortSig());
  pConv.polyToPowerful(cube, F);

  // Sanity check: convert back and compare
  zz_pX F2;
  pConv.powerfulToPoly(F2, cube);
  if (F != F2) cout << " @@@ conversion error ):\n";

  // pack the coefficients from cube in the plaintext slots: the j'th
  // slot contains the polynomial pj(X) = \sum_{t=0}^{d-1} cube[jd+t] X^t
  vector<ZZX> val1;
  val1.resize(nslots);
  for (long i = 0; i < phim; i++) {
    val1[i/d] += conv<ZZX>(conv<ZZ>(cube[i])) << (i % d);
  }
  NewPlaintextArray pa1(ea);
  encode(ea, pa1, val1);

  Ctxt ctxt(publicKey);
  ea.encrypt(ctxt, publicKey, pa1);

  resetAllTimers();
  FHE_NTIMER_START(ALL);

  // Compute homomorphically the transformation that takes the
  // coefficients packed in the slots and produces the polynomial
  // corresponding to cube

  if (!noPrint) CheckCtxt(ctxt, "init");

  if (!noPrint) cout << "build EvalMap\n";
  EvalMap map(ea, /*minimal=*/false, mvec,
    /*invert=*/false, /*build_cache=*/false, /*normal_basis=*/false);
  // compute the transformation to apply

  if (!noPrint) cout << "apply EvalMap\n";
  if (useCache) map.upgrade();
  map.apply(ctxt); // apply the transformation to ctxt
  if (!noPrint) CheckCtxt(ctxt, "EvalMap");
  if (!noPrint) cout << "check results\n";

  ZZX FF1;
  secretKey.Decrypt(FF1, ctxt);
  zz_pX F1 = conv<zz_pX>(FF1);

  if (F1 == F)
    cout << "EvalMap: GOOD\n";
  else
    cout << "EvalMap: BAD\n";

  publicKey.Encrypt(ctxt, FF1);
  if (!noPrint) CheckCtxt(ctxt, "init");

  // Compute homomorphically the inverse transformation that takes the
  // polynomial corresponding to cube and produces the coefficients
  // packed in the slots

  if (!noPrint) cout << "build EvalMap\n";
  EvalMap imap(ea, /*minimal=*/false, mvec,
    /*invert=*/true, /*build_cache=*/false, /*normal_basis=*/false);
  // compute the transformation to apply
  if (!noPrint) cout << "apply EvalMap\n";
  if (useCache) imap.upgrade();
  imap.apply(ctxt); // apply the transformation to ctxt
  if (!noPrint) {
    CheckCtxt(ctxt, "EvalMap");
    cout << "check results\n";
  }
  NewPlaintextArray pa2(ea);
  ea.decrypt(ctxt, secretKey, pa2);

  if (equals(ea, pa1, pa2))
    cout << "EvalMap: GOOD\n";
  else
    cout << "EvalMap: BAD\n";
  FHE_NTIMER_STOP(ALL);

  if (!noPrint) {
    cout << "\n*********\n";
    printAllTimers();
    cout << endl;
  }
}

/* Usage: Test_EvalMap_x.exe [ name=value ]...
 *  p       plaintext base  [ default=2 ]
 *  r       lifting  [ default=1 ]
 *  c       number of columns in the key-switching matrices  [ default=2 ]
 *  k       security parameter  [ default=80 ]
 *  L       # of levels in the modulus chain  [ default=6 ]
 *  s       minimum number of slots  [ default=0 ]
 *  seed    PRG seed  [ default=0 ]
 *  mvec    use specified factorization of m
 *             e.g., mvec='[5 3 187]'
 *  gens    use specified vector of generators
 *             e.g., gens='[562 1871 751]'
 *  ords    use specified vector of orders
 *             e.g., ords='[4 2 -4]', negative means 'bad'
 */
int main(int argc, char *argv[])
{
  ArgMapping amap;

  long p=2;
  amap.arg("p", p, "plaintext base");

  long r=1;
  amap.arg("r", r,  "lifting");

  long c=2;
  amap.arg("c", c, "number of columns in the key-switching matrices");

  long k=80;
  amap.arg("k", k, "security parameter");

  long L=6;
  amap.arg("L", L, "# of levels in the modulus chain");

  long s=0;
  amap.arg("s", s, "minimum number of slots");

  long seed=0;
  amap.arg("seed", seed, "PRG seed");

  Vec<long> mvec;
  amap.arg("mvec", mvec, "use specified factorization of m", NULL);
  amap.note("e.g., mvec='[5 3 187]'");

  Vec<long> gens;
  amap.arg("gens", gens, "use specified vector of generators", NULL);
  amap.note("e.g., gens='[562 1871 751]'");

  Vec<long> ords;
  amap.arg("ords", ords, "use specified vector of orders", NULL);
  amap.note("e.g., ords='[4 2 -4]', negative means 'bad'");

  amap.arg("dry", dry, "a dry-run flag to check the noise");

  long nthreads=1;
  amap.arg("nthreads", nthreads, "number of threads");

  amap.arg("noPrint", noPrint, "suppress printouts");

  long useCache=0;
  amap.arg("useCache", useCache, "0: zzX cache, 2: DCRT cache");

  amap.parse(argc, argv);

  SetNumThreads(nthreads);

  SetSeed(conv<ZZ>(seed));
  TestIt(p, r, c, k, /*Key Hamming weight=*/64, L, mvec, gens, ords, useCache);
}

// ./Test_EvalMap_x mvec="[73 433]" gens="[18620 12995]" ords="[72 -6]"
<commit_msg>added default values for mvec,gens,ords to Test_EvalMap<commit_after>/* Copyright (C) 2012-2017 IBM Corp.
 * This program is Licensed under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *   http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License. See accompanying LICENSE file.
 */
namespace std {} using namespace std;
namespace NTL {} using namespace NTL;

#include <NTL/BasicThreadPool.h>

#include "EvalMap.h"
#include "hypercube.h"
#include "powerful.h"

static bool dry = false; // a dry-run flag
static bool noPrint = false;

void  TestIt(long p, long r, long c, long _k, long w,
             long L, Vec<long>& mvec,
             Vec<long>& gens, Vec<long>& ords, long useCache)
{
  if (lsize(mvec)<1) { // use default values
    mvec.SetLength(3); gens.SetLength(3); ords.SetLength(3);
    mvec[0] = 7;    mvec[1] = 3;    mvec[2] = 221;
    gens[0] = 3979; gens[1] = 3095; gens[2] = 3760;
    ords[0] = 6;    ords[1] = 2;    ords[2] = -8;
  }
  if (!noPrint)
    cout << "*** TestIt"
       << (dry? " (dry run):" : ":")
       << " p=" << p
       << ", r=" << r
       << ", c=" << c
       << ", k=" << _k
       << ", w=" << w
       << ", L=" << L
       << ", mvec=" << mvec << ", "
       << ", useCache = " << useCache
       << endl;

  setTimersOn();
  setDryRun(false); // Need to get a "real context" to test EvalMap

  // mvec is supposed to include the prime-power factorization of m
  long nfactors = mvec.length();
  for (long i = 0; i < nfactors; i++)
    for (long j = i+1; j < nfactors; j++)
      assert(GCD(mvec[i], mvec[j]) == 1);

  // multiply all the prime powers to get m itself
  long m = computeProd(mvec);
  assert(GCD(p, m) == 1);

  // build a context with these generators and orders
  vector<long> gens1, ords1;
  convert(gens1, gens);
  convert(ords1, ords);
  FHEcontext context(m, p, r, gens1, ords1);
  buildModChain(context, L, c);

  if (!noPrint) {
    context.zMStar.printout(); // print structure of Zm* /(p) to cout
    cout << endl;
  }
  long d = context.zMStar.getOrdP();
  long phim = context.zMStar.getPhiM();
  long nslots = phim/d;

  setDryRun(dry); // Now we can set the dry-run flag if desired

  FHESecKey secretKey(context);
  const FHEPubKey& publicKey = secretKey;
  secretKey.GenSecKey(w); // A Hamming-weight-w secret key
  addSome1DMatrices(secretKey); // compute key-switching matrices that we need
  addFrbMatrices(secretKey); // compute key-switching matrices that we need

  // GG defines the plaintext space Z_p[X]/GG(X)
  ZZX GG;
  GG = context.alMod.getFactorsOverZZ()[0];
  EncryptedArray ea(context, GG);

  zz_p::init(context.alMod.getPPowR());
  zz_pX F;
  random(F, phim); // a random polynomial of degree phi(m)-1 modulo p

  // convert F to powerful representation: cube represents a multi-variate
  // polynomial with as many variables Xi as factors mi in mvec. cube has
  // degree phi(mi) in the variable Xi, and the coefficients are given
  // in lexicographic order.

  // compute tables for converting between powerful and zz_pX
  PowerfulTranslationIndexes ind(mvec); // indpendent of p
  PowerfulConversion pConv(ind);        // depends on p

  HyperCube<zz_p> cube(pConv.getShortSig());
  pConv.polyToPowerful(cube, F);

  // Sanity check: convert back and compare
  zz_pX F2;
  pConv.powerfulToPoly(F2, cube);
  if (F != F2) cout << " @@@ conversion error ):\n";

  // pack the coefficients from cube in the plaintext slots: the j'th
  // slot contains the polynomial pj(X) = \sum_{t=0}^{d-1} cube[jd+t] X^t
  vector<ZZX> val1;
  val1.resize(nslots);
  for (long i = 0; i < phim; i++) {
    val1[i/d] += conv<ZZX>(conv<ZZ>(cube[i])) << (i % d);
  }
  NewPlaintextArray pa1(ea);
  encode(ea, pa1, val1);

  Ctxt ctxt(publicKey);
  ea.encrypt(ctxt, publicKey, pa1);

  resetAllTimers();
  FHE_NTIMER_START(ALL);

  // Compute homomorphically the transformation that takes the
  // coefficients packed in the slots and produces the polynomial
  // corresponding to cube

  if (!noPrint) CheckCtxt(ctxt, "init");

  if (!noPrint) cout << "build EvalMap\n";
  EvalMap map(ea, /*minimal=*/false, mvec,
    /*invert=*/false, /*build_cache=*/false, /*normal_basis=*/false);
  // compute the transformation to apply

  if (!noPrint) cout << "apply EvalMap\n";
  if (useCache) map.upgrade();
  map.apply(ctxt); // apply the transformation to ctxt
  if (!noPrint) CheckCtxt(ctxt, "EvalMap");
  if (!noPrint) cout << "check results\n";

  ZZX FF1;
  secretKey.Decrypt(FF1, ctxt);
  zz_pX F1 = conv<zz_pX>(FF1);

  if (F1 == F)
    cout << "EvalMap: GOOD\n";
  else
    cout << "EvalMap: BAD\n";

  publicKey.Encrypt(ctxt, FF1);
  if (!noPrint) CheckCtxt(ctxt, "init");

  // Compute homomorphically the inverse transformation that takes the
  // polynomial corresponding to cube and produces the coefficients
  // packed in the slots

  if (!noPrint) cout << "build EvalMap\n";
  EvalMap imap(ea, /*minimal=*/false, mvec,
    /*invert=*/true, /*build_cache=*/false, /*normal_basis=*/false);
  // compute the transformation to apply
  if (!noPrint) cout << "apply EvalMap\n";
  if (useCache) imap.upgrade();
  imap.apply(ctxt); // apply the transformation to ctxt
  if (!noPrint) {
    CheckCtxt(ctxt, "EvalMap");
    cout << "check results\n";
  }
  NewPlaintextArray pa2(ea);
  ea.decrypt(ctxt, secretKey, pa2);

  if (equals(ea, pa1, pa2))
    cout << "EvalMap: GOOD\n";
  else
    cout << "EvalMap: BAD\n";
  FHE_NTIMER_STOP(ALL);

  if (!noPrint) {
    cout << "\n*********\n";
    printAllTimers();
    cout << endl;
  }
}

/* Usage: Test_EvalMap_x.exe [ name=value ]...
 *  p       plaintext base  [ default=2 ]
 *  r       lifting  [ default=1 ]
 *  c       number of columns in the key-switching matrices  [ default=2 ]
 *  k       security parameter  [ default=80 ]
 *  L       # of levels in the modulus chain  [ default=6 ]
 *  s       minimum number of slots  [ default=0 ]
 *  seed    PRG seed  [ default=0 ]
 *  mvec    use specified factorization of m
 *             e.g., mvec='[5 3 187]'
 *  gens    use specified vector of generators
 *             e.g., gens='[562 1871 751]'
 *  ords    use specified vector of orders
 *             e.g., ords='[4 2 -4]', negative means 'bad'
 */
int main(int argc, char *argv[])
{
  ArgMapping amap;

  long p=2;
  amap.arg("p", p, "plaintext base");

  long r=1;
  amap.arg("r", r,  "lifting");

  long c=2;
  amap.arg("c", c, "number of columns in the key-switching matrices");

  long k=80;
  amap.arg("k", k, "security parameter");

  long L=6;
  amap.arg("L", L, "# of levels in the modulus chain");

  long s=0;
  amap.arg("s", s, "minimum number of slots");

  long seed=0;
  amap.arg("seed", seed, "PRG seed");

  Vec<long> mvec;
  amap.arg("mvec", mvec, "use specified factorization of m", NULL);
  amap.note("e.g., mvec='[7 3 221]'");

  Vec<long> gens;
  amap.arg("gens", gens, "use specified vector of generators", NULL);
  amap.note("e.g., gens='[3979 3095 3760]'");

  Vec<long> ords;
  amap.arg("ords", ords, "use specified vector of orders", NULL);
  amap.note("e.g., ords='[6 2 -8]', negative means 'bad'");

  amap.arg("dry", dry, "a dry-run flag to check the noise");

  long nthreads=1;
  amap.arg("nthreads", nthreads, "number of threads");

  amap.arg("noPrint", noPrint, "suppress printouts");

  long useCache=0;
  amap.arg("useCache", useCache, "0: zzX cache, 2: DCRT cache");

  amap.parse(argc, argv);

  SetNumThreads(nthreads);

  SetSeed(conv<ZZ>(seed));
  TestIt(p, r, c, k, /*Key Hamming weight=*/64, L, mvec, gens, ords, useCache);
}

// ./Test_EvalMap_x mvec="[73 433]" gens="[18620 12995]" ords="[72 -6]"
<|endoftext|>