<commit_before>/* -*- mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
// vim:sts=4:sw=4:ts=4:noet:sr:cino=>s,f0,{0,g0,(0,\:0,t0,+0,=s

/*
 * Copyright (C) FFLAS-FFPACK
 * Written by David Lucas
 * This file is Free Software and part of FFLAS-FFPACK.
 *
 * ========LICENCE========
 * This file is part of the library FFLAS-FFPACK.
 *
 * FFLAS-FFPACK is free software: you can redistribute it and/or modify
 * it under the terms of the  GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 * ========LICENCE========
 *.
 */

//--------------------------------------------------------------------------
//                        Test for minpoly
//
//--------------------------------------------------------------------------
// David Lucas
//-------------------------------------------------------------------------

#include <iomanip>
#include <iostream>

#include "fflas-ffpack/fflas-ffpack-config.h"
#include "fflas-ffpack/fflas/fflas.h"
#include "fflas-ffpack/ffpack/ffpack.h"
#include "fflas-ffpack/utils/args-parser.h"
#include "fflas-ffpack/utils/fflas_randommatrix.h"
#include "test-utils.h"
#include <givaro/modular.h>
#include <givaro/modular-balanced.h>
#include <givaro/modular-integer.h>
#include <givaro/givpoly1factor.h>
#include <givaro/givpoly1.h>

using namespace std;
using namespace FFPACK;
using Givaro::Modular;
using Givaro::ModularBalanced;

typedef Givaro::ModularBalanced<double> Field;
typedef vector<Field::Element> Polynomial;

/* Computes P(A)*V and stores it in E using Horner's scheme for
 * polynomial evaluation. */
template<typename Field, typename Element>
void horner_matrix_vector(const Field &F, size_t n, Element *A, size_t lda, Element *V,
						  Element *E, Polynomial P)
{

	//TODO: Quite a few copies. Could be improved.
	//TODO: Add incV and incE
	size_t deg = P.size() - 1;
	Element *E_tmp;
	E_tmp = FFLAS::fflas_new(F, 1, n);

	FFLAS::fassign(F, n, V, 1, E, 1);
	FFLAS::fscalin(F, n, P[deg], E, 1); // E <- P[deg+1] * V

    for(long i = deg; i > 0; --i)
    {
		FFLAS::fassign(F, n, E, 1, E_tmp, 1); //E_tmp <- E
		FFLAS::fgemv(F, FFLAS::FflasNoTrans, n, n, F.one, A, lda, E_tmp, 1, F.zero, E, 1);//E <- A * E_tmp
		FFLAS::faxpy(F, 1, n, P[i-1], V, 1, E, 1); //E <- minP[i-1] * V + E
    }
	FFLAS::fflas_delete(E_tmp);
}

template<typename Field, class RandIter>
bool check_minpoly(const Field &F, size_t n, RandIter& G)
{
	cout<<"Entering check_minpoly"<<endl;
	typedef typename Field::Element Element;
	typedef typename Field::Element_ptr Element_ptr;
	size_t lda, ldv;
	Element *A, *V, *Vcst;

	//Default
	lda = n;
	ldv = n;

	/*Create variables used for testing (matrices, vectors and polynomials) */

    A = FFLAS::fflas_new(F, n, n);
    V = FFLAS::fflas_new(F, n+1, n);
	Vcst = FFLAS::fflas_new(F, 1, n);
    Polynomial minP;

    FFPACK::RandomMatrix (F, n, n, A, lda, G);

	FFPACK::NonZeroRandomMatrix(F, 1, n, V, n, G);
	FFLAS::fassign(F, n, V, 1, Vcst, 1); //MatVecMinPoly modifies V, we store it in Vcst beforehand

	FFPACK::MatVecMinPoly(F, minP, n, A, lda, V, ldv);
	FFLAS::fflas_delete(V);
	write_field(F,std::cerr<<"V="<<std::endl,Vcst,n,1,1);

	/*Check that minP is monic*/

	size_t deg = minP.size() - 1;
	if(!(minP[deg]==F.one))
		return false;

	/*Check that minP(A).V is zero*/

	Element_ptr E = FFLAS::fflas_new(F, 1, n);

	horner_matrix_vector(F, n, A, lda, Vcst, E, minP);

    if (!FFLAS::fiszero(F, n, E, 1))
	{
		cout<<"NONZEROERROR"<<endl;
		FFLAS::fflas_delete(E);
		return false;
	}

	FFLAS::fflas_delete(E);

	/* Check minimality of minP */

	// Krylov matrix computation
	Element_ptr K;
	size_t ldk = n;
	K = FFLAS::fflas_new(F, deg+1, ldk);
	FFLAS::fassign(F, n, Vcst, 1, K, 1);
	Element *Kptr = K;

	for(size_t i = 0; i < deg; ++i, Kptr += ldk)
		FFLAS::fgemv(F, FFLAS::FflasNoTrans, n, n, F.one, A, lda, Kptr, 1, F.zero, Kptr+ldk, 1);

	// minP factorization
	typedef Givaro::Poly1FactorDom<Field, Givaro::Dense> PolyDom; //defines a polynomial domain for Givaro
	typedef typename PolyDom::Element FieldPoly; //defines an element over this polynomial domain (casting purposes)
	vector<FieldPoly> factors;
	vector<uint64_t> powers;

	PolyDom PD(F);
	FieldPoly FP_minP = FieldPoly(minP.begin(), minP.end());
	PD.factor(factors, powers, FP_minP);

	cout<<minP<<endl;
	cout<<factors<<endl;
	cout<<powers<<endl;

	//cout<<res<<endl;

	// Factorized minP checks

	FieldPoly res;
	size_t nb_factors = factors.size();
	for(size_t i = 0; i < nb_factors; ++i)
	{
		Element_ptr E_min = FFLAS::fflas_new(F, 1, n);
		PD.div(res, FP_minP, factors[i]);
		//use Krylov matrix fgemv instead!
		horner_matrix_vector(F, n, A, lda, Vcst, E_min, res);
		write_field(F,std::cerr<<"V="<<std::endl,Vcst,n,1,1);
		if(FFLAS::fiszero(F, n, E_min, 1))
		{
			cout<<"Iter "<<i<<endl;
			cout<<"factors[i] "<<factors[i]<<endl;
			cout<<"res "<<res<<endl;
			write_field(F,std::cerr<<"A="<<std::endl,A,n,n,lda);
			write_field(F,std::cerr<<"V="<<std::endl,Vcst,n,1,1);
			cout<<"NONMINIMALERROR"<<endl;
			return false;
		}
		FFLAS::fflas_delete(E_min);
	}

	FFLAS::fflas_delete(A);
	FFLAS::fflas_delete(Vcst);
	FFLAS::fflas_delete(K);
	return true;
}

template <class Field>
bool run_with_field (Givaro::Integer q, size_t b, size_t n, size_t iters, uint64_t seed)
{
	bool ok = true;
	int nbiter = iters;

	while (ok && nbiter)
	{
		Field* F = chooseField<Field>(q, b); // F, characteristic q of b bits
		typename Field::RandIter G(*F, 0, seed); //random generator over F

		if(F == nullptr)
			return true; //if F is null, nothing to test, just pass

		cout<<"Checking with "; F->write(cout)<<endl;

		ok = ok && check_minpoly(*F, n, G);

		if(!ok)
			cout<<"FAILED"<<endl;
		else
			cout<<"PASS"<<endl;

		delete F;
		nbiter--;
	}

	return ok;
}

int main(int argc, char** argv)
{
    /* Test parameters */
	Givaro::Integer q = -1;
	size_t b = 0;
    size_t n = 128;
	size_t iters = 1;
	bool loop = false;
    uint64_t seed = time(NULL);

	Argument as[] = {
		{ 'q', "-q Q", "Set the field characteristic (-1 for random).",	TYPE_INTEGER, &q },
		{ 'b', "-b B", "Set the bitsize of the field characteristic.", TYPE_INT, &b },
		{ 'n', "-n N", "Set the order of the matrix.", TYPE_INT, &n },
		{ 'i', "-i, R", "set the number of repetitions.", TYPE_INT, &iters },
		{ 'l', "-loop Y/N", "run the test in an infinite loop.", TYPE_BOOL , &loop },
		{ 's', "-s seed", "set seed for the random generator.", TYPE_INT, &seed },
			END_OF_ARGUMENTS
		};

	FFLAS::parseArguments(argc, argv, as);

	bool ok = true;

	do
	{
		ok &= run_with_field<Modular<double>>(q,b,n,iters,seed);
		//more tests?
	} while(ok && loop);

	return !ok ;
}
<commit_msg>Replaced Horner calls by direct computation using Krylov matrix<commit_after>/* -*- mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
// vim:sts=4:sw=4:ts=4:noet:sr:cino=>s,f0,{0,g0,(0,\:0,t0,+0,=s

/*
 * Copyright (C) FFLAS-FFPACK
 * Written by David Lucas
 * This file is Free Software and part of FFLAS-FFPACK.
 *
 * ========LICENCE========
 * This file is part of the library FFLAS-FFPACK.
 *
 * FFLAS-FFPACK is free software: you can redistribute it and/or modify
 * it under the terms of the  GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 * ========LICENCE========
 *.
 */

//--------------------------------------------------------------------------
//                        Test for minpoly
//
//--------------------------------------------------------------------------
// David Lucas
//-------------------------------------------------------------------------

#include <iomanip>
#include <iostream>

#include "fflas-ffpack/fflas-ffpack-config.h"
#include "fflas-ffpack/fflas/fflas.h"
#include "fflas-ffpack/ffpack/ffpack.h"
#include "fflas-ffpack/utils/args-parser.h"
#include "fflas-ffpack/utils/fflas_randommatrix.h"
#include "test-utils.h"
#include <givaro/modular.h>
#include <givaro/modular-balanced.h>
#include <givaro/modular-integer.h>
#include <givaro/givpoly1factor.h>
#include <givaro/givpoly1.h>

using namespace std;
using namespace FFPACK;
using Givaro::Modular;
using Givaro::ModularBalanced;

typedef Givaro::ModularBalanced<double> Field;
typedef vector<Field::Element> Polynomial;

/* Computes P(A)*V and stores it in E using Horner's scheme for
 * polynomial evaluation. */
template<typename Field, typename Element>
void horner_matrix_vector(const Field &F, size_t n, Element *A, size_t lda, Element *V,
						  Element *E, Polynomial P)
{

	//TODO: Quite a few copies. Could be improved.
	//TODO: Add incV and incE
	size_t deg = P.size() - 1;
	Element *E_tmp;
	E_tmp = FFLAS::fflas_new(F, 1, n);

	FFLAS::fassign(F, n, V, 1, E, 1);
	FFLAS::fscalin(F, n, P[deg], E, 1); // E <- P[deg+1] * V

    for(long i = deg; i > 0; --i)
    {
		FFLAS::fassign(F, n, E, 1, E_tmp, 1); //E_tmp <- E
		FFLAS::fgemv(F, FFLAS::FflasNoTrans, n, n, F.one, A, lda, E_tmp, 1, F.zero, E, 1);//E <- A * E_tmp
		FFLAS::faxpy(F, 1, n, P[i-1], V, 1, E, 1); //E <- minP[i-1] * V + E
    }
	FFLAS::fflas_delete(E_tmp);
}

template<typename Field, class RandIter>
bool check_minpoly(const Field &F, size_t n, RandIter& G)
{
	typedef typename Field::Element Element;
	typedef typename Field::Element_ptr Element_ptr;
	size_t lda, ldv;
	Element *A, *V, *Vcst;

	//Default
	lda = n;
	ldv = n;

	/*Create variables used for testing (matrices, vectors and polynomials) */

    A = FFLAS::fflas_new(F, n, n);
    V = FFLAS::fflas_new(F, n+1, n);
	Vcst = FFLAS::fflas_new(F, 1, n);
    Polynomial minP;

    FFPACK::RandomMatrix (F, n, n, A, lda, G);

	FFPACK::NonZeroRandomMatrix(F, 1, n, V, n, G);
	FFLAS::fassign(F, n, V, 1, Vcst, 1); //MatVecMinPoly modifies V, we store it in Vcst beforehand

	FFPACK::MatVecMinPoly(F, minP, n, A, lda, V, ldv);
	FFLAS::fflas_delete(V);

	/*Check that minP is monic*/

	size_t deg = minP.size() - 1;
	if(!(minP[deg]==F.one))
		return false;

	// Krylov matrix computation
	Element_ptr K;
	size_t ldk = n;
	K = FFLAS::fflas_new(F, deg+1, ldk);
	FFLAS::fassign(F, n, Vcst, 1, K, 1);
	Element *Kptr = K;
	for(size_t i = 0; i < deg; ++i, Kptr += ldk)
		FFLAS::fgemv(F, FFLAS::FflasNoTrans, n, n, F.one, A, lda, Kptr, 1, F.zero, Kptr+ldk, 1);

	/*Check that minP(A).V is zero*/

	Element_ptr E = FFLAS::fflas_new(F, 1, n);
	FFLAS::fzero(F, n, E, 1);

	for(size_t i = 0; i < deg+1; ++i)
		FFLAS::faxpy(F, n, minP[i], K+i*ldk, 1, E, 1);

    if (!FFLAS::fiszero(F, n, E, 1))
	{
		cout<<"NONZEROERROR"<<endl;
		FFLAS::fflas_delete(E);
		return false;
	}

	FFLAS::fflas_delete(E);

	/* Check minimality of minP */

	// minP factorization
	typedef Givaro::Poly1FactorDom<Field, Givaro::Dense> PolyDom; //defines a polynomial domain for Givaro
	typedef typename PolyDom::Element FieldPoly; //defines an element over this polynomial domain (casting purposes)
	vector<FieldPoly> factors;
	vector<uint64_t> powers;

	PolyDom PD(F);
	FieldPoly FP_minP = FieldPoly(minP.begin(), minP.end());
	PD.factor(factors, powers, FP_minP);

	// Factorized minP checks

	FieldPoly res;
	size_t nb_factors = factors.size();
	for(size_t i = 0; i < nb_factors; ++i)
	{
		Element_ptr E_min = FFLAS::fflas_new(F, 1, n);
		PD.div(res, FP_minP, factors[i]);

		for(size_t j = 0; j < deg+1; ++j)
			FFLAS::faxpy(F, n, minP[j], K+j*ldk, 1, E, 1);
		write_field(F,std::cerr<<"V="<<std::endl,Vcst,n,1,1);
		if(FFLAS::fiszero(F, n, E_min, 1))
		{
			cout<<"NONMINIMALERROR"<<endl;
			return false;
		}
		FFLAS::fflas_delete(E_min);
	}

	FFLAS::fflas_delete(A);
	FFLAS::fflas_delete(Vcst);
	FFLAS::fflas_delete(K);
	return true;
}

template <class Field>
bool run_with_field (Givaro::Integer q, size_t b, size_t n, size_t iters, uint64_t seed)
{
	bool ok = true;
	int nbiter = iters;

	while (ok && nbiter)
	{
		Field* F = chooseField<Field>(q, b); // F, characteristic q of b bits
		typename Field::RandIter G(*F, 0, seed); //random generator over F

		if(F == nullptr)
			return true; //if F is null, nothing to test, just pass

		cout<<"Checking with "; F->write(cout)<<endl;

		ok = ok && check_minpoly(*F, n, G);

		if(!ok)
			cout<<"FAILED"<<endl;
		else
			cout<<"PASS"<<endl;

		delete F;
		nbiter--;
	}

	return ok;
}

int main(int argc, char** argv)
{
    /* Test parameters */
	Givaro::Integer q = -1;
	size_t b = 0;
    size_t n = 128;
	size_t iters = 1;
	bool loop = false;
    uint64_t seed = time(NULL);

	Argument as[] = {
		{ 'q', "-q Q", "Set the field characteristic (-1 for random).",	TYPE_INTEGER, &q },
		{ 'b', "-b B", "Set the bitsize of the field characteristic.", TYPE_INT, &b },
		{ 'n', "-n N", "Set the order of the matrix.", TYPE_INT, &n },
		{ 'i', "-i, R", "set the number of repetitions.", TYPE_INT, &iters },
		{ 'l', "-loop Y/N", "run the test in an infinite loop.", TYPE_BOOL , &loop },
		{ 's', "-s seed", "set seed for the random generator.", TYPE_INT, &seed },
			END_OF_ARGUMENTS
		};

	FFLAS::parseArguments(argc, argv, as);

	bool ok = true;

	do
	{
		ok &= run_with_field<Modular<double>>(q,b,n,iters,seed);
		//more tests?
	} while(ok && loop);

	return !ok ;
}
<|endoftext|>


<commit_before>/*******************************************************************************
 *
 * MIT License
 *
 * Copyright (c) 2017 Advanced Micro Devices, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 *******************************************************************************/

#include <sstream>
#include <limits>
#include <cassert>

#include <miopen/gcn_asm_utils.hpp>
#include <miopen/env.hpp>
#include <miopen/logger.hpp>
#include <miopen/handle.hpp>
#include <miopen/solver.hpp>
#include <miopen/generic_search.hpp>

MIOPEN_DECLARE_ENV_VAR(MIOPEN_DEBUG_GCN_ASM_DIRECT_3X3U_PERF_VALS)

namespace miopen {
namespace solver {

bool PerformanceConfigConvAsm3x3U::SetNextValue()
{
    // Increment with wrap-around:
    do
    {
        if(++limit_wave_cnt <= 9) // [0..9]
            break;
        limit_wave_cnt = 0;
        if(++filters_per_wave <= 8) // [1..8]
            break;
        filters_per_wave = 1;
        if(++output_lines_per_wave <= 8) // [1..8]
            break;
        // All the fields (components) of performance confic have wrapped around.
        return false;
    } while(false);
    return true;
}

PerformanceConfigConvAsm3x3U::PerformanceConfigConvAsm3x3U(int lwc, int fpw, int olpw)
    : limit_wave_cnt(lwc), filters_per_wave(fpw), output_lines_per_wave(olpw)
{
}

inline bool PerformanceConfigConvAsm3x3U::
operator==(const PerformanceConfigConvAsm3x3U& other) const
{
    // clang-format off
    return limit_wave_cnt == other.limit_wave_cnt
        && filters_per_wave == other.filters_per_wave
        && output_lines_per_wave == other.output_lines_per_wave; // clang-format on
}

bool PerformanceConfigConvAsm3x3U::IsValidValue() const
{
    // clang-format off
    return (0 <= limit_wave_cnt && limit_wave_cnt <= 9)
        && (1 <= filters_per_wave && filters_per_wave <= 8)
        && (1 <= output_lines_per_wave && output_lines_per_wave <= 8); // clang-format on
}

bool PerformanceConfigConvAsm3x3U::IsValid(const ConvolutionContext& params) const
{
    if(!IsValidValue())
        return false;

    // Count the number of VGPRs required.
    const auto& img_width  = params.in_width;
    const auto& img_height = params.in_height;
    int n                  = 0;

    const bool enable_zero_line_padding_on_read = (img_height != output_lines_per_wave);
    if(enable_zero_line_padding_on_read)
        ++n;

    const int img_x_blocks = img_width;
    const int w64_chunks   = (img_x_blocks + 63) / 64;
    assert(w64_chunks != 0);
    if(w64_chunks == 0)
        return false;
    const int active_lanes = (img_x_blocks + w64_chunks - 1) / w64_chunks;
    assert(active_lanes != 0);
    if(active_lanes == 0)
        return false;
    const bool uneven_line_read_mode  = (img_x_blocks % active_lanes != 0);
    const bool uneven_line_write_mode = (img_width % active_lanes != 0);
    if(uneven_line_read_mode || uneven_line_write_mode)
        ++n;

    const int block_size_x        = 1;
    const int gprs_per_input_line = (img_x_blocks * block_size_x + active_lanes - 1) / active_lanes;
    const int input_lines_per_wave =
        (img_height == output_lines_per_wave) ? output_lines_per_wave : (output_lines_per_wave + 2);
    n += (gprs_per_input_line * input_lines_per_wave); // linesA
    n += (gprs_per_input_line * input_lines_per_wave); // linesB

    const bool enable_dpp_zero_column_padding = true;
    if(enable_dpp_zero_column_padding)
        n += 2;

    const int acc_lines_per_wave = output_lines_per_wave;
    n += (gprs_per_input_line * filters_per_wave * acc_lines_per_wave);

    const int available_vgprs = 256;
    return n < available_vgprs;
}

void PerformanceConfigConvAsm3x3U::EuristicInit(const ConvolutionContext&)
{
    limit_wave_cnt        = 0;
    filters_per_wave      = 2;
    output_lines_per_wave = 2;
    MIOPEN_LOG_I(ToString());
}

std::string PerformanceConfigConvAsm3x3U::ToString() const
{
    std::ostringstream ss;
    Serialize(ss);
    return ss.str();
}

PerformanceConfigConvAsm3x3U
ConvAsm3x3U::GetPerformanceConfig(const ConvolutionContext& params) const
{
    PerformanceConfigConvAsm3x3U pp;
    pp.EuristicInit(params);
    MIOPEN_LOG_I(pp.ToString());
    return pp;
}

bool ConvAsm3x3U::IsValidPerformanceConfig(const ConvolutionContext& problem,
                                           const PerformanceConfigConvAsm3x3U& c) const
{
    return c.IsValidValue() && c.IsValid(problem);
}

bool ConvAsm3x3U::IsApplicable(const ConvolutionContext& params) const
{
    if(!params.use_asm_kernels)
    {
        return false;
    }
    if(!(params.rmv == rocm_meta_version::V1 || params.rmv == rocm_meta_version::V2 ||
         params.rmv == rocm_meta_version::V3 || params.rmv == rocm_meta_version::AMDHSA_1_0))
    {
        return false;
    }

    const std::string name = params.GetStream().GetDeviceName();
    if(name.find("gfx8") == std::string::npos)
    { // Any gfx8 device is ok.
        return false;
    }
    assert(params.weights_layout.length() == 0); // FIXME _weights_layout is not supported yet.
    // clang-format off
    return params.pad0 == 1
        && params.pad1 == 1
        && params.kernel_stride0 == 1
        && params.kernel_stride1 == 1
        && params.kernel_size0 == 3
        && params.kernel_size1 == 3
        && params.n_inputs > 0
        && params.n_inputs % 4 == 0
        && params.in_width > 3
        && params.in_width <= 1000
        && params.float_size == 32
        && params.in_layout == "NCHW";
        // && (params.forward ? params.weights_layout == "KCHW" : params.weights_layout == "CKHW" )
    // clang-format on
}

bool ConvAsm3x3U::IsFast(const ConvolutionContext& params) const { return params.in_width >= 50; }

ConvSolution ConvAsm3x3U::GetSolution(const ConvolutionContext& params,
                                      const PerformanceConfigConvAsm3x3U& config,
                                      const bool disableConfigOverrideFromEnv) const
{
    ConvSolution result;
    std::ostringstream options;
    GenerateClangDefsym(options, "batch_size", params.batch_sz);
    GenerateClangDefsym(options, "img_width", params.in_width);
    GenerateClangDefsym(options, "img_height", params.in_height);
    GenerateClangDefsym(options, "input_channels", params.n_inputs);
    GenerateClangDefsym(options, "output_channels", params.n_outputs);
    GenerateClangDefsym(options, "weights_layout", params.direction.IsForward() ? 0 : 1);
    GenerateClangDefsym(options, "reverse_weights", params.direction.IsForward() ? 0 : 1);
    GenerateClangDefsym(options, "no_params_file", 1);
    GenerateClangDefsym(options,
                        "ROCM_METADATA_VERSION",
                        (params.rmv == rocm_meta_version::V1)
                            ? 1
                            : (params.rmv == rocm_meta_version::V2)
                                  ? 2
                                  : (params.rmv == rocm_meta_version::V3) ? 3 : 4);
    // Perf tune:
    const PerformanceConfigConvAsm3x3U* pcfg = &config;
    PerformanceConfigConvAsm3x3U fromEnv;
    if(!disableConfigOverrideFromEnv)
    {
        std::string s;
        const auto p_asciz = miopen::GetStringEnv(MIOPEN_DEBUG_GCN_ASM_DIRECT_3X3U_PERF_VALS{});
        if(p_asciz != nullptr)
        {
            s = std::string(p_asciz);
            if(!s.empty()) // else nothing to parse.
            {
                if(!fromEnv.Deserialize(s) || !fromEnv.IsValid(params))
                {
                    MIOPEN_LOG_E("MIOPEN_DEBUG_GCN_ASM_DIRECT_3X3U_PERF_VALS: "
                                 "Bad format or invalid for the problem config: "
                                 << s);
                }
                else
                {
                    MIOPEN_LOG_I("Overridden from env: " << fromEnv.ToString());
                    pcfg = &fromEnv;
                }
            }
        }
    }
    GenerateClangDefsym(options, "limit_wave_cnt", pcfg->limit_wave_cnt);
    GenerateClangDefsym(options, "filters_per_wave", pcfg->filters_per_wave);
    GenerateClangDefsym(options, "output_lines_per_wave", pcfg->output_lines_per_wave);
    // Debugging:
    GenerateClangDefsym(options, "enable_debug_output", 0);

    const auto w64_chunks   = (params.in_width + 63) / 64;
    const auto active_lanes = (params.in_width + w64_chunks - 1) / w64_chunks;

    KernelInfo construction_params;
    construction_params.comp_options = options.str();

    construction_params.l_wk.push_back(active_lanes);
    construction_params.l_wk.push_back(1);
    construction_params.l_wk.push_back(1);

    construction_params.g_wk.push_back(
        active_lanes * ((params.n_outputs + pcfg->filters_per_wave - 1) / pcfg->filters_per_wave));
    construction_params.g_wk.push_back((params.in_height + pcfg->output_lines_per_wave - 1) /
                                       pcfg->output_lines_per_wave);
    construction_params.g_wk.push_back(params.batch_sz);

    construction_params.kernel_file = "conv3x3.s";
    construction_params.kernel_name = "gcnAsmConv3x3U";

    result.construction_params.push_back(construction_params);
    return result;
}

int ConvAsm3x3U::RunAndMeasureSolution(miopen::Handle& profile_h,
                                       Data_t bot_ocl_buf,
                                       Data_t top_ocl_buf,
                                       Data_t wei_ocl_buf,
                                       Data_t bias_ocl_buf,
                                       const ConvolutionContext&,
                                       const ConvSolution& solution,
                                       float& elapsed_time) const
{
    assert(bias_ocl_buf == nullptr);
    (void)bias_ocl_buf;
    const KernelInfo k_info = solution.construction_params.back();
#ifdef NDEBUG
    try
#endif
    {
        elapsed_time = std::numeric_limits<float>::max();
        // ConvolutionContext::general_compile_options is for OpenCL kernels
        // and thus not applicable for assembly.
        auto kernel = profile_h.AddKernel("",
                                          "",
                                          k_info.kernel_file,
                                          k_info.kernel_name,
                                          k_info.l_wk,
                                          k_info.g_wk,
                                          k_info.comp_options);
        int padding_val = 0;
        kernel(bot_ocl_buf, wei_ocl_buf, top_ocl_buf, padding_val);
        elapsed_time = profile_h.GetKernelTime();
    }
#ifdef NDEBUG
    catch(miopen::Exception&)
    {
        return -1;
    }
#endif
    return 0;
}

PerformanceConfigConvAsm3x3U ConvAsm3x3U::Search(const ConvolutionContext& context) const
{
    return GenericSearch(*this, context);
}

} // namespace solver
} // namespace miopen
<commit_msg>asm3x3u-build-error-fix(3) cppcheck. format.<commit_after>/*******************************************************************************
 *
 * MIT License
 *
 * Copyright (c) 2017 Advanced Micro Devices, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 *******************************************************************************/

#include <sstream>
#include <limits>
#include <cassert>

#include <miopen/gcn_asm_utils.hpp>
#include <miopen/env.hpp>
#include <miopen/logger.hpp>
#include <miopen/handle.hpp>
#include <miopen/solver.hpp>
#include <miopen/generic_search.hpp>

MIOPEN_DECLARE_ENV_VAR(MIOPEN_DEBUG_GCN_ASM_DIRECT_3X3U_PERF_VALS)

namespace miopen {
namespace solver {

bool PerformanceConfigConvAsm3x3U::SetNextValue()
{
    // Increment with wrap-around:
    do
    {
        if(++limit_wave_cnt <= 9) // [0..9]
            break;
        limit_wave_cnt = 0;
        if(++filters_per_wave <= 8) // [1..8]
            break;
        filters_per_wave = 1;
        if(++output_lines_per_wave <= 8) // [1..8]
            break;
        // All the fields (components) of performance confic have wrapped around.
        return false;
    } while(false);
    return true;
}

PerformanceConfigConvAsm3x3U::PerformanceConfigConvAsm3x3U(int lwc, int fpw, int olpw)
    : limit_wave_cnt(lwc), filters_per_wave(fpw), output_lines_per_wave(olpw)
{
}

inline bool PerformanceConfigConvAsm3x3U::
operator==(const PerformanceConfigConvAsm3x3U& other) const
{
    // clang-format off
    return limit_wave_cnt == other.limit_wave_cnt
        && filters_per_wave == other.filters_per_wave
        && output_lines_per_wave == other.output_lines_per_wave; // clang-format on
}

bool PerformanceConfigConvAsm3x3U::IsValidValue() const
{
    // clang-format off
    return (0 <= limit_wave_cnt && limit_wave_cnt <= 9)
        && (1 <= filters_per_wave && filters_per_wave <= 8)
        && (1 <= output_lines_per_wave && output_lines_per_wave <= 8); // clang-format on
}

bool PerformanceConfigConvAsm3x3U::IsValid(const ConvolutionContext& params) const
{
    if(!IsValidValue())
        return false;

    // Count the number of VGPRs required.
    const auto& img_width  = params.in_width;
    const auto& img_height = params.in_height;
    int n                  = 0;

    const bool enable_zero_line_padding_on_read = (img_height != output_lines_per_wave);
    if(enable_zero_line_padding_on_read)
        ++n;

    const int img_x_blocks = img_width;
    const int w64_chunks   = (img_x_blocks + 63) / 64;
    assert(w64_chunks != 0);
    if(w64_chunks == 0)
        return false;
    const int active_lanes = (img_x_blocks + w64_chunks - 1) / w64_chunks;
    assert(active_lanes != 0);
    if(active_lanes == 0)
        return false;
    const bool uneven_line_read_mode  = (img_x_blocks % active_lanes != 0);
    const bool uneven_line_write_mode = (img_width % active_lanes != 0);
    if(uneven_line_read_mode || uneven_line_write_mode)
        ++n;

    const int block_size_x        = 1;
    const int gprs_per_input_line = (img_x_blocks * block_size_x + active_lanes - 1) / active_lanes;
    const int input_lines_per_wave =
        (img_height == output_lines_per_wave) ? output_lines_per_wave : (output_lines_per_wave + 2);
    n += (gprs_per_input_line * input_lines_per_wave); // linesA
    n += (gprs_per_input_line * input_lines_per_wave); // linesB

    // const bool enable_dpp_zero_column_padding = true;
    // if(enable_dpp_zero_column_padding)
    n += 2;

    const int acc_lines_per_wave = output_lines_per_wave;
    n += (gprs_per_input_line * filters_per_wave * acc_lines_per_wave);

    const int available_vgprs = 256;
    return n < available_vgprs;
}

void PerformanceConfigConvAsm3x3U::EuristicInit(const ConvolutionContext&)
{
    limit_wave_cnt        = 0;
    filters_per_wave      = 2;
    output_lines_per_wave = 2;
    MIOPEN_LOG_I(ToString());
}

std::string PerformanceConfigConvAsm3x3U::ToString() const
{
    std::ostringstream ss;
    Serialize(ss);
    return ss.str();
}

PerformanceConfigConvAsm3x3U
ConvAsm3x3U::GetPerformanceConfig(const ConvolutionContext& params) const
{
    PerformanceConfigConvAsm3x3U pp;
    pp.EuristicInit(params);
    MIOPEN_LOG_I(pp.ToString());
    return pp;
}

bool ConvAsm3x3U::IsValidPerformanceConfig(const ConvolutionContext& problem,
                                           const PerformanceConfigConvAsm3x3U& c) const
{
    return c.IsValidValue() && c.IsValid(problem);
}

bool ConvAsm3x3U::IsApplicable(const ConvolutionContext& params) const
{
    if(!params.use_asm_kernels)
    {
        return false;
    }
    if(!(params.rmv == rocm_meta_version::V1 || params.rmv == rocm_meta_version::V2 ||
         params.rmv == rocm_meta_version::V3 || params.rmv == rocm_meta_version::AMDHSA_1_0))
    {
        return false;
    }

    const std::string name = params.GetStream().GetDeviceName();
    if(name.find("gfx8") == std::string::npos)
    { // Any gfx8 device is ok.
        return false;
    }
    assert(params.weights_layout.length() == 0); // FIXME _weights_layout is not supported yet.
    // clang-format off
    return params.pad0 == 1
        && params.pad1 == 1
        && params.kernel_stride0 == 1
        && params.kernel_stride1 == 1
        && params.kernel_size0 == 3
        && params.kernel_size1 == 3
        && params.n_inputs > 0
        && params.n_inputs % 4 == 0
        && params.in_width > 3
        && params.in_width <= 1000
        && params.float_size == 32
        && params.in_layout == "NCHW";
        // && (params.forward ? params.weights_layout == "KCHW" : params.weights_layout == "CKHW" )
    // clang-format on
}

bool ConvAsm3x3U::IsFast(const ConvolutionContext& params) const { return params.in_width >= 50; }

ConvSolution ConvAsm3x3U::GetSolution(const ConvolutionContext& params,
                                      const PerformanceConfigConvAsm3x3U& config,
                                      const bool disableConfigOverrideFromEnv) const
{
    ConvSolution result;
    std::ostringstream options;
    GenerateClangDefsym(options, "batch_size", params.batch_sz);
    GenerateClangDefsym(options, "img_width", params.in_width);
    GenerateClangDefsym(options, "img_height", params.in_height);
    GenerateClangDefsym(options, "input_channels", params.n_inputs);
    GenerateClangDefsym(options, "output_channels", params.n_outputs);
    GenerateClangDefsym(options, "weights_layout", params.direction.IsForward() ? 0 : 1);
    GenerateClangDefsym(options, "reverse_weights", params.direction.IsForward() ? 0 : 1);
    GenerateClangDefsym(options, "no_params_file", 1);
    GenerateClangDefsym(options,
                        "ROCM_METADATA_VERSION",
                        (params.rmv == rocm_meta_version::V1)
                            ? 1
                            : (params.rmv == rocm_meta_version::V2)
                                  ? 2
                                  : (params.rmv == rocm_meta_version::V3) ? 3 : 4);
    // Perf tune:
    const PerformanceConfigConvAsm3x3U* pcfg = &config;
    PerformanceConfigConvAsm3x3U fromEnv;
    if(!disableConfigOverrideFromEnv)
    {
        std::string s;
        const auto p_asciz = miopen::GetStringEnv(MIOPEN_DEBUG_GCN_ASM_DIRECT_3X3U_PERF_VALS{});
        if(p_asciz != nullptr)
        {
            s = std::string(p_asciz);
            if(!s.empty()) // else nothing to parse.
            {
                if(!fromEnv.Deserialize(s) || !fromEnv.IsValid(params))
                {
                    MIOPEN_LOG_E("MIOPEN_DEBUG_GCN_ASM_DIRECT_3X3U_PERF_VALS: "
                                 "Bad format or invalid for the problem config: "
                                 << s);
                }
                else
                {
                    MIOPEN_LOG_I("Overridden from env: " << fromEnv.ToString());
                    pcfg = &fromEnv;
                }
            }
        }
    }
    GenerateClangDefsym(options, "limit_wave_cnt", pcfg->limit_wave_cnt);
    GenerateClangDefsym(options, "filters_per_wave", pcfg->filters_per_wave);
    GenerateClangDefsym(options, "output_lines_per_wave", pcfg->output_lines_per_wave);
    // Debugging:
    GenerateClangDefsym(options, "enable_debug_output", 0);

    const auto w64_chunks   = (params.in_width + 63) / 64;
    const auto active_lanes = (params.in_width + w64_chunks - 1) / w64_chunks;

    KernelInfo construction_params;
    construction_params.comp_options = options.str();

    construction_params.l_wk.push_back(active_lanes);
    construction_params.l_wk.push_back(1);
    construction_params.l_wk.push_back(1);

    construction_params.g_wk.push_back(
        active_lanes * ((params.n_outputs + pcfg->filters_per_wave - 1) / pcfg->filters_per_wave));
    construction_params.g_wk.push_back((params.in_height + pcfg->output_lines_per_wave - 1) /
                                       pcfg->output_lines_per_wave);
    construction_params.g_wk.push_back(params.batch_sz);

    construction_params.kernel_file = "conv3x3.s";
    construction_params.kernel_name = "gcnAsmConv3x3U";

    result.construction_params.push_back(construction_params);
    return result;
}

int ConvAsm3x3U::RunAndMeasureSolution(miopen::Handle& profile_h,
                                       Data_t bot_ocl_buf,
                                       Data_t top_ocl_buf,
                                       Data_t wei_ocl_buf,
                                       Data_t bias_ocl_buf,
                                       const ConvolutionContext&,
                                       const ConvSolution& solution,
                                       float& elapsed_time) const
{
    assert(bias_ocl_buf == nullptr);
    (void)bias_ocl_buf;
    const KernelInfo k_info = solution.construction_params.back();
#ifdef NDEBUG
    try
#endif
    {
        elapsed_time = std::numeric_limits<float>::max();
        // ConvolutionContext::general_compile_options is for OpenCL kernels
        // and thus not applicable for assembly.
        auto kernel = profile_h.AddKernel("",
                                          "",
                                          k_info.kernel_file,
                                          k_info.kernel_name,
                                          k_info.l_wk,
                                          k_info.g_wk,
                                          k_info.comp_options);
        int padding_val = 0;
        kernel(bot_ocl_buf, wei_ocl_buf, top_ocl_buf, padding_val);
        elapsed_time = profile_h.GetKernelTime();
    }
#ifdef NDEBUG
    catch(miopen::Exception&)
    {
        return -1;
    }
#endif
    return 0;
}

PerformanceConfigConvAsm3x3U ConvAsm3x3U::Search(const ConvolutionContext& context) const
{
    return GenericSearch(*this, context);
}

} // namespace solver
} // namespace miopen
<|endoftext|>


<commit_before>// This file is part of the dune-stuff project:
//   https://users.dune-project.org/projects/dune-stuff/
// Copyright holders: Rene Milk, Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_STUFF_GRID_FAKEENTITY_HH
#define DUNE_STUFF_GRID_FAKEENTITY_HH

#include <dune/stuff/common/disable_warnings.hh>
# include <dune/geometry/type.hh>
#include <dune/stuff/common/reenable_warnings.hh>

namespace Dune {
namespace Stuff {
namespace Grid {

template< int dd >
class FakeEntity
{
public:
  GeometryType type() const;

  class Geometry
  {
  public:
    template< class T >
    T global(const T& t) const
    {
      return t;
    }
  }; // class Geometry

  Geometry geometry() const
  {
    return Geometry();
  }

}; // class FakeEntity

} // namespace Grid
} // namespace Stuff
} // namespace Dune

#endif // DUNE_STUFF_GRID_FAKEENTITY_HH
<commit_msg>[grid] fixes gcc 4.8 compile error with missing FakeEntity field<commit_after>// This file is part of the dune-stuff project:
//   https://users.dune-project.org/projects/dune-stuff/
// Copyright holders: Rene Milk, Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_STUFF_GRID_FAKEENTITY_HH
#define DUNE_STUFF_GRID_FAKEENTITY_HH

#include <dune/stuff/common/disable_warnings.hh>
#include <dune/geometry/type.hh>
#include <dune/stuff/common/reenable_warnings.hh>

namespace Dune {
namespace Stuff {
namespace Grid {

template< int dd >
class FakeEntity
{
public:
  GeometryType type() const;

  class Geometry
  {
  public:
    template< class T >
    T global(const T& t) const
    {
      return t;
    }
  }; // class Geometry

  Geometry geometry() const
  {
    return Geometry();
  }

  static constexpr int dimension = dd;
}; // class FakeEntity

} // namespace Grid
} // namespace Stuff
} // namespace Dune

#endif // DUNE_STUFF_GRID_FAKEENTITY_HH
<|endoftext|>


<commit_before>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/* $Id$ */

////////////////////////////////////////////////////////////////////////////
//                                                                        //
// Container of the distributions for the neural network                  //
//                                                                        //
// Author:                                                                //
// Alex Wilk <wilka@uni-muenster.de>                                      //
//                                                                        //
////////////////////////////////////////////////////////////////////////////

#include <TFile.h>
#include <TROOT.h>
#include <TObject.h>
#include <TMultiLayerPerceptron.h>

#include "AliLog.h"
#include "AliPID.h"
#include "AliESD.h"
#include "AliESDtrack.h"
#include "AliTRDtrack.h"

#include "AliTRDCalPIDNN.h"
#include "AliTRDcalibDB.h"

ClassImp(AliTRDCalPIDNN)

//_________________________________________________________________________
AliTRDCalPIDNN::AliTRDCalPIDNN()
  :AliTRDCalPID("pid", "NN PID references for TRD")
{
  //
  //  The Default constructor
  //

  Init();

}

//_________________________________________________________________________
AliTRDCalPIDNN::AliTRDCalPIDNN(const Text_t *name, const Text_t *title)
  :AliTRDCalPID(name,title)
{
  //
  //  The main constructor
  //

  Init();

}

// //_____________________________________________________________________________
// AliTRDCalPIDNN::AliTRDCalPIDNN(const AliTRDCalPIDNN &c)
//   :TNamed(c)
//   ,fMeanChargeRatio(c.fMeanChargeRatio)
//   ,fModel(0x0)
// {
//   //
//   // Copy constructor
//   //
//
//   if (this != &c) ((AliTRDCalPIDNN &) c).Copy(*this);
//
// }

//_________________________________________________________________________
AliTRDCalPIDNN::~AliTRDCalPIDNN()
{
  //
  // Destructor
  //

}

//_________________________________________________________________________
Bool_t AliTRDCalPIDNN::LoadReferences(Char_t *refFile)
{
  //
  // Read the TRD Neural Networks
  //

  // Read NN Root file
  TFile *nnFile = TFile::Open(refFile,"READ");
  if (!nnFile || !nnFile->IsOpen()) {
    AliError(Form("Opening TRD histgram file %s failed",refFile));
    return kFALSE;
  }
  gROOT->cd();

  // Read Networks
  for (Int_t imom = 0; imom < kNMom; imom++) {
    for (Int_t iplane = 0; iplane < kNPlane; iplane++) {
      TMultiLayerPerceptron *nn = (TMultiLayerPerceptron *)
         nnFile->Get(Form("NN_Mom%d_Plane%d",imom,iplane));
      fModel->AddAt(nn,GetModelID(imom,0,iplane));
    }
  }

  nnFile->Close();
  delete nnFile;

  return kTRUE;

}

//_________________________________________________________________________
TObject *AliTRDCalPIDNN::GetModel(Int_t ip, Int_t, Int_t iplane) const
{
  //
  // Returns one selected TMultiLayerPerceptron. iType not used.
  //

  if (ip<0 || ip>= kNMom) return 0x0;

  AliInfo(Form("Retrive MultiLayerPerceptron for %5.2f GeV/c for plane %d"
         ,fTrackMomentum[ip]
         ,iplane));

  return fModel->At(GetModelID(ip, 0, iplane));

}

//_________________________________________________________________________
Double_t AliTRDCalPIDNN::GetProbability(Int_t spec, Float_t mom, Float_t *dedx
                                      , Float_t, Int_t iplane) const
{
  //
  // Core function of AliTRDCalPID class for calculating the
  // likelihood for species "spec" (see AliTRDtrack::kNspecie) of a
  // given momentum "mom", a given dE/dx (slice "dedx") yield per
  // layer in a given layer (iplane)
  //

  if (spec < 0 || spec >= AliPID::kSPECIES) return 0.;

  // find the interval in momentum and track segment length which applies for this data

  Int_t imom = 1;
  while(imom<AliTRDCalPID::kNMom-1 && mom>fTrackMomentum[imom]) imom++;
  Double_t LNN1, LNN2;
  Double_t mom1 = fTrackMomentum[imom-1], mom2 = fTrackMomentum[imom];

  TMultiLayerPerceptron *nn = 0x0;
  if(!(nn = (TMultiLayerPerceptron *) fModel->At(GetModelID(imom-1, spec, iplane/*, ilength*/)))){
    //if(!(nn = (TMultiLayerPerceptron*)fModel->At(GetModelID(imom-1, spec, iplane/*, ilength*/)))){
    AliInfo(Form("Looking for mom(%f) plane(%d)", mom-1, iplane));
    AliError(Form("NN id %d not found in DB.", GetModelID(imom-1, spec, iplane)));
    return 0.;
  }

  Double_t ddedx[AliTRDtrack::kNMLPslice];
  for(int inode=0; inode<AliTRDtrack::kNMLPslice; inode++) ddedx[inode] = (Double_t)dedx[inode];
  LNN1 = nn->Evaluate(spec, ddedx);

  if(!(nn = (TMultiLayerPerceptron*)fModel->At(GetModelID(imom, spec, iplane/*, ilength*/)))){
    //if(!(nn = (TMultiLayerPerceptron*)fModel->At(GetModelID(imom, spec, iplane/*, ilength*/)))){
    AliInfo(Form("Looking for mom(%f) plane(%d)", mom, iplane));
    AliError(Form("NN id %d not found in DB.", GetModelID(imom, spec, iplane)));
    return LNN1;
  }

  LNN2 = nn->Evaluate(spec, ddedx);

  // return interpolation over momentum binning
  if(mom < fTrackMomentum[0]) return LNN1;
  else if(mom > fTrackMomentum[AliTRDCalPID::kNMom-1]) return LNN2;
  else return LNN1 + (LNN2 - LNN1)*(mom - mom1)/(mom2 - mom1);

}

//_________________________________________________________________________
void AliTRDCalPIDNN::Init()
{
  //
  // Initialization
  //

  fModel = new TObjArray(AliTRDCalPID::kNPlane * AliTRDCalPID::kNMom);
  fModel->SetOwner();

}

//_________________________________________________________________________
Int_t AliTRDCalPIDNN::GetModelID(Int_t mom, Int_t, Int_t plane) const
{

  // returns the ID of the NN distribution (66 MLPs, ID from 56 to 121)

  return /*AliPID::kSPECIES * AliTRDCalPID::kNMom + */
    plane * AliTRDCalPID::kNMom + mom;

}
<commit_msg>Bug fix by Alex<commit_after>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/* $Id$ */

////////////////////////////////////////////////////////////////////////////
//                                                                        //
// Container of the distributions for the neural network                  //
//                                                                        //
// Author:                                                                //
// Alex Wilk <wilka@uni-muenster.de>                                      //
//                                                                        //
////////////////////////////////////////////////////////////////////////////

#include <TFile.h>
#include <TROOT.h>
#include <TObject.h>
#include <TMultiLayerPerceptron.h>

#include "AliLog.h"
#include "AliPID.h"
#include "AliESD.h"
#include "AliESDtrack.h"
#include "AliTRDtrack.h"

#include "AliTRDCalPIDNN.h"
#include "AliTRDcalibDB.h"

ClassImp(AliTRDCalPIDNN)

//_________________________________________________________________________
AliTRDCalPIDNN::AliTRDCalPIDNN()
  :AliTRDCalPID("pid", "NN PID references for TRD")
{
  //
  //  The Default constructor
  //

  Init();

}

//_________________________________________________________________________
AliTRDCalPIDNN::AliTRDCalPIDNN(const Text_t *name, const Text_t *title)
  :AliTRDCalPID(name,title)
{
  //
  //  The main constructor
  //

  Init();

}

// //_____________________________________________________________________________
// AliTRDCalPIDNN::AliTRDCalPIDNN(const AliTRDCalPIDNN &c)
//   :TNamed(c)
//   ,fMeanChargeRatio(c.fMeanChargeRatio)
//   ,fModel(0x0)
// {
//   //
//   // Copy constructor
//   //
//
//   if (this != &c) ((AliTRDCalPIDNN &) c).Copy(*this);
//
// }

//_________________________________________________________________________
AliTRDCalPIDNN::~AliTRDCalPIDNN()
{
  //
  // Destructor
  //

  //if (fModel) delete fModel;

}

//_________________________________________________________________________
Bool_t AliTRDCalPIDNN::LoadReferences(Char_t *refFile)
{
  //
  // Read the TRD Neural Networks
  //

  // Read NN Root file
  TFile *nnFile = TFile::Open(refFile,"READ");
  if (!nnFile || !nnFile->IsOpen()) {
    AliError(Form("Opening TRD histgram file %s failed",refFile));
    return kFALSE;
  }
  gROOT->cd();

  // Read Networks
  for (Int_t imom = 0; imom < kNMom; imom++) {
    for (Int_t iplane = 0; iplane < kNPlane; iplane++) {
      TMultiLayerPerceptron *nn = (TMultiLayerPerceptron *)
         nnFile->Get(Form("NN_Mom%d_Plane%d",imom,iplane));
      fModel->AddAt(nn,GetModelID(imom,0,iplane));
    }
  }

  nnFile->Close();
  delete nnFile;

  return kTRUE;

}

//_________________________________________________________________________
TObject *AliTRDCalPIDNN::GetModel(Int_t ip, Int_t, Int_t iplane) const
{
  //
  // Returns one selected TMultiLayerPerceptron. iType not used.
  //

  if (ip<0 || ip>= kNMom) return 0x0;

  AliInfo(Form("Retrive MultiLayerPerceptron for %5.2f GeV/c for plane %d"
         ,fTrackMomentum[ip]
         ,iplane));

  return fModel->At(GetModelID(ip, 0, iplane));

}

//_________________________________________________________________________
Double_t AliTRDCalPIDNN::GetProbability(Int_t spec, Float_t mom, Float_t *dedx
                                      , Float_t, Int_t iplane) const
{
  //
  // Core function of AliTRDCalPID class for calculating the
  // likelihood for species "spec" (see AliTRDtrack::kNspecie) of a
  // given momentum "mom", a given dE/dx (slice "dedx") yield per
  // layer in a given layer (iplane)
  //

  if (spec < 0 || spec >= AliPID::kSPECIES) return 0.;

  // find the interval in momentum and track segment length which applies for this data

  Int_t imom = 1;
  while (imom<AliTRDCalPID::kNMom-1 && mom>fTrackMomentum[imom]) imom++;
  Double_t lNN1, lNN2;
  Double_t mom1 = fTrackMomentum[imom-1], mom2 = fTrackMomentum[imom];

  TMultiLayerPerceptron *nn = 0x0;
  if(!(nn = (TMultiLayerPerceptron *) fModel->At(GetModelID(imom-1, spec, iplane/*, ilength*/)))){
    //if(!(nn = (TMultiLayerPerceptron*)fModel->At(GetModelID(imom-1, spec, iplane/*, ilength*/)))){
    AliInfo(Form("Looking for mom(%f) plane(%d)", mom-1, iplane));
    AliError(Form("NN id %d not found in DB.", GetModelID(imom-1, spec, iplane)));
    return 0.;
  }

  Double_t ddedx[AliTRDtrack::kNMLPslice];
  for (int inode=0; inode<AliTRDtrack::kNMLPslice; inode++) {
    ddedx[inode] = (Double_t) dedx[inode]
                 / (AliTRDcalibDB::Instance()->GetNumberOfTimeBins()/AliTRDtrack::kNMLPslice);
  }
  lNN1 = nn->Evaluate(spec, ddedx);

  if(!(nn = (TMultiLayerPerceptron*)fModel->At(GetModelID(imom, spec, iplane/*, ilength*/)))){
    //if(!(nn = (TMultiLayerPerceptron*)fModel->At(GetModelID(imom, spec, iplane/*, ilength*/)))){
    AliInfo(Form("Looking for mom(%f) plane(%d)", mom, iplane));
    AliError(Form("NN id %d not found in DB.", GetModelID(imom, spec, iplane)));
    return lNN1;
  }
  lNN2 = nn->Evaluate(spec, ddedx);

  // return interpolation over momentum binning
  if      (mom < fTrackMomentum[0]) {
    return lNN1;
  }
  else if (mom > fTrackMomentum[AliTRDCalPID::kNMom-1]) {
    return lNN2;
  }
  else {
    return lNN1 + (lNN2 - lNN1)*(mom - mom1)/(mom2 - mom1);
  }

}

//_________________________________________________________________________
void AliTRDCalPIDNN::Init()
{
  //
  // Initialization
  //

  fModel = new TObjArray(AliTRDCalPID::kNPlane * AliTRDCalPID::kNMom);
  fModel->SetOwner();

}

//_________________________________________________________________________
Int_t AliTRDCalPIDNN::GetModelID(Int_t mom, Int_t, Int_t plane) const
{

  // returns the ID of the NN distribution (66 MLPs, ID from 56 to 121)

  return /*AliPID::kSPECIES * AliTRDCalPID::kNMom + */
    plane * AliTRDCalPID::kNMom + mom;

}
<|endoftext|>


<commit_before>#include <iostream>
#include <vector>
#include <getopt.h>
#include <functional>
#include <regex>
#include "subcommand.hpp"
#include "stream.hpp"
#include "index.hpp"
#include "position.hpp"
#include "vg.pb.h"
#include "path.hpp"
#include "genotypekit.hpp"
#include "genotyper.hpp"
#include "path_index.hpp"
#include "vg.hpp"
#include <math.h>
#include "srpe.hpp"
#include "filter.hpp"
#include "utility.hpp"
#include "Variant.h"
#include "translator.hpp"
#include "Fasta.h"

using namespace std;
using namespace vg;
using namespace vg::subcommand;

void help_srpe(char** argv){
    cerr << "Usage: " << argv[0] << " srpe [options] <data.gam> <graph.vg>" << endl
    << "Options: " << endl
    << "  -p / --ref-path" << endl
    << "  -x / --xg" << endl
    << "  -g / --gcsa" << endl
    << endl;
}

int main_srpe(int argc, char** argv){
    string alignment_file = "";
    string gam_index_name = "";
    string graph_name = "";
    string xg_name = "";
    string gcsa_name = "";
    string lcp_name = "";

    string spec_vcf = "";
    string ref_fasta = "";
    string ins_fasta = "";

    string augmented_graph_name = "";
    bool augment_paths = true;

    string ref_path = "";

    int max_iter = 2;
    int max_frag_len = 10000;
    int min_soft_clip = 12;

    bool do_all = false;

    vector<string> search_types;
    search_types.push_back("DEL");

    int threads = 1;

    if (argc <= 2) {
        help_srpe(argv);
        return 1;
    }

    int c;
    optind = 2; // force optind past command positional argument
    while (true) {
        static struct option long_options[] =
        {
            {"max-iter", required_argument, 0, 'm'},
            {"xg-index", required_argument, 0, 'x'},
            {"augmented", required_argument, 0, 'a'},
            {"help", no_argument, 0, 'h'},
            {"gcsa-index", required_argument, 0, 'g'},
            {"specific", required_argument, 0, 'S'},
            {"recall", no_argument, 0, 'R'},
            {"insertions", required_argument, 0, 'I'},
            {"reference", required_argument, 0, 'r'},
            {"threads", required_argument, 0, 't'},
            {"ref-path", required_argument, 0, 'p'},
            {0, 0, 0, 0}

        };
        int option_index = 0;
        c = getopt_long (argc, argv, "hx:g:m:S:RI:r:t:a:wp:",
                long_options, &option_index);

        // Detect the end of the options.
        if (c == -1)
            break;

        switch (c)
        {
            case 'a':
                augmented_graph_name = optarg;
                break;
            case 'm':
                max_iter = atoi(optarg);
                break;

            case 't':
                threads = atoi(optarg);
                break;

            case 'R':
                do_all = true;
                break;
            case 'x':
                xg_name = optarg;
                break;
            case 'g':
                gcsa_name = optarg;
                break;
            case 'S':
                spec_vcf = optarg;
                break;
            case 'r':
                ref_fasta = optarg;
                break;
            case 'I':
                ins_fasta = optarg;
                break;
            case 'p':
                ref_path = optarg;
                break;
            case 'h':
            case '?':
            default:
                help_srpe(argv);
                abort();
        }

    }

    omp_set_num_threads(threads);

    SRPE srpe;

    alignment_file = argv[optind];
    //gam_index_name = argv[++optind];
    graph_name = argv[++optind];

    xg::XG* xg_ind = new xg::XG();
    Index gamind;

    vg::VG* graph;

    if (!xg_name.empty()){
        ifstream in(xg_name);
        xg_ind->load(in);
        srpe.ff.set_my_xg_idx(xg_ind);
    }
    // Set GCSA indexes
    if (!gcsa_name.empty()){
            ifstream gcsa_stream(gcsa_name);
            srpe.ff.gcsa_ind = new gcsa::GCSA();
            srpe.ff.gcsa_ind->load(gcsa_stream);
            string lcp_name = gcsa_name + ".lcp";
            ifstream lcp_stream(lcp_name);
            srpe.ff.lcp_ind = new gcsa::LCPArray();
            srpe.ff.lcp_ind->load(lcp_stream);
    }
    if (!xg_name.empty()){
        ifstream xgstream(xg_name);
        xg_ind->load(xgstream);
        srpe.ff.set_my_xg_idx(xg_ind);
    }
    srpe.ff.init_mapper();
    // else{

    // }

    if (!graph_name.empty()){
        ifstream in(graph_name);
        graph = new VG(in, false);
    }

    // Open a variant call file,
    // hash each variant to an hash ID
    // have in if in the loop below.
    map<string, Locus> name_to_loc;
    // Makes a pathindex, which allows us to query length and push out a VCF with a position
    map<string, PathIndex*> pindexes;
    Genotyper gg;
    regex is_alt ("_alt_.*");

    vector<FastaReference*> insertions;
    if (!ins_fasta.empty()){
        FastaReference* ins = new FastaReference();
        insertions.emplace_back(ins);
        ins->open(ins_fasta);

    }

    vector<Alignment> just_fine;
    vector<Alignment> perfect;
    vector<Alignment> simple_mismatch;
    vector<Alignment> discordant_selected;
    vector<Alignment> split_selected;
    vector<Alignment> reversing_selected;
    vector<Alignment> clipped_selected;
    vector<Alignment> one_end_anchored;
    vector<Alignment> quality_selected;
    vector<Alignment> insert_selected;
    vector<Alignment> depth_selected;
    vector<Alignment> single_bp_diff;
    vector<Alignment> unmapped_selected;

    string unmapped_fn = alignment_file + ".unmapped";
    string discordant_fn = alignment_file + ".discordant";
    string split_fn = alignment_file + ".split";
    string reversing_fn = alignment_file +  ".reversing";
    string oea_fn = alignment_file + ".one_end_anchored";
    string clipped_fn = alignment_file + ".softclipped";
    string insert_fn = alignment_file + ".insert_size";
    string quality_fn = alignment_file + ".quality";
    string depth_fn = alignment_file + ".depth";

    ifstream unmapped_stream;
    ifstream discordant_stream;
    ifstream split_stream;
    ifstream reversing_stream;
    ifstream oea_stream;
    ifstream clipped_stream;
    ifstream insert_stream;
    ifstream quality_stream;
    ifstream depth_stream;
    vector<Interval<int> > inters;

    double insert_size = 0.0;
    double insert_var = 0.0;

    struct INS_INTERVAL{
        int64_t start = 0;
        int64_t end = 0;
        int64_t len = 0;
        double start_ci = 1000.0;
        double end_ci = 1000.0;
        bool precise = false;
        int fragl_supports = 0;
        int oea_supports = 0;
        int split_supports = 0;
        int other_supports = 0;
        inline int total_supports(){
            return fragl_supports + oea_supports + split_supports + other_supports;
        }
        inline string to_string(){
            stringstream ss;
            ss << "Start: " << start <<
            " End: " << end << " Support: " << total_supports() << endl;
            return ss.str();
        }
        inline bool overlap(INS_INTERVAL other){
            if ( (other.start >= start && other.start <= end) ||
                  (other.end <= end && other.end >= start) ||
                  (other.start >= start && other.end <= end)){
                    return true;
                  }
            return false;

        }
        inline bool contained(INS_INTERVAL other){
            return false;
        }
        inline Interval<int> as_interval(){
            return Interval<int>(start, end, 0);
        }
    };

    std::function<vector<INS_INTERVAL>(vector<INS_INTERVAL>)> merge_intervals = [&](vector<INS_INTERVAL> ins){
        vector<INS_INTERVAL> ret;
        // sentinel interval
        INS_INTERVAL sent;
        sent.start = -1;
        sent.end = -1;
        for (int i = 0; i < ins.size(); i++){
            bool merged = false;
            for (int j = 0; j < ret.size(); j++){
                if (ret[j].overlap(ins[i])){
                    ret[j].other_supports+=1;
                    merged = true;
                }
            }
            if (!merged){
                ret.push_back(ins[i]);
            }

        }
        return ret;
    };

    // Set up path index
    srpe.ff.set_my_vg(graph);
    srpe.ff.fill_node_to_position(ref_path);

    vector<INS_INTERVAL> ins;

    std::function<void(vector<INS_INTERVAL>&, map<int64_t, vector<INS_INTERVAL> >&)> merge = [&](vector<INS_INTERVAL>& ins, map<int64_t, vector<INS_INTERVAL> >& start_to_interval){

    };

    std::function<void(Alignment&, Alignment&)> calc_insert_size = [&](Alignment& a, Alignment& b){
        insert_size = 1000.0;
        insert_var = 300.0;
    };

    std::function<void(Alignment&, Alignment&)> insert_sz_func = [&](Alignment& a, Alignment& b){
        if (a.fragment_size() > 0 && a.mapping_quality() > 0
            && b.mapping_quality() >  0){
            int frag_diff = abs(a.fragment(0).length() - floor(insert_size));
            // Get mappings of node from graph

            // Get position (using Mapping* and path index)
            INS_INTERVAL i;
            i.start = srpe.ff.node_to_position[ a.path().mapping(0).position().node_id()] ;
            i.end = srpe.ff.node_to_position[ b.path().mapping(0).position().node_id()] ;
            i.fragl_supports +=1;
            // Set start to final position of first mate
            // Set end position to start + (frag_diff)
            // Length to frag_diff
            // Increment supports
            ins.push_back(i);
        }
    };

    std::vector<Alignment> splits;
    std::vector<INS_INTERVAL> split_intervals;
    std::function<void(Alignment&)> split_read_func = [&](Alignment& a){
        // remap in clipped reads
        string a_clip = srpe.ff.get_clipped_seq(a);
        if (a_clip.length() > 20){
            cerr << "Remapping " << a_clip << endl;
            vector<Alignment> a_remap = srpe.ff.remap(a_clip);
            if (a_remap.size() > 0 && a_remap[0].score() > 0){
            //cerr << (a_remap[0].score() > 0 ? "MAPPED!" : "unmapped :(") << endl;
            INS_INTERVAL i;
            i.start = srpe.ff.get_clipped_position(a);
            //i.end = srpe.ff.node_to_position[ a_remap[0].path().mapping(0).position().node_id() ];
            ins.push_back(i);
            }
        }
        //Alignment x = srpe.ff.split_read_filter(a);
        //Alignment y = srpe.ff.split_read_filter(b);
        // if (!x.sequence().empty()){
        //     // We got a match to the graph from our clip
        //     // store the alignment and create an interval
        //     INS_INTERVAL i;
        //     i.start = srpe.ff.get_clipped_position(a);
        //     Alignment cmatch = srpe.ff.remap( srpe.ff.get_clipped_seq(a));
        //     //i.end = srpe.ff.node_to_position[ cmatch.path().mapping(0).position().node_id() ];
        // }
        // else if (!y.sequence().empty()){
        //     // We got a match to the graph from our clip
        //     // store the alignment and create an interval
        //     INS_INTERVAL i;
        //     i.start = srpe.ff.get_clipped_position(b);
        //     //Alignment cmatch = srpe.ff.remap( srpe.ff.get_clipped_seq(b));
        //     //i.end = srpe.ff.node_to_position[ cmatch.path().mapping(0).position().node_id() ];
        //     ins.push_back(i);
        // }
        // Set putative breakpoint evidence based on those (i.e. make interval for each split read)
        // Merge overlapping intervals.
        // Search for additional support in split reads.

    };

    // Once merged, we can output putative breakpoints
    // using the combined information.

    // Get splits that map near the breakpoint

    // INSERTIONS
    // Open relevant GAMfiles
    insert_stream.open(discordant_fn);
    clipped_stream.open(clipped_fn);
    if (!insert_stream.good()){
        cerr << "Must provide a .discordant file.";
    }
    else{
        // Collect all long insert reads
        //stream::for_each_interleaved_pair_parallel(insert_stream, insert_sz_func);
        stream::for_each_parallel(clipped_stream, split_read_func);
    }

    oea_stream.open(oea_fn);
    if (!oea_stream.good()){
        cerr << "No one-end-anchored file found." << endl
        << "Please provide one using [ vg sift -p -O x.gam ]" << endl;
        exit(1);
    }
    else{
        // Get all OEA reads
        // and place a breakpoint <insertsize> bp from the mapped read.

    }

    clipped_stream.open(clipped_fn);
    if(!clipped_stream.good()){
    }
    else{
        // collect some clipped reads
        // Split-read map their clipped portions
        // check if the seq mapped; if not, move on
        // if it did:
        //   find the interval where we see the break
        //   add some SR evidence
        //   refine its start / end / CI
    }

     // Merge insertion intervals and supports
    vector<INS_INTERVAL> merged = merge_intervals(ins);

    cerr << "Found " << merged.size() << " candidate intervals." << endl;
    for (auto x : merged){
        cerr << x.to_string() << endl;
    }

    return 0;
}

static Subcommand vg_srpe ("srpe", "graph-external SV detection", main_srpe);

<commit_msg>Update SRPE<commit_after>#include <iostream>
#include <vector>
#include <getopt.h>
#include <functional>
#include <regex>
#include "subcommand.hpp"
#include "stream.hpp"
#include "index.hpp"
#include "position.hpp"
#include "vg.pb.h"
#include "path.hpp"
#include "genotypekit.hpp"
#include "genotyper.hpp"
#include "path_index.hpp"
#include "vg.hpp"
#include <math.h>
#include "srpe.hpp"
#include "filter.hpp"
#include "utility.hpp"
#include "Variant.h"
#include "translator.hpp"
#include "Fasta.h"

using namespace std;
using namespace vg;
using namespace vg::subcommand;

void help_srpe(char** argv){
    cerr << "Usage: " << argv[0] << " srpe [options] <data.gam> <graph.vg>" << endl
    << "Options: " << endl
    << "  -p / --ref-path" << endl
    << "  -x / --xg" << endl
    << "  -g / --gcsa" << endl
    << endl;
}

int main_srpe(int argc, char** argv){
    string alignment_file = "";
    string gam_index_name = "";
    string graph_name = "";
    string xg_name = "";
    string gcsa_name = "";
    string lcp_name = "";

    string spec_vcf = "";
    string ref_fasta = "";
    string ins_fasta = "";

    string augmented_graph_name = "";
    bool augment_paths = true;

    string ref_path = "";

    int max_iter = 2;
    int max_frag_len = 10000;
    int min_soft_clip = 12;

    bool do_all = false;

    vector<string> search_types;
    search_types.push_back("DEL");

    int threads = 1;

    if (argc <= 2) {
        help_srpe(argv);
        return 1;
    }

    int c;
    optind = 2; // force optind past command positional argument
    while (true) {
        static struct option long_options[] =
        {
            {"max-iter", required_argument, 0, 'm'},
            {"xg-index", required_argument, 0, 'x'},
            {"augmented", required_argument, 0, 'a'},
            {"help", no_argument, 0, 'h'},
            {"gcsa-index", required_argument, 0, 'g'},
            {"specific", required_argument, 0, 'S'},
            {"recall", no_argument, 0, 'R'},
            {"insertions", required_argument, 0, 'I'},
            {"reference", required_argument, 0, 'r'},
            {"threads", required_argument, 0, 't'},
            {"ref-path", required_argument, 0, 'p'},
            {0, 0, 0, 0}

        };
        int option_index = 0;
        c = getopt_long (argc, argv, "hx:g:m:S:RI:r:t:a:wp:",
                long_options, &option_index);

        // Detect the end of the options.
        if (c == -1)
            break;

        switch (c)
        {
            case 'a':
                augmented_graph_name = optarg;
                break;
            case 'm':
                max_iter = atoi(optarg);
                break;

            case 't':
                threads = atoi(optarg);
                break;

            case 'R':
                do_all = true;
                break;
            case 'x':
                xg_name = optarg;
                break;
            case 'g':
                gcsa_name = optarg;
                break;
            case 'S':
                spec_vcf = optarg;
                break;
            case 'r':
                ref_fasta = optarg;
                break;
            case 'I':
                ins_fasta = optarg;
                break;
            case 'p':
                ref_path = optarg;
                break;
            case 'h':
            case '?':
            default:
                help_srpe(argv);
                abort();
        }

    }

    omp_set_num_threads(threads);

    SRPE srpe;

    alignment_file = argv[optind];
    //gam_index_name = argv[++optind];
    graph_name = argv[++optind];

    xg::XG* xg_ind = new xg::XG();
    Index gamind;

    vg::VG* graph;

    if (!xg_name.empty()){
        ifstream in(xg_name);
        xg_ind->load(in);
        srpe.ff.set_my_xg_idx(xg_ind);
    }
    // Set GCSA indexes
    if (!gcsa_name.empty()){
            ifstream gcsa_stream(gcsa_name);
            srpe.ff.gcsa_ind = new gcsa::GCSA();
            srpe.ff.gcsa_ind->load(gcsa_stream);
            string lcp_name = gcsa_name + ".lcp";
            ifstream lcp_stream(lcp_name);
            srpe.ff.lcp_ind = new gcsa::LCPArray();
            srpe.ff.lcp_ind->load(lcp_stream);
    }
    if (!xg_name.empty()){
        ifstream xgstream(xg_name);
        xg_ind->load(xgstream);
        srpe.ff.set_my_xg_idx(xg_ind);
    }
    srpe.ff.init_mapper();
    // else{

    // }

    if (!graph_name.empty()){
        ifstream in(graph_name);
        graph = new VG(in, false);
    }

    // Open a variant call file,
    // hash each variant to an hash ID
    // have in if in the loop below.
    map<string, Locus> name_to_loc;
    // Makes a pathindex, which allows us to query length and push out a VCF with a position
    map<string, PathIndex*> pindexes;
    Genotyper gg;
    regex is_alt ("_alt_.*");

    vector<FastaReference*> insertions;
    if (!ins_fasta.empty()){
        FastaReference* ins = new FastaReference();
        insertions.emplace_back(ins);
        ins->open(ins_fasta);

    }

    vector<Alignment> just_fine;
    vector<Alignment> perfect;
    vector<Alignment> simple_mismatch;
    vector<Alignment> discordant_selected;
    vector<Alignment> split_selected;
    vector<Alignment> reversing_selected;
    vector<Alignment> clipped_selected;
    vector<Alignment> one_end_anchored;
    vector<Alignment> quality_selected;
    vector<Alignment> insert_selected;
    vector<Alignment> depth_selected;
    vector<Alignment> single_bp_diff;
    vector<Alignment> unmapped_selected;

    string unmapped_fn = alignment_file + ".unmapped";
    string discordant_fn = alignment_file + ".discordant";
    string split_fn = alignment_file + ".split";
    string reversing_fn = alignment_file +  ".reversing";
    string oea_fn = alignment_file + ".one_end_anchored";
    string clipped_fn = alignment_file + ".softclipped";
    string insert_fn = alignment_file + ".insert_size";
    string quality_fn = alignment_file + ".quality";
    string depth_fn = alignment_file + ".depth";

    ifstream unmapped_stream;
    ifstream discordant_stream;
    ifstream split_stream;
    ifstream reversing_stream;
    ifstream oea_stream;
    ifstream clipped_stream;
    ifstream insert_stream;
    ifstream quality_stream;
    ifstream depth_stream;
    vector<Interval<int> > inters;

    double insert_size = 0.0;
    double insert_var = 0.0;

    struct INS_INTERVAL{
        int64_t start = 0;
        int64_t end = 0;
        int64_t len = 0;
        double start_ci = 1000.0;
        double end_ci = 1000.0;
        bool precise = false;
        int fragl_supports = 0;
        int oea_supports = 0;
        int split_supports = 0;
        int other_supports = 0;
        inline int total_supports(){
            return fragl_supports + oea_supports + split_supports + other_supports;
        }
        inline string to_string(){
            stringstream ss;
            ss << "Start: " << start <<
            " End: " << end << " Support: " << total_supports() << endl;
            return ss.str();
        }
        inline bool overlap(INS_INTERVAL other){
            if ( (other.start >= start && other.start <= end) ||
                  (other.end <= end && other.end >= start) ||
                  (other.start >= start && other.end <= end)){
                    return true;
                  }
            return false;

        }
        inline bool contained(INS_INTERVAL other){
            return false;
        }
        inline Interval<int> as_interval(){
            return Interval<int>(start, end, 0);
        }
    };

    std::function<vector<INS_INTERVAL>(vector<INS_INTERVAL>)> merge_intervals = [&](vector<INS_INTERVAL> ins){
        vector<INS_INTERVAL> ret;
        // sentinel interval
        INS_INTERVAL sent;
        sent.start = -1;
        sent.end = -1;
        for (int i = 0; i < ins.size(); i++){
            bool merged = false;
            for (int j = 0; j < ret.size(); j++){
                if (ret[j].overlap(ins[i])){
                    ret[j].other_supports+=1;
                    merged = true;
                }
            }
            if (!merged){
                ret.push_back(ins[i]);
            }

        }
        return ret;
    };

    // Set up path index
    srpe.ff.set_my_vg(graph);
    srpe.ff.soft_clip_limit = 20;
    srpe.ff.fill_node_to_position(ref_path);

    vector<INS_INTERVAL> ins;

    std::function<void(vector<INS_INTERVAL>&, map<int64_t, vector<INS_INTERVAL> >&)> merge = [&](vector<INS_INTERVAL>& ins, map<int64_t, vector<INS_INTERVAL> >& start_to_interval){

    };

    std::function<void(Alignment&, Alignment&)> calc_insert_size = [&](Alignment& a, Alignment& b){
        insert_size = 1000.0;
        insert_var = 300.0;
    };

    std::function<void(Alignment&, Alignment&)> insert_sz_func = [&](Alignment& a, Alignment& b){
        if (a.fragment_size() > 0 && a.mapping_quality() > 0
            && b.mapping_quality() >  0){
            int frag_diff = abs(a.fragment(0).length() - floor(insert_size));
            // Get mappings of node from graph

            // Get position (using Mapping* and path index)
            INS_INTERVAL i;
            i.start = srpe.ff.node_to_position[ a.path().mapping(0).position().node_id()] ;
            i.end = srpe.ff.node_to_position[ b.path().mapping(0).position().node_id()] ;
            i.fragl_supports +=1;
            // Set start to final position of first mate
            // Set end position to start + (frag_diff)
            // Length to frag_diff
            // Increment supports
            ins.push_back(i);
        }
    };

    std::vector<Alignment> splits;
    std::vector<INS_INTERVAL> split_intervals;
    std::function<void(Alignment&)> split_read_func = [&](Alignment& a){
        // remap in clipped reads
        string a_clip = srpe.ff.get_clipped_seq(a);
        //cerr << a.DebugString() << endl;
        //cerr << a_clip << endl;
        if (a_clip.length() > 25){
            //cerr << "Remapping " << a_clip << endl;
            vector<Alignment> a_remap = srpe.ff.remap(a_clip);
            if (a_remap.size() > 0 && a_remap[0].score() > 0){
                //cerr << (a_remap[0].score() > 0 ? "MAPPED!" : "unmapped :(") << endl;
                INS_INTERVAL i;
                i.start = srpe.ff.get_clipped_position(a);
                i.end = srpe.ff.node_to_position[ a_remap[0].path().mapping(0).position().node_id() ];
                i.split_supports +=1;
                ins.push_back(i);
                cerr << i.to_string() << "\t" << a_remap.size() << endl;
            }
        }

        // Set putative breakpoint evidence based on those (i.e. make interval for each split read)
        // Merge overlapping intervals.
        // Search for additional support in split reads.

    };

    // Once merged, we can output putative breakpoints
    // using the combined information.

    // Get splits that map near the breakpoint

    // INSERTIONS
    // Open relevant GAMfiles
    insert_stream.open(discordant_fn);
    clipped_stream.open(clipped_fn);
    if (!insert_stream.good()){
        cerr << "Must provide a .discordant file.";
    }
    else{
        // Collect all long insert reads
        //stream::for_each_interleaved_pair_parallel(insert_stream, insert_sz_func);
        stream::for_each_parallel(clipped_stream, split_read_func);
    }

    oea_stream.open(oea_fn);
    if (!oea_stream.good()){
        cerr << "No one-end-anchored file found." << endl
        << "Please provide one using [ vg sift -p -O x.gam ]" << endl;
        exit(1);
    }
    else{
        // Get all OEA reads
        // and place a breakpoint <insertsize> bp from the mapped read.

    }

    clipped_stream.open(clipped_fn);
    if(!clipped_stream.good()){
    }
    else{
        // collect some clipped reads
        // Split-read map their clipped portions
        // check if the seq mapped; if not, move on
        // if it did:
        //   find the interval where we see the break
        //   add some SR evidence
        //   refine its start / end / CI
    }

     // Merge insertion intervals and supports
    vector<INS_INTERVAL> merged = merge_intervals(ins);

    cerr << "Found " << merged.size() << " candidate intervals." << endl;
    for (auto x : merged){
        cerr << x.to_string() << endl;
    }

    return 0;
}

static Subcommand vg_srpe ("srpe", "graph-external SV detection", main_srpe);

<|endoftext|>


<commit_before>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/autofill/name_field.h"

#include "base/string_util.h"
#include "chrome/browser/autofill/autofill_type.h"

NameField* NameField::Parse(std::vector<AutoFillField*>::const_iterator* iter,
                            bool is_ecml) {
  // Try FirstLastNameField first since it's more specific.
  NameField* field = FirstLastNameField::Parse(iter, is_ecml);
  if (field == NULL && !is_ecml)
    field = FullNameField::Parse(iter);
  return field;
}

FullNameField* FullNameField::Parse(
    std::vector<AutoFillField*>::const_iterator* iter) {
  // Exclude labels containing the string "username", which typically
  // denotes a login ID rather than the user's actual name.
  AutoFillField* field = **iter;
  if (Match(field, ASCIIToUTF16("username"), false))
    return NULL;

  // Searching for any label containing the word "name" is too general;
  // for example, Travelocity_Edit travel profile.html contains a field
  // "Travel Profile Name".
  if (ParseText(iter, ASCIIToUTF16("^name|full name|your name|customer name"),
                &field))
    return new FullNameField(field);

  return NULL;
}

FirstLastNameField* FirstLastNameField::Parse1(
    std::vector<AutoFillField*>::const_iterator* iter) {
  // Some pages (e.g. Overstock_comBilling.html, SmithsonianCheckout.html)
  // have the label "Name" followed by two or three text fields.
  FirstLastNameField v;
  std::vector<AutoFillField*>::const_iterator q = *iter;

  AutoFillField* next;
  if (ParseText(&q, ASCIIToUTF16("^name"), &v.first_name_) &&
      ParseText(&q, ASCIIToUTF16(""), &next)) {
    if (ParseText(&q, ASCIIToUTF16(""), &v.last_name_)) {
      // There are three name fields; assume that the middle one is a
      // middle initial (it is, at least, on SmithsonianCheckout.html).
      v.middle_name_ = next;
      v.middle_initial_ = true;
    } else {  // only two name fields
      v.last_name_ = next;
    }

    *iter = q;
    return new FirstLastNameField(v);
  }

  return NULL;
}

FirstLastNameField* FirstLastNameField::Parse2(
    std::vector<AutoFillField*>::const_iterator* iter) {
  FirstLastNameField v;
  std::vector<AutoFillField*>::const_iterator q = *iter;

  // A fair number of pages use the names "fname" and "lname" for naming
  // first and last name fields (examples from the test suite:
  // BESTBUY_COM - Sign In2.html; Crate and Barrel Check Out.html;
  // dell_checkout1.html).  At least one UK page (The China Shop2.html)
  // asks, in stuffy English style, for just initials and a surname,
  // so we match "initials" here (and just fill in a first name there,
  // American-style).
  // The ".*first$" matches fields ending in "first" (example in sample8.html).
  if (!ParseText(&q,
                 ASCIIToUTF16("first name|firstname|initials|fname|.*first$"),
                 &v.first_name_))
    return NULL;

  // We check for a middle initial before checking for a middle name
  // because at least one page (PC Connection.html) has a field marked
  // as both (the label text is "MI" and the element name is
  // "txtmiddlename"); such a field probably actually represents a
  // middle initial.
  if (ParseText(&q,
                ASCIIToUTF16("^mi|middle initial|middleinitial|m.i."),
                &v.middle_name_)) {
    v.middle_initial_ = true;
  } else {
    ParseText(&q, ASCIIToUTF16("middle name|mname"), &v.middle_name_);
  }

  // The ".*last$" matches fields ending in "last" (example in sample8.html).
  if (!ParseText(&q,
                 ASCIIToUTF16("last name|lastname|lname|surname|.*last$"),
                 &v.last_name_))
    return NULL;

  *iter = q;
  return new FirstLastNameField(v);
}

FirstLastNameField* FirstLastNameField::ParseEcmlName(
    std::vector<AutoFillField*>::const_iterator* iter) {
  FirstLastNameField field;
  std::vector<AutoFillField*>::const_iterator q = *iter;

  string16 pattern = GetEcmlPattern(kEcmlShipToFirstName,
                                    kEcmlBillToFirstName, '|');
  if (!ParseText(&q, pattern, &field.first_name_))
    return NULL;

  pattern = GetEcmlPattern(kEcmlShipToMiddleName, kEcmlBillToMiddleName, '|');
  ParseText(&q, pattern, &field.middle_name_);

  pattern = GetEcmlPattern(kEcmlShipToLastName, kEcmlBillToLastName, '|');
  if (ParseText(&q, pattern, &field.last_name_)) {
    *iter = q;
    return new FirstLastNameField(field);
  }

  return NULL;
}

FirstLastNameField* FirstLastNameField::Parse(
    std::vector<AutoFillField*>::const_iterator* iter,
    bool is_ecml) {
  if (is_ecml) {
    return ParseEcmlName(iter);
  } else {
    FirstLastNameField* v = Parse1(iter);
    if (v != NULL)
      return v;

    return Parse2(iter);
  }
}

bool FirstLastNameField::GetFieldInfo(FieldTypeMap* field_type_map) const {
  bool ok = Add(field_type_map, first_name_, AutoFillType(NAME_FIRST));
  DCHECK(ok);
  ok = ok && Add(field_type_map, last_name_, AutoFillType(NAME_LAST));
  DCHECK(ok);
  AutoFillType type = middle_initial_ ?
      AutoFillType(NAME_MIDDLE_INITIAL) : AutoFillType(NAME_MIDDLE);
  ok = ok && Add(field_type_map, middle_name_, type);
  DCHECK(ok);

  return ok;
}

FirstLastNameField::FirstLastNameField()
    : first_name_(NULL),
      middle_name_(NULL),
      last_name_(NULL),
      middle_initial_(false) {
}

FirstLastNameField::FirstLastNameField(const FirstLastNameField& field)
    : NameField(),
      first_name_(field.first_name_),
      middle_name_(field.middle_name_),
      last_name_(field.last_name_),
      middle_initial_(field.middle_initial_) {
}
<commit_msg>AutoFill form filling on myspace.com<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/autofill/name_field.h"

#include "base/string_util.h"
#include "chrome/browser/autofill/autofill_type.h"

NameField* NameField::Parse(std::vector<AutoFillField*>::const_iterator* iter,
                            bool is_ecml) {
  // Try FirstLastNameField first since it's more specific.
  NameField* field = FirstLastNameField::Parse(iter, is_ecml);
  if (field == NULL && !is_ecml)
    field = FullNameField::Parse(iter);
  return field;
}

FullNameField* FullNameField::Parse(
    std::vector<AutoFillField*>::const_iterator* iter) {
  // Exclude labels containing the string "username", which typically
  // denotes a login ID rather than the user's actual name.
  AutoFillField* field = **iter;
  if (Match(field, ASCIIToUTF16("username"), false))
    return NULL;

  // Searching for any label containing the word "name" is too general;
  // for example, Travelocity_Edit travel profile.html contains a field
  // "Travel Profile Name".
  const string16 name_match =
      ASCIIToUTF16("^name|full name|fullname|your name|customer name");
  if (ParseText(iter, name_match, &field))
    return new FullNameField(field);

  return NULL;
}

FirstLastNameField* FirstLastNameField::Parse1(
    std::vector<AutoFillField*>::const_iterator* iter) {
  // Some pages (e.g. Overstock_comBilling.html, SmithsonianCheckout.html)
  // have the label "Name" followed by two or three text fields.
  FirstLastNameField v;
  std::vector<AutoFillField*>::const_iterator q = *iter;

  AutoFillField* next;
  if (ParseText(&q, ASCIIToUTF16("^name"), &v.first_name_) &&
      ParseText(&q, ASCIIToUTF16(""), &next)) {
    if (ParseText(&q, ASCIIToUTF16(""), &v.last_name_)) {
      // There are three name fields; assume that the middle one is a
      // middle initial (it is, at least, on SmithsonianCheckout.html).
      v.middle_name_ = next;
      v.middle_initial_ = true;
    } else {  // only two name fields
      v.last_name_ = next;
    }

    *iter = q;
    return new FirstLastNameField(v);
  }

  return NULL;
}

FirstLastNameField* FirstLastNameField::Parse2(
    std::vector<AutoFillField*>::const_iterator* iter) {
  FirstLastNameField v;
  std::vector<AutoFillField*>::const_iterator q = *iter;

  // A fair number of pages use the names "fname" and "lname" for naming
  // first and last name fields (examples from the test suite:
  // BESTBUY_COM - Sign In2.html; Crate and Barrel Check Out.html;
  // dell_checkout1.html).  At least one UK page (The China Shop2.html)
  // asks, in stuffy English style, for just initials and a surname,
  // so we match "initials" here (and just fill in a first name there,
  // American-style).
  // The ".*first$" matches fields ending in "first" (example in sample8.html).
  if (!ParseText(&q,
                 ASCIIToUTF16("first name|firstname|initials|fname|.*first$"),
                 &v.first_name_))
    return NULL;

  // We check for a middle initial before checking for a middle name
  // because at least one page (PC Connection.html) has a field marked
  // as both (the label text is "MI" and the element name is
  // "txtmiddlename"); such a field probably actually represents a
  // middle initial.
  if (ParseText(&q,
                ASCIIToUTF16("^mi|middle initial|middleinitial|m.i."),
                &v.middle_name_)) {
    v.middle_initial_ = true;
  } else {
    ParseText(&q, ASCIIToUTF16("middle name|mname"), &v.middle_name_);
  }

  // The ".*last$" matches fields ending in "last" (example in sample8.html).
  if (!ParseText(&q,
                 ASCIIToUTF16("last name|lastname|lname|surname|.*last$"),
                 &v.last_name_))
    return NULL;

  *iter = q;
  return new FirstLastNameField(v);
}

FirstLastNameField* FirstLastNameField::ParseEcmlName(
    std::vector<AutoFillField*>::const_iterator* iter) {
  FirstLastNameField field;
  std::vector<AutoFillField*>::const_iterator q = *iter;

  string16 pattern = GetEcmlPattern(kEcmlShipToFirstName,
                                    kEcmlBillToFirstName, '|');
  if (!ParseText(&q, pattern, &field.first_name_))
    return NULL;

  pattern = GetEcmlPattern(kEcmlShipToMiddleName, kEcmlBillToMiddleName, '|');
  ParseText(&q, pattern, &field.middle_name_);

  pattern = GetEcmlPattern(kEcmlShipToLastName, kEcmlBillToLastName, '|');
  if (ParseText(&q, pattern, &field.last_name_)) {
    *iter = q;
    return new FirstLastNameField(field);
  }

  return NULL;
}

FirstLastNameField* FirstLastNameField::Parse(
    std::vector<AutoFillField*>::const_iterator* iter,
    bool is_ecml) {
  if (is_ecml) {
    return ParseEcmlName(iter);
  } else {
    FirstLastNameField* v = Parse1(iter);
    if (v != NULL)
      return v;

    return Parse2(iter);
  }
}

bool FirstLastNameField::GetFieldInfo(FieldTypeMap* field_type_map) const {
  bool ok = Add(field_type_map, first_name_, AutoFillType(NAME_FIRST));
  DCHECK(ok);
  ok = ok && Add(field_type_map, last_name_, AutoFillType(NAME_LAST));
  DCHECK(ok);
  AutoFillType type = middle_initial_ ?
      AutoFillType(NAME_MIDDLE_INITIAL) : AutoFillType(NAME_MIDDLE);
  ok = ok && Add(field_type_map, middle_name_, type);
  DCHECK(ok);

  return ok;
}

FirstLastNameField::FirstLastNameField()
    : first_name_(NULL),
      middle_name_(NULL),
      last_name_(NULL),
      middle_initial_(false) {
}

FirstLastNameField::FirstLastNameField(const FirstLastNameField& field)
    : NameField(),
      first_name_(field.first_name_),
      middle_name_(field.middle_name_),
      last_name_(field.last_name_),
      middle_initial_(field.middle_initial_) {
}
<|endoftext|>


<commit_before>
#include <stdlib.h>
#include <v8.h>
#include <node.h>

using namespace node;
using namespace v8;

static Handle<Value> Random (const Arguments&);
static Handle<Value> Rand (const Arguments&);
static Handle<Value> SRand (const Arguments&);
extern "C" void init (Handle<Object>);

static Handle<Value> Random (const Arguments& args) {
  return Number::New(rand()/((double)RAND_MAX + 1));
}

static Handle<Value> Rand (const Arguments& args) {
  return Integer::New(rand());
}

static Handle<Value> SRand (const Arguments& args) {
  if (args.Length() == 0) {
    return ThrowException(Exception::Error(String::New("Usage: srand(n)")));
  }
  srand(args[0]->Int32Value());
  return Undefined();
}

extern "C" void init (Handle<Object> target) {
  HandleScope scope;
  NODE_SET_METHOD(target, "random", Random);
  NODE_SET_METHOD(target, "rand", Rand);
  NODE_SET_METHOD(target, "srand", SRand);
  NODE_SET_METHOD(target, "seed", SRand);
}
<commit_msg>export RAND_MAX const<commit_after>
#include <stdlib.h>
#include <v8.h>
#include <node.h>

using namespace node;
using namespace v8;

static Handle<Value> Random (const Arguments&);
static Handle<Value> Rand (const Arguments&);
static Handle<Value> SRand (const Arguments&);
extern "C" void init (Handle<Object>);

static Handle<Value> Random (const Arguments& args) {
  return Number::New(rand()/((double)RAND_MAX + 1));
}

static Handle<Value> Rand (const Arguments& args) {
  return Integer::New(rand());
}

static Handle<Value> SRand (const Arguments& args) {
  if (args.Length() == 0) {
    return ThrowException(Exception::Error(String::New("Usage: srand(n)")));
  }
  srand(args[0]->Int32Value());
  return Undefined();
}

extern "C" void init (Handle<Object> target) {
  HandleScope scope;
  NODE_SET_METHOD(target, "random", Random);
  NODE_SET_METHOD(target, "rand", Rand);
  NODE_SET_METHOD(target, "srand", SRand);
  NODE_SET_METHOD(target, "seed", SRand);
  NODE_DEFINE_CONSTANT(target, RAND_MAX);
}
<|endoftext|>