<commit_before>#pragma once

#include <memory>

#include "MatrixData.h"

namespace smurff
{
   template<typename YType>
   class MatrixDataTempl : public MatrixData
   {
   public:
      MatrixDataTempl(YType Y) : Y(Y)
      {
      }

      //init and center
      void init_pre() override
      {
         assert(nrow() > 0 && ncol() > 0);

         Ycentered = std::shared_ptr<std::vector<YType> >(new std::vector<YType>());
         Ycentered->push_back(Y.transpose());
         Ycentered->push_back(Y);

         init_cwise_mean();
      }

      PVec<>   dim() const override { return PVec<>({ static_cast<int>(Y.rows()), static_cast<int>(Y.cols()) }); }
      int    nnz() const override { return Y.nonZeros(); }
      double sum() const override { return Y.sum(); }

      double offset_to_mean(const PVec<>& pos) const override
      {
              if (getCenterMode() == CenterModeTypes::CENTER_GLOBAL) return getGlobalMean();
         else if (getCenterMode() == CenterModeTypes::CENTER_VIEW)   return getCwiseMean();
         else if (getCenterMode() == CenterModeTypes::CENTER_ROWS)   return getModeMeanItem(1,pos.at(1));
         else if (getCenterMode() == CenterModeTypes::CENTER_COLS)   return getModeMeanItem(0,pos.at(0));
         else if (getCenterMode() == CenterModeTypes::CENTER_NONE)   return .0;
         assert(false);
         return .0;
      }

      double var_total() const override;
      double sumsq(const SubModel& model) const override;

      YType Y; // eigen matrix with the data

   private:
      std::shared_ptr<std::vector<YType> > Ycentered; // centered versions of original matrix (transposed, original)

   public:
      const std::vector<YType>& getYc() const
      {
         assert(Ycentered);
         return *Ycentered.get();
      }

      std::shared_ptr<std::vector<YType> > getYcPtr() const
      {
         assert(Ycentered);
         return Ycentered;
      }
   };

   template<>
   double MatrixDataTempl<Eigen::MatrixXd>::var_total() const;

   template<>
   double MatrixDataTempl<Eigen::SparseMatrix<double> >::var_total() const;

   template<>
   double MatrixDataTempl<Eigen::MatrixXd>::sumsq(const SubModel &model) const;

   template<>
   double MatrixDataTempl<Eigen::SparseMatrix<double> >::sumsq(const SubModel &model) const;
}
<commit_msg>Fix order of modes in offset_to_mean<commit_after>#pragma once

#include <memory>

#include "MatrixData.h"

namespace smurff
{
   template<typename YType>
   class MatrixDataTempl : public MatrixData
   {
   public:
      MatrixDataTempl(YType Y) : Y(Y)
      {
      }

      //init and center
      void init_pre() override
      {
         assert(nrow() > 0 && ncol() > 0);

         Ycentered = std::shared_ptr<std::vector<YType> >(new std::vector<YType>());
         Ycentered->push_back(Y.transpose());
         Ycentered->push_back(Y);

         init_cwise_mean();
      }

      PVec<>   dim() const override { return PVec<>({ static_cast<int>(Y.rows()), static_cast<int>(Y.cols()) }); }
      int    nnz() const override { return Y.nonZeros(); }
      double sum() const override { return Y.sum(); }

      double offset_to_mean(const PVec<>& pos) const override
      {
              if (getCenterMode() == CenterModeTypes::CENTER_GLOBAL) return getGlobalMean();
         else if (getCenterMode() == CenterModeTypes::CENTER_VIEW)   return getCwiseMean();
         else if (getCenterMode() == CenterModeTypes::CENTER_ROWS)   return getModeMeanItem(0,pos.at(0));
         else if (getCenterMode() == CenterModeTypes::CENTER_COLS)   return getModeMeanItem(1,pos.at(1));
         else if (getCenterMode() == CenterModeTypes::CENTER_NONE)   return .0;
         assert(false);
         return .0;
      }

      double var_total() const override;
      double sumsq(const SubModel& model) const override;

      YType Y; // eigen matrix with the data

   private:
      std::shared_ptr<std::vector<YType> > Ycentered; // centered versions of original matrix (transposed, original)

   public:
      const std::vector<YType>& getYc() const
      {
         assert(Ycentered);
         return *Ycentered.get();
      }

      std::shared_ptr<std::vector<YType> > getYcPtr() const
      {
         assert(Ycentered);
         return Ycentered;
      }
   };

   template<>
   double MatrixDataTempl<Eigen::MatrixXd>::var_total() const;

   template<>
   double MatrixDataTempl<Eigen::SparseMatrix<double> >::var_total() const;

   template<>
   double MatrixDataTempl<Eigen::MatrixXd>::sumsq(const SubModel &model) const;

   template<>
   double MatrixDataTempl<Eigen::SparseMatrix<double> >::sumsq(const SubModel &model) const;
}
<|endoftext|>


<commit_before>// Copyright (C) 2012-2014 Leap Motion, Inc. All rights reserved.
#include "stdafx.h"
#include <autowiring/AutoParameter.h>
#include <limits.h>

class AutoParameterTest:
  public testing::Test
{};

struct MyParamClass1 {
  struct MyIntParam1 {
    static constexpr int Default() { return 15; }
  };

  AutoParameter<int, MyIntParam1> m_param;
};

TEST_F(AutoParameterTest, VerifyCorrectDeconstruction) {
  AutoRequired<MyParamClass1> mpc;
  auto& param = mpc->m_param;

  EXPECT_STREQ("AutoParam.MyParamClass1::MyIntParam1", param.m_key.c_str())
    << "Configuration variable name was not correctly extracted";
}

TEST_F(AutoParameterTest, VerifyDefaultValue) {
  AutoRequired<MyParamClass1> mpc;
  auto& param = mpc->m_param;

  ASSERT_EQ(*param, 15)
    << "Default value was not properly set";
  ASSERT_FALSE(param.IsConfigured())
    << "Using the default value does not mean the parameter should be configured/set";
}

TEST_F(AutoParameterTest, VerifySetShouldCallConfigure) {
  AutoRequired<MyParamClass1> mpc;
  auto& param = mpc->m_param;

  ASSERT_TRUE(param.Set(MyParamClass1::MyIntParam1::Default()) && param.IsConfigured())
    << "Settung the variable should configure it in the auto config manager";
}

TEST_F(AutoParameterTest, VerifyResetToDefaultValue) {
  AutoRequired<MyParamClass1> mpc;
  auto& param = mpc->m_param;

  ASSERT_TRUE(param.Set(30) && *param == 30)
    << "Could not set the parameter to another value";

  // Reset
  param.Set(MyParamClass1::MyIntParam1::Default());

  ASSERT_EQ(*param, 15)
    << "Parameter was not properly reset to its default value";
}

struct MyParamClass2 {
  struct MyIntParam2 {
    static constexpr int Default() { return 15; }
    static bool Validate(const int& value) { return 10 <= value && value <= 20; }
  };

  AutoParameter<int, MyIntParam2> m_param;
};

TEST_F(AutoParameterTest, VerifyValidationFunction) {
  AutoRequired<MyParamClass2> mpc;
  auto& param = mpc->m_param;

  ASSERT_FALSE(param.Set(9))
    << "Set() should return false when setting invalid value";
  ASSERT_EQ(*param, 15)
    << "Failed set attempts should not have altered the previous state";

  ASSERT_TRUE(param.Set(10) && *param == 10)
    << "Should be able to set values that are valid according to the validation function";
}

struct MyParamClass4 {
  struct MyIntParam4 {
    static constexpr int Default() { return 0; }
    static bool Validate(const int& value) { return 10 <= value && value <= 20; }
  };

  AutoParameter<int, MyIntParam4> m_param;
};

TEST_F(AutoParameterTest, VerifyInvalidDefaultValue) {
  ASSERT_ANY_THROW(AutoRequired<MyParamClass4>())
    << "Cannot construct a parameter where default value is invalid";
}
<commit_msg>name change<commit_after>// Copyright (C) 2012-2014 Leap Motion, Inc. All rights reserved.
#include "stdafx.h"
#include <autowiring/AutoParameter.h>
#include <limits.h>

class AutoParameterTest:
  public testing::Test
{};

struct MyParamClass1 {
  struct MyIntParam1 {
    static constexpr int Default() { return 15; }
  };

  AutoParameter<int, MyIntParam1> m_param;
};

TEST_F(AutoParameterTest, VerifyCorrectDeconstruction) {
  AutoRequired<MyParamClass1> mpc;
  auto& param = mpc->m_param;

  EXPECT_STREQ("AutoParam.MyParamClass1::MyIntParam1", param.m_key.c_str())
    << "Configuration variable name was not correctly extracted";
}

TEST_F(AutoParameterTest, VerifyDefaultValue) {
  AutoRequired<MyParamClass1> mpc;
  auto& param = mpc->m_param;

  ASSERT_EQ(*param, 15)
    << "Default value was not properly set";
  ASSERT_FALSE(param.IsConfigured())
    << "Using the default value does not mean the parameter should be configured/set";
}

TEST_F(AutoParameterTest, VerifySetShouldCallConfigure) {
  AutoRequired<MyParamClass1> mpc;
  auto& param = mpc->m_param;

  ASSERT_TRUE(param.Set(MyParamClass1::MyIntParam1::Default()) && param.IsConfigured())
    << "Settung the variable should configure it in the auto config manager";
}

TEST_F(AutoParameterTest, VerifyResetToDefaultValue) {
  AutoRequired<MyParamClass1> mpc;
  auto& param = mpc->m_param;

  ASSERT_TRUE(param.Set(30) && *param == 30)
    << "Could not set the parameter to another value";

  // Reset
  param.Set(MyParamClass1::MyIntParam1::Default());

  ASSERT_EQ(*param, 15)
    << "Parameter was not properly reset to its default value";
}

struct MyParamClass2 {
  struct MyIntParam2 {
    static constexpr int Default() { return 15; }
    static bool Validate(const int& value) { return 10 <= value && value <= 20; }
  };

  AutoParameter<int, MyIntParam2> m_param;
};

TEST_F(AutoParameterTest, VerifyValidationFunction) {
  AutoRequired<MyParamClass2> mpc;
  auto& param = mpc->m_param;

  ASSERT_FALSE(param.Set(9))
    << "Set() should return false when setting invalid value";
  ASSERT_EQ(*param, 15)
    << "Failed set attempts should not have altered the previous state";

  ASSERT_TRUE(param.Set(10) && *param == 10)
    << "Should be able to set values that are valid according to the validation function";
}

struct MyParamClass3 {
  struct MyIntParam3 {
    static constexpr int Default() { return 0; }
    static bool Validate(const int& value) { return 10 <= value && value <= 20; }
  };

  AutoParameter<int, MyIntParam3> m_param;
};

TEST_F(AutoParameterTest, VerifyInvalidDefaultValue) {
  ASSERT_ANY_THROW(AutoRequired<MyParamClass3>())
    << "Cannot construct a parameter where default value is invalid";
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: Pattern.cxx,v $
 *
 *  $Revision: 1.15 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-16 23:52:34 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_forms.hxx"

#ifndef _FORMS_PATTERN_HXX_
#include "Pattern.hxx"
#endif

#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif

//.........................................................................
namespace frm
{
//.........................................................................
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::sdb;
using namespace ::com::sun::star::sdbc;
using namespace ::com::sun::star::sdbcx;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::form;
using namespace ::com::sun::star::awt;
using namespace ::com::sun::star::io;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::util;

//==================================================================
// OPatternControl
//==================================================================
//------------------------------------------------------------------
OPatternControl::OPatternControl(const Reference<XMultiServiceFactory>& _rxFactory)
    :OBoundControl(_rxFactory, VCL_CONTROL_PATTERNFIELD)
{
}

//------------------------------------------------------------------
InterfaceRef SAL_CALL OPatternControl_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory)
{
    return *(new OPatternControl(_rxFactory));
}

//------------------------------------------------------------------------------
Sequence<Type> OPatternControl::_getTypes()
{
    return OBoundControl::_getTypes();
}

//------------------------------------------------------------------------------
StringSequence OPatternControl::getSupportedServiceNames() throw()
{
    StringSequence aSupported = OBoundControl::getSupportedServiceNames();
    aSupported.realloc(aSupported.getLength() + 1);

    ::rtl::OUString*pArray = aSupported.getArray();
    pArray[aSupported.getLength()-1] = FRM_SUN_CONTROL_PATTERNFIELD;
    return aSupported;
}

//==================================================================
// OPatternModel
//==================================================================
//------------------------------------------------------------------
InterfaceRef SAL_CALL OPatternModel_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory)
{
    return *(new OPatternModel(_rxFactory));
}

//------------------------------------------------------------------------------
Sequence<Type> OPatternModel::_getTypes()
{
    return OEditBaseModel::_getTypes();
}

//------------------------------------------------------------------
DBG_NAME( OPatternModel )
//------------------------------------------------------------------
OPatternModel::OPatternModel(const Reference<XMultiServiceFactory>& _rxFactory)
    :OEditBaseModel( _rxFactory, VCL_CONTROLMODEL_PATTERNFIELD, FRM_SUN_CONTROL_PATTERNFIELD, sal_False, sal_False )
                                    // use the old control name for compytibility reasons
{
    DBG_CTOR( OPatternModel, NULL );

    m_nClassId = FormComponentType::PATTERNFIELD;
    initValueProperty( PROPERTY_TEXT, PROPERTY_ID_TEXT );
}

//------------------------------------------------------------------
OPatternModel::OPatternModel( const OPatternModel* _pOriginal, const Reference<XMultiServiceFactory>& _rxFactory )
    :OEditBaseModel( _pOriginal, _rxFactory )
{
    DBG_CTOR( OPatternModel, NULL );
}

//------------------------------------------------------------------
OPatternModel::~OPatternModel()
{
    DBG_DTOR( OPatternModel, NULL );
}

// XCloneable
//------------------------------------------------------------------------------
IMPLEMENT_DEFAULT_CLONING( OPatternModel )

// XServiceInfo
//------------------------------------------------------------------------------
StringSequence SAL_CALL OPatternModel::getSupportedServiceNames() throw()
{
    StringSequence aSupported = OBoundControlModel::getSupportedServiceNames();
    aSupported.realloc(aSupported.getLength() + 2);

    ::rtl::OUString*pArray = aSupported.getArray();
    pArray[aSupported.getLength()-2] = FRM_SUN_COMPONENT_DATABASE_PATTERNFIELD;
    pArray[aSupported.getLength()-1] = FRM_SUN_COMPONENT_PATTERNFIELD;
    return aSupported;
}

//------------------------------------------------------------------------------
Reference<XPropertySetInfo> SAL_CALL OPatternModel::getPropertySetInfo() throw( RuntimeException )
{
    Reference<XPropertySetInfo>  xInfo( createPropertySetInfo( getInfoHelper() ) );
    return xInfo;
}

//------------------------------------------------------------------------------
void OPatternModel::fillProperties(
        Sequence< Property >& _rProps,
        Sequence< Property >& _rAggregateProps ) const
{
    BEGIN_DESCRIBE_PROPERTIES( 4, OEditBaseModel )
        DECL_PROP2(DEFAULT_TEXT,    ::rtl::OUString,    BOUND, MAYBEDEFAULT);
        DECL_BOOL_PROP1(EMPTY_IS_NULL,                  BOUND);
        DECL_PROP1(TABINDEX,        sal_Int16,          BOUND);
        DECL_PROP2(FILTERPROPOSAL,  sal_Bool,           BOUND, MAYBEDEFAULT);
    END_DESCRIBE_PROPERTIES();
}

//------------------------------------------------------------------------------
::cppu::IPropertyArrayHelper& OPatternModel::getInfoHelper()
{
    return *const_cast<OPatternModel*>(this)->getArrayHelper();
}

//------------------------------------------------------------------------------
::rtl::OUString SAL_CALL OPatternModel::getServiceName() throw ( ::com::sun::star::uno::RuntimeException)
{
    return FRM_COMPONENT_PATTERNFIELD;  // old (non-sun) name for compatibility !
}

//------------------------------------------------------------------------------
sal_Bool OPatternModel::commitControlValueToDbColumn( bool /*_bPostReset*/ )
{
    ::rtl::OUString sNewValue;
    m_xAggregateFastSet->getFastPropertyValue( getValuePropertyAggHandle() ) >>= sNewValue;

    if ( sNewValue != m_aSaveValue )
    {
        if ( !sNewValue.getLength() && !isRequired() && m_bEmptyIsNull )
            m_xColumnUpdate->updateNull();
        else
        {
            try
            {
                m_xColumnUpdate->updateString( sNewValue );
            }
            catch(Exception&)
            {
                return sal_False;
            }
        }
        m_aSaveValue = sNewValue;
    }
    return sal_True;
}

// XPropertyChangeListener
//------------------------------------------------------------------------------
Any OPatternModel::translateDbColumnToControlValue()
{
    m_aSaveValue = m_xColumn->getString();
    return makeAny( m_aSaveValue );
}

// XReset
//------------------------------------------------------------------------------
Any OPatternModel::getDefaultForReset() const
{
    return makeAny( m_aDefaultText );
}

//.........................................................................
}   // namespace frm
//.........................................................................

<commit_msg>INTEGRATION: CWS hb02 (1.15.52); FILE MERGED 2007/02/01 12:09:40 fs 1.15.52.2: #i74051# split describeFixedProperties in describeFixedProperties and describeAggregateProperties 2007/01/31 10:55:29 fs 1.15.52.1: changed handling of properties in the course of #i74051#<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: Pattern.cxx,v $
 *
 *  $Revision: 1.16 $
 *
 *  last change: $Author: obo $ $Date: 2007-03-09 13:30:52 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_forms.hxx"

#ifndef _FORMS_PATTERN_HXX_
#include "Pattern.hxx"
#endif

#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif

//.........................................................................
namespace frm
{
//.........................................................................
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::sdb;
using namespace ::com::sun::star::sdbc;
using namespace ::com::sun::star::sdbcx;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::form;
using namespace ::com::sun::star::awt;
using namespace ::com::sun::star::io;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::util;

//==================================================================
// OPatternControl
//==================================================================
//------------------------------------------------------------------
OPatternControl::OPatternControl(const Reference<XMultiServiceFactory>& _rxFactory)
    :OBoundControl(_rxFactory, VCL_CONTROL_PATTERNFIELD)
{
}

//------------------------------------------------------------------
InterfaceRef SAL_CALL OPatternControl_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory)
{
    return *(new OPatternControl(_rxFactory));
}

//------------------------------------------------------------------------------
Sequence<Type> OPatternControl::_getTypes()
{
    return OBoundControl::_getTypes();
}

//------------------------------------------------------------------------------
StringSequence OPatternControl::getSupportedServiceNames() throw()
{
    StringSequence aSupported = OBoundControl::getSupportedServiceNames();
    aSupported.realloc(aSupported.getLength() + 1);

    ::rtl::OUString*pArray = aSupported.getArray();
    pArray[aSupported.getLength()-1] = FRM_SUN_CONTROL_PATTERNFIELD;
    return aSupported;
}

//==================================================================
// OPatternModel
//==================================================================
//------------------------------------------------------------------
InterfaceRef SAL_CALL OPatternModel_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory)
{
    return *(new OPatternModel(_rxFactory));
}

//------------------------------------------------------------------------------
Sequence<Type> OPatternModel::_getTypes()
{
    return OEditBaseModel::_getTypes();
}

//------------------------------------------------------------------
DBG_NAME( OPatternModel )
//------------------------------------------------------------------
OPatternModel::OPatternModel(const Reference<XMultiServiceFactory>& _rxFactory)
    :OEditBaseModel( _rxFactory, VCL_CONTROLMODEL_PATTERNFIELD, FRM_SUN_CONTROL_PATTERNFIELD, sal_False, sal_False )
                                    // use the old control name for compytibility reasons
{
    DBG_CTOR( OPatternModel, NULL );

    m_nClassId = FormComponentType::PATTERNFIELD;
    initValueProperty( PROPERTY_TEXT, PROPERTY_ID_TEXT );
}

//------------------------------------------------------------------
OPatternModel::OPatternModel( const OPatternModel* _pOriginal, const Reference<XMultiServiceFactory>& _rxFactory )
    :OEditBaseModel( _pOriginal, _rxFactory )
{
    DBG_CTOR( OPatternModel, NULL );
}

//------------------------------------------------------------------
OPatternModel::~OPatternModel()
{
    DBG_DTOR( OPatternModel, NULL );
}

// XCloneable
//------------------------------------------------------------------------------
IMPLEMENT_DEFAULT_CLONING( OPatternModel )

// XServiceInfo
//------------------------------------------------------------------------------
StringSequence SAL_CALL OPatternModel::getSupportedServiceNames() throw()
{
    StringSequence aSupported = OBoundControlModel::getSupportedServiceNames();
    aSupported.realloc(aSupported.getLength() + 2);

    ::rtl::OUString*pArray = aSupported.getArray();
    pArray[aSupported.getLength()-2] = FRM_SUN_COMPONENT_DATABASE_PATTERNFIELD;
    pArray[aSupported.getLength()-1] = FRM_SUN_COMPONENT_PATTERNFIELD;
    return aSupported;
}

//------------------------------------------------------------------------------
void OPatternModel::describeFixedProperties( Sequence< Property >& _rProps ) const
{
    BEGIN_DESCRIBE_PROPERTIES( 4, OEditBaseModel )
        DECL_PROP2(DEFAULT_TEXT,    ::rtl::OUString,    BOUND, MAYBEDEFAULT);
        DECL_BOOL_PROP1(EMPTY_IS_NULL,                  BOUND);
        DECL_PROP1(TABINDEX,        sal_Int16,          BOUND);
        DECL_PROP2(FILTERPROPOSAL,  sal_Bool,           BOUND, MAYBEDEFAULT);
    END_DESCRIBE_PROPERTIES();
}

//------------------------------------------------------------------------------
::rtl::OUString SAL_CALL OPatternModel::getServiceName() throw ( ::com::sun::star::uno::RuntimeException)
{
    return FRM_COMPONENT_PATTERNFIELD;  // old (non-sun) name for compatibility !
}

//------------------------------------------------------------------------------
sal_Bool OPatternModel::commitControlValueToDbColumn( bool /*_bPostReset*/ )
{
    ::rtl::OUString sNewValue;
    m_xAggregateFastSet->getFastPropertyValue( getValuePropertyAggHandle() ) >>= sNewValue;

    if ( sNewValue != m_aSaveValue )
    {
        if ( !sNewValue.getLength() && !isRequired() && m_bEmptyIsNull )
            m_xColumnUpdate->updateNull();
        else
        {
            try
            {
                m_xColumnUpdate->updateString( sNewValue );
            }
            catch(Exception&)
            {
                return sal_False;
            }
        }
        m_aSaveValue = sNewValue;
    }
    return sal_True;
}

// XPropertyChangeListener
//------------------------------------------------------------------------------
Any OPatternModel::translateDbColumnToControlValue()
{
    m_aSaveValue = m_xColumn->getString();
    return makeAny( m_aSaveValue );
}

// XReset
//------------------------------------------------------------------------------
Any OPatternModel::getDefaultForReset() const
{
    return makeAny( m_aDefaultText );
}

//.........................................................................
}   // namespace frm
//.........................................................................

<|endoftext|>


<commit_before>/*
 * BloscPlugin.cpp
 *
 *  Created on: 22 Jan 2018
 *      Author: Ulrik Pedersen
 */
#include <cstdlib>
#include <blosc.h>
#include <version.h>
#include <BloscPlugin.h>
#include <DebugLevelLogger.h>

namespace FrameProcessor
{

/**
 * cd_values[7] meaning (see blosc.h):
 *   0: reserved
 *   1: reserved
 *   2: type size
 *   3: uncompressed size
 *   4: compression level
 *   5: 0: shuffle not active, 1: byte shuffle, 2: bit shuffle
 *   6: the actual Blosc compressor to use. See blosc.h
 *
 * @param settings
 * @return
 */
void create_cd_values(const BloscCompressionSettings& settings, std::vector<unsigned int>& cd_values)
{
  if (cd_values.size() < 7) cd_values.resize(7);
  cd_values[0] = 0;
  cd_values[1] = 0;
  cd_values[2] = static_cast<unsigned int>(settings.type_size);
  cd_values[3] = static_cast<unsigned int>(settings.uncompressed_size);
  cd_values[4] = settings.compression_level;
  cd_values[5] = settings.shuffle;
  cd_values[6] = settings.blosc_compressor;
}

/**
* The constructor sets up logging used within the class.
*/
BloscPlugin::BloscPlugin() :
current_acquisition_("")
{
  this->commanded_compression_settings_.blosc_compressor = BLOSC_LZ4;
  this->commanded_compression_settings_.shuffle = BLOSC_BITSHUFFLE;
  this->commanded_compression_settings_.compression_level = 1;
  this->commanded_compression_settings_.type_size = 0;
  this->commanded_compression_settings_.uncompressed_size = 0;
  this->compression_settings_ = this->commanded_compression_settings_;

  // Setup logging for the class
  logger_ = Logger::getLogger("FP.BloscPlugin");
  logger_->setLevel(Level::getAll());
  LOG4CXX_TRACE(logger_, "BloscPlugin constructor");

  //blosc_init(); // not required for blosc >= v1.9
  int ret = 0;
  ret = blosc_set_compressor(BLOSC_LZ4_COMPNAME);
  if (ret < 0) LOG4CXX_ERROR(logger_, "Blosc unable to set compressor: " << BLOSC_LZ4_COMPNAME);
  LOG4CXX_TRACE(logger_, "Blosc Version: " << blosc_get_version_string());
  LOG4CXX_TRACE(logger_, "Blosc list available compressors: " << blosc_list_compressors());
  LOG4CXX_TRACE(logger_, "Blosc current compressor: " << blosc_get_compressor());
}

/**
 * Destructor.
 */
BloscPlugin::~BloscPlugin()
{
  LOG4CXX_DEBUG_LEVEL(3, logger_, "BloscPlugin destructor.");
}

/**
 * Compress one frame, return compressed frame.
 */
boost::shared_ptr<Frame> BloscPlugin::compress_frame(boost::shared_ptr<Frame> src_frame)
{
  int compressed_size = 0;
  BloscCompressionSettings c_settings;
  boost::shared_ptr <Frame> dest_frame;

  const void* src_data_ptr = static_cast<const void*>(
      static_cast<const char*>(src_frame->get_data())
  );

  this->update_compression_settings(src_frame->get_acquisition_id());
  c_settings = this->compression_settings_;
  if (src_frame->get_data_type() >= 0) {
    c_settings.type_size = src_frame->get_data_type_size();
  }
  else { // TODO: This if/else is a hack to work around Frame::data_type_ not being set. See https://jira.diamond.ac.uk/browse/BC-811
    c_settings.type_size = 2; // hack: just default to 16bit per pixel as Excalibur use that
  }
  c_settings.uncompressed_size = src_frame->get_data_size();

  size_t dest_data_size = c_settings.uncompressed_size + BLOSC_MAX_OVERHEAD;
  // TODO: is this malloc really necessary? Can't we get writable DataBlocks somehow?
  void *dest_data_ptr = malloc(dest_data_size);
  if (dest_data_ptr == NULL) {throw std::runtime_error("Failed to malloc buffer for Blosc compression output");}

  try {
    std::stringstream ss_blosc_settings;
    ss_blosc_settings << " compressor=" << blosc_get_compressor()
                      << " threads=" << blosc_get_nthreads()
                      << " clevel=" << c_settings.compression_level
                      << " doshuffle=" << c_settings.shuffle
                      << " typesize=" << c_settings.type_size
                      << " nbytes=" << c_settings.uncompressed_size
                      << " destsize=" << dest_data_size;

    LOG4CXX_DEBUG_LEVEL(2, logger_, "Blosc compression: frame=" << src_frame->get_frame_number()
                            << " acquisition=\"" << src_frame->get_acquisition_id() << "\""
                            << ss_blosc_settings.str()
                            << " src=" << src_data_ptr
                            << " dest=" << dest_data_ptr);
    compressed_size = blosc_compress(c_settings.compression_level, c_settings.shuffle,
                                     c_settings.type_size,
                                     c_settings.uncompressed_size, src_data_ptr,
                                     dest_data_ptr, dest_data_size);
    if (compressed_size < 0) {
      std::stringstream ss;
      ss << "blosc_compress failed. error=" << compressed_size << ss_blosc_settings.str();
      LOG4CXX_ERROR(logger_, ss.str());
      throw std::runtime_error(ss.str());
    }
    double factor = 0.;
    if (compressed_size > 0) {
      factor = (double)src_frame->get_data_size() / (double)compressed_size;
    }
    LOG4CXX_DEBUG_LEVEL(2, logger_, "Blosc compression complete: frame=" << src_frame->get_frame_number()
                                    << " compressed_size=" << compressed_size
                                    << " factor=" << factor);

    dest_frame = boost::shared_ptr<Frame>(new Frame(src_frame->get_dataset_name()));

    LOG4CXX_DEBUG_LEVEL(3, logger_, "Copying compressed data to output frame. (" << compressed_size << " bytes)");
    // I wish we had a pointer swap feature on the Frame class and avoid this unnecessary copy...
    dest_frame->copy_data(dest_data_ptr, compressed_size);
    if (dest_data_ptr != NULL) {free(dest_data_ptr); dest_data_ptr = NULL;}

    // I wish we had a shallow-copy feature on the Frame class...
    dest_frame->set_data_type(src_frame->get_data_type());
    dest_frame->set_frame_number(src_frame->get_frame_number());
    dest_frame->set_acquisition_id(src_frame->get_acquisition_id());
    // TODO: is this the correct way to get and set dimensions?
    dest_frame->set_dimensions(src_frame->get_dimensions());
  }
  catch (const std::exception& e) {
    LOG4CXX_ERROR(logger_, "Serious error in Blosc compression: " << e.what());
    if (dest_data_ptr != NULL) {free(dest_data_ptr); dest_data_ptr = NULL;}
  }
  return dest_frame;
}

/**
 * Update the compression settings used if the acquisition ID differs from the current one.
 * i.e. if a new acquisition has been started.
 *
 * @param acquisition_id
 */
void BloscPlugin::update_compression_settings(const std::string &acquisition_id)
{
  if (acquisition_id != this->current_acquisition_){
    LOG4CXX_DEBUG_LEVEL(1, logger_, "New acquisition detected: "<< acquisition_id);
    this->compression_settings_ = this->commanded_compression_settings_;
    this->current_acquisition_ = acquisition_id;

    int ret = 0;
    const char * p_compressor_name;
    ret = blosc_compcode_to_compname(this->compression_settings_.blosc_compressor, &p_compressor_name);
    LOG4CXX_DEBUG_LEVEL(1, logger_, "Blosc compression new acquisition=\"" << acquisition_id << "\":"
                                    << " compressor=" << p_compressor_name
                                    << " threads=" << blosc_get_nthreads()
                                    << " clevel=" << this->compression_settings_.compression_level
                                    << " doshuffle=" << this->compression_settings_.shuffle
                                    << " typesize=" << this->compression_settings_.type_size
                                    << " nbytes=" << this->compression_settings_.uncompressed_size);
    ret = blosc_set_compressor(p_compressor_name);
    if (ret < 0) {
      LOG4CXX_ERROR(logger_, "Blosc failed to set compressor: "
          << " " << this->compression_settings_.blosc_compressor
          << " " << *p_compressor_name)
      throw std::runtime_error("Blosc failed to set compressor");
    }
  }
}

  /**
 * Perform compression on the frame and output a new, compressed Frame.
 *
 * \param[in] frame - Pointer to a Frame object.
 */
void BloscPlugin::process_frame(boost::shared_ptr<Frame> src_frame)
{
  LOG4CXX_DEBUG_LEVEL(3, logger_, "Received a new frame...");
  boost::shared_ptr <Frame> compressed_frame = this->compress_frame(src_frame);
  LOG4CXX_DEBUG_LEVEL(3, logger_, "Pushing compressed frame");
  this->push(compressed_frame);
}

int BloscPlugin::get_version_major()
{
  return ODIN_DATA_VERSION_MAJOR;
}

int BloscPlugin::get_version_minor()
{
  return ODIN_DATA_VERSION_MINOR;
}

int BloscPlugin::get_version_patch()
{
  return ODIN_DATA_VERSION_PATCH;
}

std::string BloscPlugin::get_version_short()
{
  return ODIN_DATA_VERSION_STR_SHORT;
}

std::string BloscPlugin::get_version_long()
{
  return ODIN_DATA_VERSION_STR;
}

} /* namespace FrameProcessor */
<commit_msg>BloscPlugin: removing large try/catch section<commit_after>/*
 * BloscPlugin.cpp
 *
 *  Created on: 22 Jan 2018
 *      Author: Ulrik Pedersen
 */
#include <cstdlib>
#include <blosc.h>
#include <version.h>
#include <BloscPlugin.h>
#include <DebugLevelLogger.h>

namespace FrameProcessor
{

/**
 * cd_values[7] meaning (see blosc.h):
 *   0: reserved
 *   1: reserved
 *   2: type size
 *   3: uncompressed size
 *   4: compression level
 *   5: 0: shuffle not active, 1: byte shuffle, 2: bit shuffle
 *   6: the actual Blosc compressor to use. See blosc.h
 *
 * @param settings
 * @return
 */
void create_cd_values(const BloscCompressionSettings& settings, std::vector<unsigned int>& cd_values)
{
  if (cd_values.size() < 7) cd_values.resize(7);
  cd_values[0] = 0;
  cd_values[1] = 0;
  cd_values[2] = static_cast<unsigned int>(settings.type_size);
  cd_values[3] = static_cast<unsigned int>(settings.uncompressed_size);
  cd_values[4] = settings.compression_level;
  cd_values[5] = settings.shuffle;
  cd_values[6] = settings.blosc_compressor;
}

/**
* The constructor sets up logging used within the class.
*/
BloscPlugin::BloscPlugin() :
current_acquisition_("")
{
  this->commanded_compression_settings_.blosc_compressor = BLOSC_LZ4;
  this->commanded_compression_settings_.shuffle = BLOSC_BITSHUFFLE;
  this->commanded_compression_settings_.compression_level = 1;
  this->commanded_compression_settings_.type_size = 0;
  this->commanded_compression_settings_.uncompressed_size = 0;
  this->compression_settings_ = this->commanded_compression_settings_;

  // Setup logging for the class
  logger_ = Logger::getLogger("FP.BloscPlugin");
  logger_->setLevel(Level::getAll());
  LOG4CXX_TRACE(logger_, "BloscPlugin constructor");

  //blosc_init(); // not required for blosc >= v1.9
  int ret = 0;
  ret = blosc_set_compressor(BLOSC_LZ4_COMPNAME);
  if (ret < 0) LOG4CXX_ERROR(logger_, "Blosc unable to set compressor: " << BLOSC_LZ4_COMPNAME);
  LOG4CXX_TRACE(logger_, "Blosc Version: " << blosc_get_version_string());
  LOG4CXX_TRACE(logger_, "Blosc list available compressors: " << blosc_list_compressors());
  LOG4CXX_TRACE(logger_, "Blosc current compressor: " << blosc_get_compressor());
}

/**
 * Destructor.
 */
BloscPlugin::~BloscPlugin()
{
  LOG4CXX_DEBUG_LEVEL(3, logger_, "BloscPlugin destructor.");
}

/**
 * Compress one frame, return compressed frame.
 */
boost::shared_ptr<Frame> BloscPlugin::compress_frame(boost::shared_ptr<Frame> src_frame)
{
  int compressed_size = 0;
  BloscCompressionSettings c_settings;
  boost::shared_ptr <Frame> dest_frame;

  const void* src_data_ptr = static_cast<const void*>(
      static_cast<const char*>(src_frame->get_data())
  );

  this->update_compression_settings(src_frame->get_acquisition_id());
  c_settings = this->compression_settings_;
  if (src_frame->get_data_type() >= 0) {
    c_settings.type_size = src_frame->get_data_type_size();
  }
  else { // TODO: This if/else is a hack to work around Frame::data_type_ not being set. See https://jira.diamond.ac.uk/browse/BC-811
    c_settings.type_size = 2; // hack: just default to 16bit per pixel as Excalibur use that
  }
  c_settings.uncompressed_size = src_frame->get_data_size();

  size_t dest_data_size = c_settings.uncompressed_size + BLOSC_MAX_OVERHEAD;
  // TODO: is this malloc really necessary? Can't we get writable DataBlocks somehow?
  void *dest_data_ptr = malloc(dest_data_size);
  if (dest_data_ptr == NULL) {throw std::runtime_error("Failed to malloc buffer for Blosc compression output");}

  std::stringstream ss_blosc_settings;
  ss_blosc_settings << " compressor=" << blosc_get_compressor()
                    << " threads=" << blosc_get_nthreads()
                    << " clevel=" << c_settings.compression_level
                    << " doshuffle=" << c_settings.shuffle
                    << " typesize=" << c_settings.type_size
                    << " nbytes=" << c_settings.uncompressed_size
                    << " destsize=" << dest_data_size;

  LOG4CXX_DEBUG_LEVEL(2, logger_, "Blosc compression: frame=" << src_frame->get_frame_number()
                          << " acquisition=\"" << src_frame->get_acquisition_id() << "\""
                          << ss_blosc_settings.str()
                          << " src=" << src_data_ptr
                          << " dest=" << dest_data_ptr);
  compressed_size = blosc_compress(c_settings.compression_level, c_settings.shuffle,
                                   c_settings.type_size,
                                   c_settings.uncompressed_size, src_data_ptr,
                                   dest_data_ptr, dest_data_size);
  if (compressed_size < 0) {
    std::stringstream ss;
    ss << "blosc_compress failed. error=" << compressed_size << ss_blosc_settings.str();
    LOG4CXX_ERROR(logger_, ss.str());
    throw std::runtime_error(ss.str());
  }
  double factor = 0.;
  if (compressed_size > 0) {
    factor = (double)src_frame->get_data_size() / (double)compressed_size;
  }
  LOG4CXX_DEBUG_LEVEL(2, logger_, "Blosc compression complete: frame=" << src_frame->get_frame_number()
                                  << " compressed_size=" << compressed_size
                                  << " factor=" << factor);

  dest_frame = boost::shared_ptr<Frame>(new Frame(src_frame->get_dataset_name()));

  LOG4CXX_DEBUG_LEVEL(3, logger_, "Copying compressed data to output frame. (" << compressed_size << " bytes)");
  // I wish we had a pointer swap feature on the Frame class and avoid this unnecessary copy...
  dest_frame->copy_data(dest_data_ptr, compressed_size);
  if (dest_data_ptr != NULL) {free(dest_data_ptr); dest_data_ptr = NULL;}

  // I wish we had a shallow-copy feature on the Frame class...
  dest_frame->set_data_type(src_frame->get_data_type());
  dest_frame->set_frame_number(src_frame->get_frame_number());
  dest_frame->set_acquisition_id(src_frame->get_acquisition_id());
  // TODO: is this the correct way to get and set dimensions?
  dest_frame->set_dimensions(src_frame->get_dimensions());
  return dest_frame;
}

/**
 * Update the compression settings used if the acquisition ID differs from the current one.
 * i.e. if a new acquisition has been started.
 *
 * @param acquisition_id
 */
void BloscPlugin::update_compression_settings(const std::string &acquisition_id)
{
  if (acquisition_id != this->current_acquisition_){
    LOG4CXX_DEBUG_LEVEL(1, logger_, "New acquisition detected: "<< acquisition_id);
    this->compression_settings_ = this->commanded_compression_settings_;
    this->current_acquisition_ = acquisition_id;

    int ret = 0;
    const char * p_compressor_name;
    ret = blosc_compcode_to_compname(this->compression_settings_.blosc_compressor, &p_compressor_name);
    LOG4CXX_DEBUG_LEVEL(1, logger_, "Blosc compression new acquisition=\"" << acquisition_id << "\":"
                                    << " compressor=" << p_compressor_name
                                    << " threads=" << blosc_get_nthreads()
                                    << " clevel=" << this->compression_settings_.compression_level
                                    << " doshuffle=" << this->compression_settings_.shuffle
                                    << " typesize=" << this->compression_settings_.type_size
                                    << " nbytes=" << this->compression_settings_.uncompressed_size);
    ret = blosc_set_compressor(p_compressor_name);
    if (ret < 0) {
      LOG4CXX_ERROR(logger_, "Blosc failed to set compressor: "
          << " " << this->compression_settings_.blosc_compressor
          << " " << *p_compressor_name)
      throw std::runtime_error("Blosc failed to set compressor");
    }
  }
}

  /**
 * Perform compression on the frame and output a new, compressed Frame.
 *
 * \param[in] frame - Pointer to a Frame object.
 */
void BloscPlugin::process_frame(boost::shared_ptr<Frame> src_frame)
{
  LOG4CXX_DEBUG_LEVEL(3, logger_, "Received a new frame...");
  boost::shared_ptr <Frame> compressed_frame = this->compress_frame(src_frame);
  LOG4CXX_DEBUG_LEVEL(3, logger_, "Pushing compressed frame");
  this->push(compressed_frame);
}

int BloscPlugin::get_version_major()
{
  return ODIN_DATA_VERSION_MAJOR;
}

int BloscPlugin::get_version_minor()
{
  return ODIN_DATA_VERSION_MINOR;
}

int BloscPlugin::get_version_patch()
{
  return ODIN_DATA_VERSION_PATCH;
}

std::string BloscPlugin::get_version_short()
{
  return ODIN_DATA_VERSION_STR_SHORT;
}

std::string BloscPlugin::get_version_long()
{
  return ODIN_DATA_VERSION_STR;
}

} /* namespace FrameProcessor */
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   T2 Relaxation Map
  Module:    Compute T2 Relaxation Map Filter
  Language:  C++

  Copyright (c) University of North Carolina at Chapel Hill (UNC-CH) All Rights Reserved.

  See License.txt for details.

==========================================================================*/

#ifndef __itkT2RelaxationMapFilter_hxx
#define __itkT2RelaxationMapFilter_hxx

#include "itkT2RelaxationMapFilter.h"

using namespace std;

namespace itk
{

  template <class TInputImage, class TOutputImage>
  T2RelaxationMapFilter<TInputImage, TOutputImage>
  ::T2RelaxationMapFilter()
  {
    this->SetNumberOfRequiredInputs( 1 );
    this->SetNumberOfRequiredOutputs( 1 );

    m_M0 = 1;
  }

  template <class TInput, class TOutput>
  void
  T2RelaxationMapFilter<TInput, TOutput>
  ::BeforeThreadedGenerateData(){
    InputImageConstPointer inputImage = this->GetInput();
    int numComponents = inputImage->GetNumberOfComponentsPerPixel();

    m_EchoTimes = vnl_vector<double>(numComponents);
    double echotime = this->GetEchoTime();

    for(int i = 0; i < numComponents; i++){
      m_EchoTimes[i] = echotime*(i+1);
    }
  }

  template <class TInput, class TOutput>
  void
  T2RelaxationMapFilter<TInput, TOutput>
  ::ThreadedGenerateData( const OutputImageRegionType & outputRegionForThread,
                          ThreadIdType itkNotUsed(threadId)){

    InputImageConstPointer inputImage = this->GetInput();
    InputImageIteratorType  init( inputImage, outputRegionForThread );

    OutputImagePointerType  outputImagePtr = this->GetOutput( 0 );
    OutputImageIteratorType  outit( outputImagePtr, outputRegionForThread );

    init.GoToBegin();
    outit.GoToBegin();

    int numComponents = inputImage->GetNumberOfComponentsPerPixel();
    vnl_vector<double> Y = vnl_vector<double>(numComponents);

    t2Fitting t2fit(numComponents);
    t2fit.SetX(m_EchoTimes);
    t2fit.SetM0(m_M0);

    while(!init.IsAtEnd()){

      InputImagePixelType t2values = init.Get();
      for(int i = 0; i < numComponents; i++){
        Y[i] = t2values[i] + 1;
      }

      t2fit.SetY(Y);

      vnl_vector<double> b(1, 1);

      vnl_levenberg_marquardt optimizer(t2fit);
      optimizer.minimize(b);

      if(b[0] != 0 && !isnan(b[0])){
        outit.Set(-1.0/b[0]);
      }

      ++init;
      ++outit;
    }

  }

}

#endif<commit_msg>BUG: Initialize map when wrong value<commit_after>/*=========================================================================

  Program:   T2 Relaxation Map
  Module:    Compute T2 Relaxation Map Filter
  Language:  C++

  Copyright (c) University of North Carolina at Chapel Hill (UNC-CH) All Rights Reserved.

  See License.txt for details.

==========================================================================*/

#ifndef __itkT2RelaxationMapFilter_hxx
#define __itkT2RelaxationMapFilter_hxx

#include "itkT2RelaxationMapFilter.h"

using namespace std;

namespace itk
{

  template <class TInputImage, class TOutputImage>
  T2RelaxationMapFilter<TInputImage, TOutputImage>
  ::T2RelaxationMapFilter()
  {
    this->SetNumberOfRequiredInputs( 1 );
    this->SetNumberOfRequiredOutputs( 1 );

    m_M0 = 1;
  }

  template <class TInput, class TOutput>
  void
  T2RelaxationMapFilter<TInput, TOutput>
  ::BeforeThreadedGenerateData(){
    InputImageConstPointer inputImage = this->GetInput();
    int numComponents = inputImage->GetNumberOfComponentsPerPixel();

    m_EchoTimes = vnl_vector<double>(numComponents);
    double echotime = this->GetEchoTime();

    for(int i = 0; i < numComponents; i++){
      m_EchoTimes[i] = echotime*(i+1);
    }
  }

  template <class TInput, class TOutput>
  void
  T2RelaxationMapFilter<TInput, TOutput>
  ::ThreadedGenerateData( const OutputImageRegionType & outputRegionForThread,
                          ThreadIdType itkNotUsed(threadId)){

    InputImageConstPointer inputImage = this->GetInput();
    InputImageIteratorType  init( inputImage, outputRegionForThread );

    OutputImagePointerType  outputImagePtr = this->GetOutput( 0 );
    OutputImageIteratorType  outit( outputImagePtr, outputRegionForThread );

    init.GoToBegin();
    outit.GoToBegin();

    int numComponents = inputImage->GetNumberOfComponentsPerPixel();
    vnl_vector<double> Y = vnl_vector<double>(numComponents);

    t2Fitting t2fit(numComponents);
    t2fit.SetX(m_EchoTimes);
    t2fit.SetM0(m_M0);

    while(!init.IsAtEnd()){

      InputImagePixelType t2values = init.Get();
      for(int i = 0; i < numComponents; i++){
        Y[i] = t2values[i] + 1;
      }

      t2fit.SetY(Y);

      vnl_vector<double> b(1, 1);

      vnl_levenberg_marquardt optimizer(t2fit);
      optimizer.minimize(b);

      if(b[0] != 0 && !isnan(b[0])){
        outit.Set(-1.0/b[0]);
      }else{
        outit.Set(0);
      }

      ++init;
      ++outit;
    }

  }

}

#endif
<|endoftext|>


<commit_before>/**
 * elf_parser.cpp - Implementation of ELF binary perser
 * @author Alexander Titov <alexander.igorevich.titov@gmail.com>
 * Copyright 2012 uArchSim iLab project
 */

// Genereic C
#include <libelf.h>
#include <cstdio>
#include <unistd.h>
#include <cstring>
#include <fcntl.h>
#include <gelf.h>
#include <cstdlib>
#include <cerrno>
#include <cassert>

// Generic C++
#include <iostream>
#include <string>
#include <sstream>

// uArchSim modules
#include <elf_parser.h>

using namespace std;

ElfSection::ElfSection( const char* elf_file_name, const char* section_name)
{
    // open the binary file, we have to use C-style open,
    // because it is required by elf_begin function
    int file_descr = open( elf_file_name, O_RDONLY);
    if ( file_descr < 0)
    {
        cerr << "ERROR: Could not open file " << elf_file_name << ": "
             << strerror( errno) << endl;
        exit( EXIT_FAILURE);
    }

    // set ELF library operating version
    if ( elf_version( EV_CURRENT) == EV_NONE)
    {
        cerr << "ERROR: Could not set ELF library operating version:"
             <<  elf_errmsg( elf_errno()) << endl;
        exit( EXIT_FAILURE);
    }

    // open the file in ELF format
    Elf* elf = elf_begin( file_descr, ELF_C_READ, NULL);
    if ( !elf)
    {
        cerr << "ERROR: Could not open file " << elf_file_name
             << " as ELF file: "
             <<  elf_errmsg( elf_errno()) << endl;
        exit( EXIT_FAILURE);
    }

    // set the name of the sections
    this->name = new char[ strlen( section_name) + 1];
    strcpy( this->name, section_name);

    // set the size, start address and offset
    uint64 offset = NO_VAL64;
    this->extractSectionParams( elf, section_name,
        offset, this->size, this->start_addr);

    // allocate place for the content
    this->content = new uint8[ this->size + 1];

    lseek( file_descr, offset, SEEK_SET);
    FILE *file = fdopen( file_descr, "r");
    if ( !file )
    {
        cerr << "ERROR: Could not open file " << elf_file_name << ": "
             << strerror(errno) << endl;
        exit( EXIT_FAILURE);
    }

    // fill the content by the section data
    fread( this->content, sizeof( uint8), this->size, file);

    // close all used files
    fclose( file);
    elf_end( elf);
    close( file_descr);
}

ElfSection::~ElfSection()
{
    delete [] this->name;
    delete [] this->content;
}

void ElfSection::extractSectionParams( Elf* elf, const char* section_name,
                                       uint64& offset, uint64& size,
                                       uint64& start_addr)
{
    size_t shstrndx;
    elf_getshdrstrndx( elf, &shstrndx);

    // look through all sections and try to find the desired one
    Elf_Scn *section = NULL;
    while ( ( section = elf_nextscn( elf, section)) != NULL)
    {
        GElf_Shdr shdr;
        gelf_getshdr( section, &shdr);
        char* name = elf_strptr( elf, shstrndx, shdr.sh_name);

        // if a section with the decired name
        // then set its start address, size and offset
        // and return back from the function.
        if ( !strcmp( name, section_name))
        {
            offset = ( uint64)shdr.sh_offset;
            size = ( uint64)shdr.sh_size;
            start_addr = ( uint64)shdr.sh_addr;

            return;
        }
    }

    cerr << "ERROR: Could not find section " << section_name
         << " in ELF file!" << endl;
    exit( EXIT_FAILURE);
}

uint64 ElfSection::read( uint64 addr, short num_of_bytes) const
{
    assert( num_of_bytes < sizeof( uint64));
    assert( isInside( addr, num_of_bytes));
    uint64 data = 0;
    for ( short i = num_of_bytes; i > 0; --i)
    {
        short the_num_of_byte = addr - this->start_addr + i - 1;
        data <<= 8;
        data |= this->content[the_num_of_byte];
    }
    cout << "\n\nit my debug print!\ndata=" << hex << data << endl;
    return data;
}

bool ElfSection::isInside( uint64 addr, short num_of_bytes) const
{
    cout << "\nstart_addr = " << start_addr << "\naddr = "
         << addr << endl;
    assert( num_of_bytes);
    if (this->start_addr > addr)
    {
        return false;
    }
    if ( this->start_addr + this->size >= addr + num_of_bytes)
    {
        return true;
    }
    return false;
}

uint64 ElfSection::startAddr() const
{
    assert(start_addr);
    return start_addr;
}

string ElfSection::dump( string indent) const
{
    ostringstream oss;

    oss << indent << "Dump ELF section \"" << this->name << "\"" << endl
        << indent << "  size = " << this->size << " Bytes" << endl
        << indent << "  start_addr = 0x" << hex << this->start_addr << dec << endl
        << indent << "  Content:" << endl;

    string str = this->strByBytes();

    // split the contents into words of 4 bytes
    for ( size_t offset = 0; offset < this->size; offset += sizeof( uint32))
    {
        oss << indent << "    0x" << hex << ( this->start_addr + offset)
            << indent << ":    " << str.substr( 2 * offset, // 2 hex digits is need per byte
                                                sizeof( uint64))
	        << endl;
    }

    return oss.str();
}

string ElfSection::strByBytes() const
{
    // temp stream is used to convert numbers into the output string
    ostringstream oss;
    oss << hex;

    // convert each byte into 2 hex digits
    for( size_t i = 0; i < this->size; ++i)
    {
        oss.width( 2); // because we need two hex symbols to print a byte (e.g. "ff")
        oss.fill( '0'); // thus, number 8 will be printed as "08"

        // print a value of
        oss << (uint16) *( this->content + i); // need converting to uint16
                                               // to be not preinted as an alphabet symbol
    }

    return oss.str();
}

string ElfSection::strByWords() const
{
    // temp stream is used to convert numbers into the output string
    ostringstream oss;
    oss << hex;

    // convert each words of 4 bytes into 8 hex digits
    for( size_t i = 0; i < this->size/sizeof( uint32); ++i)
    {
        oss.width( 8); // because we need 8 hex symbols to print a word (e.g. "ffffffff")
        oss.fill( '0'); // thus, number a44f will be printed as "0000a44f"

        oss << *( ( uint32*)this->content + i);
    }

    return oss.str();
}

<commit_msg>[trunk] revert changes of Yuri Samarin<commit_after>/**
 * elf_parser.cpp - Implementation of ELF binary perser
 * @author Alexander Titov <alexander.igorevich.titov@gmail.com>
 * Copyright 2012 uArchSim iLab project
 */

// Genereic C
#include <libelf.h>
#include <cstdio>
#include <unistd.h>
#include <cstring>
#include <fcntl.h>
#include <gelf.h>
#include <cstdlib>
#include <cerrno>
#include <cassert>

// Generic C++
#include <iostream>
#include <string>
#include <sstream>

// uArchSim modules
#include <elf_parser.h>

using namespace std;

ElfSection::ElfSection( const char* elf_file_name, const char* section_name)
{
    // open the binary file, we have to use C-style open,
    // because it is required by elf_begin function
    int file_descr = open( elf_file_name, O_RDONLY);
    if ( file_descr < 0)
    {
        cerr << "ERROR: Could not open file " << elf_file_name << ": "
             << strerror( errno) << endl;
        exit( EXIT_FAILURE);
    }

    // set ELF library operating version
    if ( elf_version( EV_CURRENT) == EV_NONE)
    {
        cerr << "ERROR: Could not set ELF library operating version:"
             <<  elf_errmsg( elf_errno()) << endl;
        exit( EXIT_FAILURE);
    }

    // open the file in ELF format
    Elf* elf = elf_begin( file_descr, ELF_C_READ, NULL);
    if ( !elf)
    {
        cerr << "ERROR: Could not open file " << elf_file_name
             << " as ELF file: "
             <<  elf_errmsg( elf_errno()) << endl;
        exit( EXIT_FAILURE);
    }

    // set the name of the sections
    this->name = new char[ strlen( section_name) + 1];
    strcpy( this->name, section_name);

    // set the size, start address and offset
    uint64 offset = NO_VAL64;
    this->extractSectionParams( elf, section_name,
        offset, this->size, this->start_addr);

    // allocate place for the content
    this->content = new uint8[ this->size + 1];

    lseek( file_descr, offset, SEEK_SET);
    FILE *file = fdopen( file_descr, "r");
    if ( !file )
    {
        cerr << "ERROR: Could not open file " << elf_file_name << ": "
             << strerror(errno) << endl;
        exit( EXIT_FAILURE);
    }

    // fill the content by the section data
    fread( this->content, sizeof( uint8), this->size, file);

    // close all used files
    fclose( file);
    elf_end( elf);
    close( file_descr);
}

ElfSection::~ElfSection()
{
    delete [] this->name;
    delete [] this->content;
}

void ElfSection::extractSectionParams( Elf* elf, const char* section_name,
                                       uint64& offset, uint64& size,
                                       uint64& start_addr)
{
    size_t shstrndx;
    elf_getshdrstrndx( elf, &shstrndx);

    // look through all sections and try to find the desired one
    Elf_Scn *section = NULL;
    while ( ( section = elf_nextscn( elf, section)) != NULL)
    {
        GElf_Shdr shdr;
        gelf_getshdr( section, &shdr);
        char* name = elf_strptr( elf, shstrndx, shdr.sh_name);

        // if a section with the decired name
        // then set its start address, size and offset
        // and return back from the function.
        if ( !strcmp( name, section_name))
        {
            offset = ( uint64)shdr.sh_offset;
            size = ( uint64)shdr.sh_size;
            start_addr = ( uint64)shdr.sh_addr;

            return;
        }
    }

    cerr << "ERROR: Could not find section " << section_name
         << " in ELF file!" << endl;
    exit( EXIT_FAILURE);
}

uint64 ElfSection::read( uint64 addr, short num_of_bytes) const
{
    // insert here your implementation
    assert(0);
    return NO_VAL64;
}

bool ElfSection::isInside( uint64 addr, short num_of_bytes) const
{
    // insert here your implementation
    assert(0);
    return false;
}

uint64 ElfSection::startAddr() const
{
    // insert here your implementation
    assert(0);
    return NO_VAL64;
}

string ElfSection::dump( string indent) const
{
    ostringstream oss;

    oss << indent << "Dump ELF section \"" << this->name << "\"" << endl
        << indent << "  size = " << this->size << " Bytes" << endl
        << indent << "  start_addr = 0x" << hex << this->start_addr << dec << endl
        << indent << "  Content:" << endl;

    string str = this->strByBytes();

    // split the contents into words of 4 bytes
    for ( size_t offset = 0; offset < this->size; offset += sizeof( uint32))
    {
        oss << indent << "    0x" << hex << ( this->start_addr + offset)
            << indent << ":    " << str.substr( 2 * offset, // 2 hex digits is need per byte
                                                sizeof( uint64))
	        << endl;
    }

    return oss.str();
}

string ElfSection::strByBytes() const
{
    // temp stream is used to convert numbers into the output string
    ostringstream oss;
    oss << hex;

    // convert each byte into 2 hex digits
    for( size_t i = 0; i < this->size; ++i)
    {
        oss.width( 2); // because we need two hex symbols to print a byte (e.g. "ff")
        oss.fill( '0'); // thus, number 8 will be printed as "08"

        // print a value of
        oss << (uint16) *( this->content + i); // need converting to uint16
                                               // to be not preinted as an alphabet symbol
    }

    return oss.str();
}

string ElfSection::strByWords() const
{
    // temp stream is used to convert numbers into the output string
    ostringstream oss;
    oss << hex;

    // convert each words of 4 bytes into 8 hex digits
    for( size_t i = 0; i < this->size/sizeof( uint32); ++i)
    {
        oss.width( 8); // because we need 8 hex symbols to print a word (e.g. "ffffffff")
        oss.fill( '0'); // thus, number a44f will be printed as "0000a44f"

        oss << *( ( uint32*)this->content + i);
    }

    return oss.str();
}

<|endoftext|>


<commit_before>#include "APS2.h"
#include <sstream>

using std::ostringstream;
using std::endl;

string APS2::printStatusRegisters(const APS_Status_Registers & status) {
	ostringstream ret;

	ret << "Host Firmware Version = " << std::hex << status.hostFirmwareVersion << endl;
	ret << "User Firmware Version = " << std::hex << status.userFirmwareVersion << endl;
	ret << "Configuration Source  = " << status.configurationSource << endl;
	ret << "User Status           = " << status.userStatus << endl;
	ret << "DAC 0 Status          = " << status.dac0Status << endl;
	ret << "DAC 1 Status          = " << status.dac1Status << endl;
	ret << "PLL Status            = " << status.pllStatus << endl;
	ret << "VCXO Status           = " << status.vcxoStatus << endl;
	ret << "Send Packet Count     = " << status.sendPacketCount << endl;
	ret << "Recv Packet Count     = " << status.receivePacketCount << endl;
	ret << "Seq Skip Count        = " << status.sequenceSkipCount << endl;
	ret << "Seq Dup  Count        = " << status.sequenceDupCount << endl;
	ret << "Uptime                = " << status.uptime << endl;
	ret << "Reserved 1            = " << status.reserved1 << endl;
	ret << "Reserved 2            = " << status.reserved2 << endl;
	ret << "Reserved 3            = " << status.reserved3 << endl;
	return ret.str();
}

string APS2::printAPSCommand(APSCommand * cmd) {
    ostringstream ret;

    uint32_t * packedCmd;

    packedCmd = reinterpret_cast<uint32_t *>(cmd);

    ret << std::hex << *packedCmd << " =";
    ret << " ACK: " << cmd->ack;
    ret << " SEQ: " << cmd->seq;
    ret << " SEL: " << cmd->sel;
    ret << " R/W: " << cmd->r_w;
    ret << " CMD: " << cmd->cmd;
    ret << " MODE/STAT: " << cmd->mode_stat;
    ret << std::dec << " cnt: " << cmd->cnt;
    return ret.str();
}

void APS2::zeroAPSCommand(APSCommand * command) {
	uint32_t * packedCmd;
    packedCmd = reinterpret_cast<uint32_t *>(command);
    packedCmd = 0;
}

uint8_t * APS2::getPayloadPtr(uint8_t * packet) {
	uint8_t * start = reinterpret_cast<uint8_t *>(packet);
    start += sizeof(APSEthernetHeader);
	return start;
}

<commit_msg>Added chip config IO commands to APS2<commit_after>#include "APS2.h"
#include <sstream>

using std::ostringstream;
using std::endl;

string APS2::printStatusRegisters(const APS_Status_Registers & status) {
	ostringstream ret;

	ret << "Host Firmware Version = " << std::hex << status.hostFirmwareVersion << endl;
	ret << "User Firmware Version = " << std::hex << status.userFirmwareVersion << endl;
	ret << "Configuration Source  = " << status.configurationSource << endl;
	ret << "User Status           = " << status.userStatus << endl;
	ret << "DAC 0 Status          = " << status.dac0Status << endl;
	ret << "DAC 1 Status          = " << status.dac1Status << endl;
	ret << "PLL Status            = " << status.pllStatus << endl;
	ret << "VCXO Status           = " << status.vcxoStatus << endl;
	ret << "Send Packet Count     = " << status.sendPacketCount << endl;
	ret << "Recv Packet Count     = " << status.receivePacketCount << endl;
	ret << "Seq Skip Count        = " << status.sequenceSkipCount << endl;
	ret << "Seq Dup  Count        = " << status.sequenceDupCount << endl;
	ret << "Uptime                = " << status.uptime << endl;
	ret << "Reserved 1            = " << status.reserved1 << endl;
	ret << "Reserved 2            = " << status.reserved2 << endl;
	ret << "Reserved 3            = " << status.reserved3 << endl;
	return ret.str();
}

string APS2::printAPSCommand(APSCommand_t & cmd) {
    ostringstream ret;

    ret << std::hex << cmd.packed << " =";
    ret << " ACK: " << cmd.ack;
    ret << " SEQ: " << cmd.seq;
    ret << " SEL: " << cmd.sel;
    ret << " R/W: " << cmd.r_w;
    ret << " CMD: " << cmd.cmd;
    ret << " MODE/STAT: " << cmd.mode_stat;
    ret << std::dec << " cnt: " << cmd.cnt;
    return ret.str();
}

string APS2::printAPSChipCommand(APSChipConfigCommand_t & cmd) {
    ostringstream ret;

    ret << std::hex << cmd.packed << " =";
    ret << " Target: " << cmd.target;
    ret << " SPICNT_DATA: " << cmd.spicnt_data;
    ret << " INSTR: " << cmd.instr;
    return ret.str();
}

uint32_t * APS2::getPayloadPtr(uint32_t * frame) {
   frame += sizeof(APSEthernetHeader) / sizeof(uint32_t);
   return frame;
}

<|endoftext|>


<commit_before>/*
 * Copyright © 2010 Intel Corporation
 *
 * 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 (including the next
 * paragraph) 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.
 */

/**
 * \file opt_array_splitting.cpp
 *
 * If an array is always dereferenced with a constant index, then
 * split it apart into its elements, making it more amenable to other
 * optimization passes.
 *
 * This skips uniform/varying arrays, which would need careful
 * handling due to their ir->location fields tying them to the GL API
 * and other shader stages.
 */

#include "ir.h"
#include "ir_visitor.h"
#include "ir_rvalue_visitor.h"
#include "compiler/glsl_types.h"

static bool debug = false;

namespace {

namespace opt_array_splitting {

class variable_entry : public exec_node
{
public:
   variable_entry(ir_variable *var)
   {
      this->var = var;
      this->split = true;
      this->declaration = false;
      this->components = NULL;
      this->mem_ctx = NULL;
      if (var->type->is_array())
         this->size = var->type->length;
      else
         this->size = var->type->matrix_columns;
   }

   ir_variable *var; /* The key: the variable's pointer. */
   unsigned size; /* array length or matrix columns */

   /** Whether this array should be split or not. */
   bool split;

   /* If the variable had a decl we can work with in the instruction
    * stream.  We can't do splitting on function arguments, which
    * don't get this variable set.
    */
   bool declaration;

   ir_variable **components;

   /** ralloc_parent(this->var) -- the shader's talloc context. */
   void *mem_ctx;
};

} /* namespace */

using namespace opt_array_splitting;

/**
 * This class does a walk over the tree, coming up with the set of
 * variables that could be split by looking to see if they are arrays
 * that are only ever constant-index dereferenced.
 */
class ir_array_reference_visitor : public ir_hierarchical_visitor {
public:
   ir_array_reference_visitor(void)
   {
      this->mem_ctx = ralloc_context(NULL);
      this->variable_list.make_empty();
   }

   ~ir_array_reference_visitor(void)
   {
      ralloc_free(mem_ctx);
   }

   bool get_split_list(exec_list *instructions, bool linked);

   virtual ir_visitor_status visit(ir_variable *);
   virtual ir_visitor_status visit(ir_dereference_variable *);
   virtual ir_visitor_status visit_enter(ir_dereference_array *);
   virtual ir_visitor_status visit_enter(ir_function_signature *);

   variable_entry *get_variable_entry(ir_variable *var);

   /* List of variable_entry */
   exec_list variable_list;

   void *mem_ctx;
};

} /* namespace */

variable_entry *
ir_array_reference_visitor::get_variable_entry(ir_variable *var)
{
   assert(var);

   if (var->data.mode != ir_var_auto &&
       var->data.mode != ir_var_temporary)
      return NULL;

   if (!(var->type->is_array() || var->type->is_matrix()))
      return NULL;

   /* If the array hasn't been sized yet, we can't split it.  After
    * linking, this should be resolved.
    */
   if (var->type->is_unsized_array())
      return NULL;

   foreach_in_list(variable_entry, entry, &this->variable_list) {
      if (entry->var == var)
         return entry;
   }

   variable_entry *entry = new(mem_ctx) variable_entry(var);
   this->variable_list.push_tail(entry);
   return entry;
}

ir_visitor_status
ir_array_reference_visitor::visit(ir_variable *ir)
{
   variable_entry *entry = this->get_variable_entry(ir);

   if (entry)
      entry->declaration = true;

   return visit_continue;
}

ir_visitor_status
ir_array_reference_visitor::visit(ir_dereference_variable *ir)
{
   variable_entry *entry = this->get_variable_entry(ir->var);

   /* If we made it to here without seeing an ir_dereference_array,
    * then the dereference of this array didn't have a constant index
    * (see the visit_continue_with_parent below), so we can't split
    * the variable.
    */
   if (entry)
      entry->split = false;

   return visit_continue;
}

ir_visitor_status
ir_array_reference_visitor::visit_enter(ir_dereference_array *ir)
{
   ir_dereference_variable *deref = ir->array->as_dereference_variable();
   if (!deref)
      return visit_continue;

   variable_entry *entry = this->get_variable_entry(deref->var);

   /* If the access to the array has a variable index, we wouldn't
    * know which split variable this dereference should go to.
    */
   if (!ir->array_index->as_constant()) {
      if (entry)
         entry->split = false;
      /* This variable indexing could come from a different array dereference
       * that also has variable indexing, that is, something like a[b[a[b[0]]]].
       * If we return visit_continue_with_parent here for the first appearence
       * of a, then we can miss that b also has indirect indexing (if this is
       * the only place in the program where such indirect indexing into b
       * happens), so keep going.
       */
      return visit_continue;
   }

   /* If the index is also array dereference, visit index. */
   if (ir->array_index->as_dereference_array())
      visit_enter(ir->array_index->as_dereference_array());

   return visit_continue_with_parent;
}

ir_visitor_status
ir_array_reference_visitor::visit_enter(ir_function_signature *ir)
{
   /* We don't have logic for array-splitting function arguments,
    * so just look at the body instructions and not the parameter
    * declarations.
    */
   visit_list_elements(this, &ir->body);
   return visit_continue_with_parent;
}

bool
ir_array_reference_visitor::get_split_list(exec_list *instructions,
                                           bool linked)
{
   visit_list_elements(this, instructions);

   /* If the shaders aren't linked yet, we can't mess with global
    * declarations, which need to be matched by name across shaders.
    */
   if (!linked) {
      foreach_in_list(ir_instruction, node, instructions) {
         ir_variable *var = node->as_variable();
         if (var) {
            variable_entry *entry = get_variable_entry(var);
            if (entry)
               entry->remove();
         }
      }
   }

   /* Trim out variables we found that we can't split. */
   foreach_in_list_safe(variable_entry, entry, &variable_list) {
      if (debug) {
         printf("array %s@%p: decl %d, split %d\n",
                entry->var->name, (void *) entry->var, entry->declaration,
                entry->split);
      }

      if (!(entry->declaration && entry->split)) {
         entry->remove();
      }
   }

   return !variable_list.is_empty();
}

/**
 * This class rewrites the dereferences of arrays that have been split
 * to use the newly created ir_variables for each component.
 */
class ir_array_splitting_visitor : public ir_rvalue_visitor {
public:
   ir_array_splitting_visitor(exec_list *vars)
   {
      this->variable_list = vars;
   }

   virtual ~ir_array_splitting_visitor()
   {
   }

   virtual ir_visitor_status visit_leave(ir_assignment *);

   void split_deref(ir_dereference **deref);
   void handle_rvalue(ir_rvalue **rvalue);
   variable_entry *get_splitting_entry(ir_variable *var);

   exec_list *variable_list;
};

variable_entry *
ir_array_splitting_visitor::get_splitting_entry(ir_variable *var)
{
   assert(var);

   foreach_in_list(variable_entry, entry, this->variable_list) {
      if (entry->var == var) {
         return entry;
      }
   }

   return NULL;
}

void
ir_array_splitting_visitor::split_deref(ir_dereference **deref)
{
   ir_dereference_array *deref_array = (*deref)->as_dereference_array();
   if (!deref_array)
      return;

   ir_dereference_variable *deref_var = deref_array->array->as_dereference_variable();
   if (!deref_var)
      return;
   ir_variable *var = deref_var->var;

   variable_entry *entry = get_splitting_entry(var);
   if (!entry)
      return;

   ir_constant *constant = deref_array->array_index->as_constant();
   assert(constant);

   if (constant->value.i[0] >= 0 && constant->value.i[0] < (int)entry->size) {
      *deref = new(entry->mem_ctx)
               ir_dereference_variable(entry->components[constant->value.i[0]]);
   } else {
      /* There was a constant array access beyond the end of the
       * array.  This might have happened due to constant folding
       * after the initial parse.  This produces an undefined value,
       * but shouldn't crash.  Just give them an uninitialized
       * variable.
       */
      ir_variable *temp = new(entry->mem_ctx) ir_variable(deref_array->type,
                                                          "undef",
                                                          ir_var_temporary);
      entry->components[0]->insert_before(temp);
      *deref = new(entry->mem_ctx) ir_dereference_variable(temp);
   }
}

void
ir_array_splitting_visitor::handle_rvalue(ir_rvalue **rvalue)
{
   if (!*rvalue)
      return;

   ir_dereference *deref = (*rvalue)->as_dereference();

   if (!deref)
      return;

   split_deref(&deref);
   *rvalue = deref;
}

ir_visitor_status
ir_array_splitting_visitor::visit_leave(ir_assignment *ir)
{
   /* The normal rvalue visitor skips the LHS of assignments, but we
    * need to process those just the same.
    */
   ir_rvalue *lhs = ir->lhs;

   handle_rvalue(&lhs);
   ir->lhs = lhs->as_dereference();

   ir->lhs->accept(this);

   handle_rvalue(&ir->rhs);
   ir->rhs->accept(this);

   if (ir->condition) {
      handle_rvalue(&ir->condition);
      ir->condition->accept(this);
   }

   return visit_continue;
}

bool
optimize_split_arrays(exec_list *instructions, bool linked)
{
   ir_array_reference_visitor refs;
   if (!refs.get_split_list(instructions, linked))
      return false;

   void *mem_ctx = ralloc_context(NULL);

   /* Replace the decls of the arrays to be split with their split
    * components.
    */
   foreach_in_list(variable_entry, entry, &refs.variable_list) {
      const struct glsl_type *type = entry->var->type;
      const struct glsl_type *subtype;

      if (type->is_matrix())
         subtype = type->column_type();
      else
         subtype = type->fields.array;

      entry->mem_ctx = ralloc_parent(entry->var);

      entry->components = ralloc_array(mem_ctx, ir_variable *, entry->size);

      for (unsigned int i = 0; i < entry->size; i++) {
         const char *name = ralloc_asprintf(mem_ctx, "%s_%d",
                                            entry->var->name, i);

         entry->components[i] =
            new(entry->mem_ctx) ir_variable(subtype, name, ir_var_temporary);
         entry->var->insert_before(entry->components[i]);
      }

      entry->var->remove();
   }

   ir_array_splitting_visitor split(&refs.variable_list);
   visit_list_elements(&split, instructions);

   if (debug)
      _mesa_print_ir(stdout, instructions, NULL);

   ralloc_free(mem_ctx);

   return true;

}
<commit_msg>glsl: Split arrays even in the presence of whole-array copies.<commit_after>/*
 * Copyright © 2010 Intel Corporation
 *
 * 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 (including the next
 * paragraph) 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.
 */

/**
 * \file opt_array_splitting.cpp
 *
 * If an array is always dereferenced with a constant index, then
 * split it apart into its elements, making it more amenable to other
 * optimization passes.
 *
 * This skips uniform/varying arrays, which would need careful
 * handling due to their ir->location fields tying them to the GL API
 * and other shader stages.
 */

#include "ir.h"
#include "ir_visitor.h"
#include "ir_rvalue_visitor.h"
#include "compiler/glsl_types.h"

static bool debug = false;

namespace {

namespace opt_array_splitting {

class variable_entry : public exec_node
{
public:
   variable_entry(ir_variable *var)
   {
      this->var = var;
      this->split = true;
      this->declaration = false;
      this->components = NULL;
      this->mem_ctx = NULL;
      if (var->type->is_array())
         this->size = var->type->length;
      else
         this->size = var->type->matrix_columns;
   }

   ir_variable *var; /* The key: the variable's pointer. */
   unsigned size; /* array length or matrix columns */

   /** Whether this array should be split or not. */
   bool split;

   /* If the variable had a decl we can work with in the instruction
    * stream.  We can't do splitting on function arguments, which
    * don't get this variable set.
    */
   bool declaration;

   ir_variable **components;

   /** ralloc_parent(this->var) -- the shader's talloc context. */
   void *mem_ctx;
};

} /* namespace */

using namespace opt_array_splitting;

/**
 * This class does a walk over the tree, coming up with the set of
 * variables that could be split by looking to see if they are arrays
 * that are only ever constant-index dereferenced.
 */
class ir_array_reference_visitor : public ir_hierarchical_visitor {
public:
   ir_array_reference_visitor(void)
   {
      this->mem_ctx = ralloc_context(NULL);
      this->variable_list.make_empty();
      this->in_whole_array_copy = false;
   }

   ~ir_array_reference_visitor(void)
   {
      ralloc_free(mem_ctx);
   }

   bool get_split_list(exec_list *instructions, bool linked);

   virtual ir_visitor_status visit(ir_variable *);
   virtual ir_visitor_status visit(ir_dereference_variable *);
   virtual ir_visitor_status visit_enter(ir_assignment *);
   virtual ir_visitor_status visit_leave(ir_assignment *);
   virtual ir_visitor_status visit_enter(ir_dereference_array *);
   virtual ir_visitor_status visit_enter(ir_function_signature *);

   variable_entry *get_variable_entry(ir_variable *var);

   /* List of variable_entry */
   exec_list variable_list;

   void *mem_ctx;

   bool in_whole_array_copy;
};

} /* namespace */

variable_entry *
ir_array_reference_visitor::get_variable_entry(ir_variable *var)
{
   assert(var);

   if (var->data.mode != ir_var_auto &&
       var->data.mode != ir_var_temporary)
      return NULL;

   if (!(var->type->is_array() || var->type->is_matrix()))
      return NULL;

   /* If the array hasn't been sized yet, we can't split it.  After
    * linking, this should be resolved.
    */
   if (var->type->is_unsized_array())
      return NULL;

   foreach_in_list(variable_entry, entry, &this->variable_list) {
      if (entry->var == var)
         return entry;
   }

   variable_entry *entry = new(mem_ctx) variable_entry(var);
   this->variable_list.push_tail(entry);
   return entry;
}

ir_visitor_status
ir_array_reference_visitor::visit(ir_variable *ir)
{
   variable_entry *entry = this->get_variable_entry(ir);

   if (entry)
      entry->declaration = true;

   return visit_continue;
}

ir_visitor_status
ir_array_reference_visitor::visit_enter(ir_assignment *ir)
{
   in_whole_array_copy =
      ir->lhs->type->is_array() && ir->whole_variable_written();

   return visit_continue;
}

ir_visitor_status
ir_array_reference_visitor::visit_leave(ir_assignment *ir)
{
   in_whole_array_copy = false;

   return visit_continue;
}

ir_visitor_status
ir_array_reference_visitor::visit(ir_dereference_variable *ir)
{
   variable_entry *entry = this->get_variable_entry(ir->var);

   /* Allow whole-array assignments on the LHS.  We can split those
    * by "unrolling" the assignment into component-wise assignments.
    */
   if (in_assignee && in_whole_array_copy)
      return visit_continue;

   /* If we made it to here without seeing an ir_dereference_array,
    * then the dereference of this array didn't have a constant index
    * (see the visit_continue_with_parent below), so we can't split
    * the variable.
    */
   if (entry)
      entry->split = false;

   return visit_continue;
}

ir_visitor_status
ir_array_reference_visitor::visit_enter(ir_dereference_array *ir)
{
   ir_dereference_variable *deref = ir->array->as_dereference_variable();
   if (!deref)
      return visit_continue;

   variable_entry *entry = this->get_variable_entry(deref->var);

   /* If the access to the array has a variable index, we wouldn't
    * know which split variable this dereference should go to.
    */
   if (!ir->array_index->as_constant()) {
      if (entry)
         entry->split = false;
      /* This variable indexing could come from a different array dereference
       * that also has variable indexing, that is, something like a[b[a[b[0]]]].
       * If we return visit_continue_with_parent here for the first appearence
       * of a, then we can miss that b also has indirect indexing (if this is
       * the only place in the program where such indirect indexing into b
       * happens), so keep going.
       */
      return visit_continue;
   }

   /* If the index is also array dereference, visit index. */
   if (ir->array_index->as_dereference_array())
      visit_enter(ir->array_index->as_dereference_array());

   return visit_continue_with_parent;
}

ir_visitor_status
ir_array_reference_visitor::visit_enter(ir_function_signature *ir)
{
   /* We don't have logic for array-splitting function arguments,
    * so just look at the body instructions and not the parameter
    * declarations.
    */
   visit_list_elements(this, &ir->body);
   return visit_continue_with_parent;
}

bool
ir_array_reference_visitor::get_split_list(exec_list *instructions,
                                           bool linked)
{
   visit_list_elements(this, instructions);

   /* If the shaders aren't linked yet, we can't mess with global
    * declarations, which need to be matched by name across shaders.
    */
   if (!linked) {
      foreach_in_list(ir_instruction, node, instructions) {
         ir_variable *var = node->as_variable();
         if (var) {
            variable_entry *entry = get_variable_entry(var);
            if (entry)
               entry->remove();
         }
      }
   }

   /* Trim out variables we found that we can't split. */
   foreach_in_list_safe(variable_entry, entry, &variable_list) {
      if (debug) {
         printf("array %s@%p: decl %d, split %d\n",
                entry->var->name, (void *) entry->var, entry->declaration,
                entry->split);
      }

      if (!(entry->declaration && entry->split)) {
         entry->remove();
      }
   }

   return !variable_list.is_empty();
}

/**
 * This class rewrites the dereferences of arrays that have been split
 * to use the newly created ir_variables for each component.
 */
class ir_array_splitting_visitor : public ir_rvalue_visitor {
public:
   ir_array_splitting_visitor(exec_list *vars)
   {
      this->variable_list = vars;
   }

   virtual ~ir_array_splitting_visitor()
   {
   }

   virtual ir_visitor_status visit_leave(ir_assignment *);

   void split_deref(ir_dereference **deref);
   void handle_rvalue(ir_rvalue **rvalue);
   variable_entry *get_splitting_entry(ir_variable *var);

   exec_list *variable_list;
};

variable_entry *
ir_array_splitting_visitor::get_splitting_entry(ir_variable *var)
{
   assert(var);

   foreach_in_list(variable_entry, entry, this->variable_list) {
      if (entry->var == var) {
         return entry;
      }
   }

   return NULL;
}

void
ir_array_splitting_visitor::split_deref(ir_dereference **deref)
{
   ir_dereference_array *deref_array = (*deref)->as_dereference_array();
   if (!deref_array)
      return;

   ir_dereference_variable *deref_var = deref_array->array->as_dereference_variable();
   if (!deref_var)
      return;
   ir_variable *var = deref_var->var;

   variable_entry *entry = get_splitting_entry(var);
   if (!entry)
      return;

   ir_constant *constant = deref_array->array_index->as_constant();
   assert(constant);

   if (constant->value.i[0] >= 0 && constant->value.i[0] < (int)entry->size) {
      *deref = new(entry->mem_ctx)
               ir_dereference_variable(entry->components[constant->value.i[0]]);
   } else {
      /* There was a constant array access beyond the end of the
       * array.  This might have happened due to constant folding
       * after the initial parse.  This produces an undefined value,
       * but shouldn't crash.  Just give them an uninitialized
       * variable.
       */
      ir_variable *temp = new(entry->mem_ctx) ir_variable(deref_array->type,
                                                          "undef",
                                                          ir_var_temporary);
      entry->components[0]->insert_before(temp);
      *deref = new(entry->mem_ctx) ir_dereference_variable(temp);
   }
}

void
ir_array_splitting_visitor::handle_rvalue(ir_rvalue **rvalue)
{
   if (!*rvalue)
      return;

   ir_dereference *deref = (*rvalue)->as_dereference();

   if (!deref)
      return;

   split_deref(&deref);
   *rvalue = deref;
}

ir_visitor_status
ir_array_splitting_visitor::visit_leave(ir_assignment *ir)
{
   /* The normal rvalue visitor skips the LHS of assignments, but we
    * need to process those just the same.
    */
   ir_rvalue *lhs = ir->lhs;

   /* "Unroll" any whole array assignments, creating assignments for
    * each array element.  Then, do splitting on each new assignment.
    */
   if (lhs->type->is_array() && ir->whole_variable_written() &&
       get_splitting_entry(ir->whole_variable_written())) {
      void *mem_ctx = ralloc_parent(ir);

      for (unsigned i = 0; i < lhs->type->length; i++) {
         ir_rvalue *lhs_i =
            new(mem_ctx) ir_dereference_array(ir->lhs->clone(mem_ctx, NULL),
                                              new(mem_ctx) ir_constant(i));
         ir_rvalue *rhs_i =
            new(mem_ctx) ir_dereference_array(ir->rhs->clone(mem_ctx, NULL),
                                              new(mem_ctx) ir_constant(i));
         ir_rvalue *condition_i =
            ir->condition ? ir->condition->clone(mem_ctx, NULL) : NULL;

         ir_assignment *assign_i =
            new(mem_ctx) ir_assignment(lhs_i, rhs_i, condition_i);

         ir->insert_before(assign_i);
         assign_i->accept(this);
      }
      ir->remove();
      return visit_continue;
   }

   handle_rvalue(&lhs);
   ir->lhs = lhs->as_dereference();

   ir->lhs->accept(this);

   handle_rvalue(&ir->rhs);
   ir->rhs->accept(this);

   if (ir->condition) {
      handle_rvalue(&ir->condition);
      ir->condition->accept(this);
   }

   return visit_continue;
}

bool
optimize_split_arrays(exec_list *instructions, bool linked)
{
   ir_array_reference_visitor refs;
   if (!refs.get_split_list(instructions, linked))
      return false;

   void *mem_ctx = ralloc_context(NULL);

   /* Replace the decls of the arrays to be split with their split
    * components.
    */
   foreach_in_list(variable_entry, entry, &refs.variable_list) {
      const struct glsl_type *type = entry->var->type;
      const struct glsl_type *subtype;

      if (type->is_matrix())
         subtype = type->column_type();
      else
         subtype = type->fields.array;

      entry->mem_ctx = ralloc_parent(entry->var);

      entry->components = ralloc_array(mem_ctx, ir_variable *, entry->size);

      for (unsigned int i = 0; i < entry->size; i++) {
         const char *name = ralloc_asprintf(mem_ctx, "%s_%d",
                                            entry->var->name, i);

         entry->components[i] =
            new(entry->mem_ctx) ir_variable(subtype, name, ir_var_temporary);
         entry->var->insert_before(entry->components[i]);
      }

      entry->var->remove();
   }

   ir_array_splitting_visitor split(&refs.variable_list);
   visit_list_elements(&split, instructions);

   if (debug)
      _mesa_print_ir(stdout, instructions, NULL);

   ralloc_free(mem_ctx);

   return true;

}
<|endoftext|>


<commit_before>/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
  *
  * Condor Software Copyright Notice
  * Copyright (C) 1990-2006, Condor Team, Computer Sciences Department,
  * University of Wisconsin-Madison, WI.
  *
  * This source code is covered by the Condor Public License, which can
  * be found in the accompanying LICENSE.TXT file, or online at
  * www.condorproject.org.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  * AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  * WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
  * FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
  * HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
  * MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
  * ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
  * PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
  * RIGHT.
  *
  ****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/

#include "HashTable.h"
#include "../condor_daemon_core.V6/condor_daemon_core.h"
#include "scheduler.h"
#include "proc.h"
#include "MyString.h"
#include "dedicated_scheduler.h"
#include "grid_universe.h"
#include "simplelist.h"
#include "list.h"
#include "schedd_api.h"
#include "tdman.h"
//#include "condor_crontab.h"

template class SimpleList<TransferRequest*>;
template class HashTable<MyString, TransferRequest*>;

template class HashTable<MyString, JobFile>;
template class List<FileInfo>;
template class Item<FileInfo>;

class Shadow;

template class HashTable<int, int>;
template class HashBucket<int,int>;
template class HashTable<int, shadow_rec *>;
template class HashBucket<int,shadow_rec *>;
template class HashTable<HashKey, match_rec *>;
template class HashTable<PROC_ID, match_rec *>;
template class HashBucket<HashKey,match_rec *>;
template class HashTable<PROC_ID, shadow_rec *>;
template class HashBucket<PROC_ID,shadow_rec *>;
template class HashTable<PROC_ID, ClassAd *>;
template class HashBucket<PROC_ID, ClassAd *>;
//template class HashTable<PROC_ID, CronTab *>;
//template class HashBucket<PROC_ID, CronTab *>;
template class HashTable<UserIdentity, GridJobCounts>;
template class HashBucket<UserIdentity, GridJobCounts>;
template class Queue<shadow_rec*>;
template class Queue<ContactStartdArgs*>;
template class List<shadow_rec*>;
template class Item<shadow_rec*>;
template class SimpleList<PROC_ID>;
template class ExtArray<MyString*>;
template class ExtArray<bool>;
template class ExtArray<PROC_ID>;
template class ExtArray<OwnerData>;
template class SimpleList<Shadow*>;
template class HashTable<int, ExtArray<PROC_ID> *>;

template class HashTable<MyString, TransferDaemon*>;
template class HashBucket<MyString, TransferDaemon*>;
template class HashTable<MyString, MyString>;
template class HashBucket<MyString, MyString>;
template class HashTable<long, TransferDaemon*>;
template class HashBucket<long, TransferDaemon*>;

// for condor-G
template class HashTable<MyString,GridUniverseLogic::gman_node_t *>;

// for MPI (or parallel) use:
template class ExtArray<match_rec*>;
template class ExtArray<MRecArray*>;
template class ExtArray<ClassAd*>;
template class HashTable<int,AllocationNode*>;
template class HashBucket<int,AllocationNode*>;
template class List<ClassAd>;
template class Item<ClassAd>;
template class Queue<PROC_ID>;
// You'd think we'd need to instantiate a HashTable and HashBucket for
// <HashKey, ClassAd*> here, but those are already instantiated in
// classad_log.C in the c++_util_lib (not in c++_util_instantiate.C
// where you'd expect to find it *sigh*)

// schedd_api
template class HashTable<int, ScheddTransaction*>;
template class HashTable<PROC_ID, Job*>;
<commit_msg>removed redundant template instantiations.  everything removed was already instantiated in c++_util_instantiate.C.<commit_after>/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
  *
  * Condor Software Copyright Notice
  * Copyright (C) 1990-2006, Condor Team, Computer Sciences Department,
  * University of Wisconsin-Madison, WI.
  *
  * This source code is covered by the Condor Public License, which can
  * be found in the accompanying LICENSE.TXT file, or online at
  * www.condorproject.org.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  * AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  * WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
  * FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
  * HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
  * MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
  * ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
  * PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
  * RIGHT.
  *
  ****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/

#include "HashTable.h"
#include "../condor_daemon_core.V6/condor_daemon_core.h"
#include "scheduler.h"
#include "proc.h"
#include "MyString.h"
#include "dedicated_scheduler.h"
#include "grid_universe.h"
#include "simplelist.h"
#include "list.h"
#include "schedd_api.h"
#include "tdman.h"
//#include "condor_crontab.h"

template class SimpleList<TransferRequest*>;
template class HashTable<MyString, TransferRequest*>;

template class HashTable<MyString, JobFile>;
template class List<FileInfo>;
template class Item<FileInfo>;

class Shadow;

template class HashTable<int, int>;
template class HashBucket<int,int>;
template class HashTable<int, shadow_rec *>;
template class HashBucket<int,shadow_rec *>;
template class HashTable<HashKey, match_rec *>;
template class HashTable<PROC_ID, match_rec *>;
template class HashBucket<HashKey,match_rec *>;
template class HashTable<PROC_ID, shadow_rec *>;
template class HashBucket<PROC_ID,shadow_rec *>;
template class HashTable<PROC_ID, ClassAd *>;
template class HashBucket<PROC_ID, ClassAd *>;
//template class HashTable<PROC_ID, CronTab *>;
//template class HashBucket<PROC_ID, CronTab *>;
template class HashTable<UserIdentity, GridJobCounts>;
template class HashBucket<UserIdentity, GridJobCounts>;
template class Queue<shadow_rec*>;
template class Queue<ContactStartdArgs*>;
template class List<shadow_rec*>;
template class Item<shadow_rec*>;
template class SimpleList<PROC_ID>;
template class ExtArray<MyString*>;
template class ExtArray<bool>;
template class ExtArray<OwnerData>;
template class SimpleList<Shadow*>;
template class HashTable<int, ExtArray<PROC_ID> *>;

template class HashTable<MyString, TransferDaemon*>;
template class HashBucket<MyString, TransferDaemon*>;
template class HashTable<long, TransferDaemon*>;
template class HashBucket<long, TransferDaemon*>;

// for condor-G
template class HashTable<MyString,GridUniverseLogic::gman_node_t *>;

// for MPI (or parallel) use:
template class ExtArray<match_rec*>;
template class ExtArray<MRecArray*>;
template class ExtArray<ClassAd*>;
template class HashTable<int,AllocationNode*>;
template class HashBucket<int,AllocationNode*>;
template class List<ClassAd>;
template class Item<ClassAd>;
template class Queue<PROC_ID>;
// You'd think we'd need to instantiate a HashTable and HashBucket for
// <HashKey, ClassAd*> here, but those are already instantiated in
// classad_log.C in the c++_util_lib (not in c++_util_instantiate.C
// where you'd expect to find it *sigh*)

// schedd_api
template class HashTable<int, ScheddTransaction*>;
template class HashTable<PROC_ID, Job*>;
<|endoftext|>