<commit_before>/*************************************************************************
 *
 *  $RCSfile: jscriptclasses.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: jl $ $Date: 2001-12-06 08:12:40 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#include "jscriptclasses.hxx"

//========================================================================
// JScriptValue
//========================================================================
JScriptValue::JScriptValue(): m_bOutParam(0), m_bInOutParam(0)
{
}

JScriptValue::~JScriptValue()
{
}

// JScriptValue, IDispatch --------------------------------------------
STDMETHODIMP JScriptValue::GetTypeInfoCount(UINT *pctinfo)
{
    return E_NOTIMPL;
}

// JScriptValue, IDispatch --------------------------------------------
STDMETHODIMP JScriptValue::GetTypeInfo( UINT iTInfo,
                                           LCID lcid,
                                           ITypeInfo **ppTInfo)
{
    return E_NOTIMPL;
}

// JScriptValue, IDispatch --------------------------------------------
STDMETHODIMP JScriptValue::GetIDsOfNames( REFIID riid,
                                             LPOLESTR *rgszNames,
                                             UINT cNames,
                                             LCID lcid,
                                             DISPID *rgDispId)
{
    if( !rgDispId)
        return E_POINTER;

    HRESULT ret= S_OK;
    CComBSTR name(*rgszNames);
    name.ToLower();

    if( name == CComBSTR( L"set") )
        *rgDispId= 1;
    else if( name == CComBSTR( L"get") )
        *rgDispId= 2;
    else if( name == CComBSTR( L"initoutparam") )
        *rgDispId= 3;
    else if( name == CComBSTR( L"initinoutparam") )
        *rgDispId= 4;
    else
        ret= DISP_E_UNKNOWNNAME;

    return ret;
}

// JScriptValue, IDispatch --------------------------------------------
STDMETHODIMP JScriptValue::Invoke( DISPID dispIdMember,
                         REFIID riid,
                         LCID lcid,
                         WORD wFlags,
                         DISPPARAMS *pDispParams,
                         VARIANT *pVarResult,
                         EXCEPINFO *pExcepInfo,
                         UINT *puArgErr)
{
    if( pDispParams->cNamedArgs)
        return DISP_E_NONAMEDARGS;

    HRESULT ret= S_OK;
    switch( dispIdMember)
    {
    case 0: // DISPID_VALUE
        if( wFlags & DISPATCH_PROPERTYGET && pVarResult)
        {
            if( FAILED( VariantCopy( pVarResult, &m_varValue)))
                ret= E_FAIL;
        }
        else
            ret= E_POINTER;
        break;
    case 1:
        if( wFlags & DISPATCH_METHOD)
            ret= Set( pDispParams->rgvarg[1], pDispParams->rgvarg[0]);
        if( FAILED( ret))
            ret= DISP_E_EXCEPTION;
        break;
    case 2:
        if( wFlags & DISPATCH_METHOD)
            ret= Get( pVarResult);
        if( FAILED( ret))
            ret= DISP_E_EXCEPTION;
        break;
    case 3:
        if( wFlags & DISPATCH_METHOD)
            ret= InitOutParam();
        if( FAILED( ret))
            ret= DISP_E_EXCEPTION;
        break;
    case 4:
        if( wFlags & DISPATCH_METHOD)
            ret= InitInOutParam( pDispParams->rgvarg[1], pDispParams->rgvarg[0]);
        if( FAILED( ret))
            ret= DISP_E_EXCEPTION;
        break;
    default:
        ret= DISP_E_MEMBERNOTFOUND;
        break;
    }

    return ret;
}

// JScriptValue, IScriptOutParam-----------------------
STDMETHODIMP JScriptValue::Set( VARIANT type, VARIANT value)
{
    Lock();
    HRESULT hr= S_OK;
    m_varValue.Clear();
    hr= VariantCopyInd( &m_varValue, &value);
    VARIANT var;
    VariantInit( &var);
    if( SUCCEEDED( hr= VariantChangeType( &var, &type, 0, VT_BSTR)))
        m_bstrType= var.bstrVal;
    Unlock();
    return hr;
}
// JScriptValue, IScriptOutParam-----------------------
STDMETHODIMP JScriptValue::Get( VARIANT *val)
{
    Lock();
    if( !val)
        return E_POINTER;
    HRESULT hr= VariantCopy( val, &m_varValue);
    Unlock();
    return hr;
}

STDMETHODIMP JScriptValue::InitOutParam()
{
    Lock();
    m_varValue.Clear();
    m_bOutParam= true;
    m_bInOutParam= false;
    Unlock();
    return S_OK;
}

STDMETHODIMP JScriptValue::InitInOutParam( VARIANT type, VARIANT value)
{
    Lock();
    m_bInOutParam= true;
    m_bOutParam= false;
    Unlock();
    return Set( type, value);
}

STDMETHODIMP JScriptValue::IsOutParam( VARIANT_BOOL * flag)
{
    Lock();
    if( !flag)
        return E_POINTER;
    *flag= m_bOutParam ? VARIANT_TRUE : VARIANT_FALSE;
    Unlock();
    return S_OK;
}

STDMETHODIMP JScriptValue::IsInOutParam( VARIANT_BOOL * flag)
{
    Lock();
    if( !flag)
        return E_POINTER;
    *flag= m_bInOutParam ? VARIANT_TRUE : VARIANT_FALSE;
    Unlock();
    return S_OK;
}

STDMETHODIMP JScriptValue::GetValue( BSTR* type, VARIANT *value)
{
    Lock();
    if( !type || !value)
        return E_POINTER;
    HRESULT hr;
    if( SUCCEEDED(  hr= m_bstrType.CopyTo( type)))
        hr= VariantCopy( value, &m_varValue);
    Unlock();
    return hr;
}

//##########################################################################################
// JScriptOutValue
//##########################################################################################

JScriptOutParam::JScriptOutParam()
{
}

JScriptOutParam::~JScriptOutParam()
{
}

// JScriptOutParam, IDispatch --------------------------------------------
STDMETHODIMP JScriptOutParam::GetTypeInfoCount(UINT *pctinfo)
{
    return E_NOTIMPL;
}

// JScriptOutParam, IDispatch --------------------------------------------
STDMETHODIMP JScriptOutParam::GetTypeInfo( UINT iTInfo,
                                           LCID lcid,
                                           ITypeInfo **ppTInfo)
{
    return E_NOTIMPL;
}

// JScriptOutParam, IDispatch --------------------------------------------
STDMETHODIMP JScriptOutParam::GetIDsOfNames( REFIID riid,
                                             LPOLESTR *rgszNames,
                                             UINT cNames,
                                             LCID lcid,
                                             DISPID *rgDispId)
{
    if( !rgDispId)
        return E_POINTER;

    HRESULT ret= S_OK;
    CComBSTR name(*rgszNames);
    name.ToLower();

    if( name == CComBSTR( L"0") )
        *rgDispId= 1;
    else
        ret= DISP_E_UNKNOWNNAME;

    return ret;
}

// JScriptOutParam, IDispatch --------------------------------------------
STDMETHODIMP JScriptOutParam::Invoke( DISPID dispIdMember,
                         REFIID riid,
                         LCID lcid,
                         WORD wFlags,
                         DISPPARAMS *pDispParams,
                         VARIANT *pVarResult,
                         EXCEPINFO *pExcepInfo,
                         UINT *puArgErr)
{
    HRESULT ret= S_OK;
    switch( dispIdMember)
    {
    case 0: // DISPID_VALUE
        if( wFlags & DISPATCH_PROPERTYGET && pVarResult)
        {
            if( FAILED( VariantCopy( pVarResult, &m_varValue)))
                ret= E_FAIL;
        }
        else if( wFlags & DISPATCH_PROPERTYPUT || wFlags & DISPATCH_PROPERTYPUTREF)
        {
            m_varValue.Clear();
            if( FAILED( VariantCopyInd( &m_varValue, &pDispParams->rgvarg[0])))
                ret= E_FAIL;
        }
        else
            ret= E_POINTER;
        break;
    case 1: //
        if( wFlags & DISPATCH_PROPERTYGET && pVarResult)
        {
            if( FAILED( VariantCopy( pVarResult, &m_varValue)))
                ret= E_FAIL;
        }
        else if( wFlags & DISPATCH_PROPERTYPUT || wFlags & DISPATCH_PROPERTYPUTREF)
        {
            m_varValue.Clear();
            if( FAILED( VariantCopyInd( &m_varValue, &pDispParams->rgvarg[0])))
                ret= E_FAIL;
        }
        else
            ret= E_POINTER;
        break;

    default:
        ret= DISP_E_MEMBERNOTFOUND;
        break;
    }

    return ret;
}
<commit_msg>INTEGRATION: CWS ooo19126 (1.3.578); FILE MERGED 2005/09/05 12:59:31 rt 1.3.578.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: jscriptclasses.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 19:42:46 $
 *
 *  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
 *
 ************************************************************************/
#include "jscriptclasses.hxx"

//========================================================================
// JScriptValue
//========================================================================
JScriptValue::JScriptValue(): m_bOutParam(0), m_bInOutParam(0)
{
}

JScriptValue::~JScriptValue()
{
}

// JScriptValue, IDispatch --------------------------------------------
STDMETHODIMP JScriptValue::GetTypeInfoCount(UINT *pctinfo)
{
    return E_NOTIMPL;
}

// JScriptValue, IDispatch --------------------------------------------
STDMETHODIMP JScriptValue::GetTypeInfo( UINT iTInfo,
                                           LCID lcid,
                                           ITypeInfo **ppTInfo)
{
    return E_NOTIMPL;
}

// JScriptValue, IDispatch --------------------------------------------
STDMETHODIMP JScriptValue::GetIDsOfNames( REFIID riid,
                                             LPOLESTR *rgszNames,
                                             UINT cNames,
                                             LCID lcid,
                                             DISPID *rgDispId)
{
    if( !rgDispId)
        return E_POINTER;

    HRESULT ret= S_OK;
    CComBSTR name(*rgszNames);
    name.ToLower();

    if( name == CComBSTR( L"set") )
        *rgDispId= 1;
    else if( name == CComBSTR( L"get") )
        *rgDispId= 2;
    else if( name == CComBSTR( L"initoutparam") )
        *rgDispId= 3;
    else if( name == CComBSTR( L"initinoutparam") )
        *rgDispId= 4;
    else
        ret= DISP_E_UNKNOWNNAME;

    return ret;
}

// JScriptValue, IDispatch --------------------------------------------
STDMETHODIMP JScriptValue::Invoke( DISPID dispIdMember,
                         REFIID riid,
                         LCID lcid,
                         WORD wFlags,
                         DISPPARAMS *pDispParams,
                         VARIANT *pVarResult,
                         EXCEPINFO *pExcepInfo,
                         UINT *puArgErr)
{
    if( pDispParams->cNamedArgs)
        return DISP_E_NONAMEDARGS;

    HRESULT ret= S_OK;
    switch( dispIdMember)
    {
    case 0: // DISPID_VALUE
        if( wFlags & DISPATCH_PROPERTYGET && pVarResult)
        {
            if( FAILED( VariantCopy( pVarResult, &m_varValue)))
                ret= E_FAIL;
        }
        else
            ret= E_POINTER;
        break;
    case 1:
        if( wFlags & DISPATCH_METHOD)
            ret= Set( pDispParams->rgvarg[1], pDispParams->rgvarg[0]);
        if( FAILED( ret))
            ret= DISP_E_EXCEPTION;
        break;
    case 2:
        if( wFlags & DISPATCH_METHOD)
            ret= Get( pVarResult);
        if( FAILED( ret))
            ret= DISP_E_EXCEPTION;
        break;
    case 3:
        if( wFlags & DISPATCH_METHOD)
            ret= InitOutParam();
        if( FAILED( ret))
            ret= DISP_E_EXCEPTION;
        break;
    case 4:
        if( wFlags & DISPATCH_METHOD)
            ret= InitInOutParam( pDispParams->rgvarg[1], pDispParams->rgvarg[0]);
        if( FAILED( ret))
            ret= DISP_E_EXCEPTION;
        break;
    default:
        ret= DISP_E_MEMBERNOTFOUND;
        break;
    }

    return ret;
}

// JScriptValue, IScriptOutParam-----------------------
STDMETHODIMP JScriptValue::Set( VARIANT type, VARIANT value)
{
    Lock();
    HRESULT hr= S_OK;
    m_varValue.Clear();
    hr= VariantCopyInd( &m_varValue, &value);
    VARIANT var;
    VariantInit( &var);
    if( SUCCEEDED( hr= VariantChangeType( &var, &type, 0, VT_BSTR)))
        m_bstrType= var.bstrVal;
    Unlock();
    return hr;
}
// JScriptValue, IScriptOutParam-----------------------
STDMETHODIMP JScriptValue::Get( VARIANT *val)
{
    Lock();
    if( !val)
        return E_POINTER;
    HRESULT hr= VariantCopy( val, &m_varValue);
    Unlock();
    return hr;
}

STDMETHODIMP JScriptValue::InitOutParam()
{
    Lock();
    m_varValue.Clear();
    m_bOutParam= true;
    m_bInOutParam= false;
    Unlock();
    return S_OK;
}

STDMETHODIMP JScriptValue::InitInOutParam( VARIANT type, VARIANT value)
{
    Lock();
    m_bInOutParam= true;
    m_bOutParam= false;
    Unlock();
    return Set( type, value);
}

STDMETHODIMP JScriptValue::IsOutParam( VARIANT_BOOL * flag)
{
    Lock();
    if( !flag)
        return E_POINTER;
    *flag= m_bOutParam ? VARIANT_TRUE : VARIANT_FALSE;
    Unlock();
    return S_OK;
}

STDMETHODIMP JScriptValue::IsInOutParam( VARIANT_BOOL * flag)
{
    Lock();
    if( !flag)
        return E_POINTER;
    *flag= m_bInOutParam ? VARIANT_TRUE : VARIANT_FALSE;
    Unlock();
    return S_OK;
}

STDMETHODIMP JScriptValue::GetValue( BSTR* type, VARIANT *value)
{
    Lock();
    if( !type || !value)
        return E_POINTER;
    HRESULT hr;
    if( SUCCEEDED(  hr= m_bstrType.CopyTo( type)))
        hr= VariantCopy( value, &m_varValue);
    Unlock();
    return hr;
}

//##########################################################################################
// JScriptOutValue
//##########################################################################################

JScriptOutParam::JScriptOutParam()
{
}

JScriptOutParam::~JScriptOutParam()
{
}

// JScriptOutParam, IDispatch --------------------------------------------
STDMETHODIMP JScriptOutParam::GetTypeInfoCount(UINT *pctinfo)
{
    return E_NOTIMPL;
}

// JScriptOutParam, IDispatch --------------------------------------------
STDMETHODIMP JScriptOutParam::GetTypeInfo( UINT iTInfo,
                                           LCID lcid,
                                           ITypeInfo **ppTInfo)
{
    return E_NOTIMPL;
}

// JScriptOutParam, IDispatch --------------------------------------------
STDMETHODIMP JScriptOutParam::GetIDsOfNames( REFIID riid,
                                             LPOLESTR *rgszNames,
                                             UINT cNames,
                                             LCID lcid,
                                             DISPID *rgDispId)
{
    if( !rgDispId)
        return E_POINTER;

    HRESULT ret= S_OK;
    CComBSTR name(*rgszNames);
    name.ToLower();

    if( name == CComBSTR( L"0") )
        *rgDispId= 1;
    else
        ret= DISP_E_UNKNOWNNAME;

    return ret;
}

// JScriptOutParam, IDispatch --------------------------------------------
STDMETHODIMP JScriptOutParam::Invoke( DISPID dispIdMember,
                         REFIID riid,
                         LCID lcid,
                         WORD wFlags,
                         DISPPARAMS *pDispParams,
                         VARIANT *pVarResult,
                         EXCEPINFO *pExcepInfo,
                         UINT *puArgErr)
{
    HRESULT ret= S_OK;
    switch( dispIdMember)
    {
    case 0: // DISPID_VALUE
        if( wFlags & DISPATCH_PROPERTYGET && pVarResult)
        {
            if( FAILED( VariantCopy( pVarResult, &m_varValue)))
                ret= E_FAIL;
        }
        else if( wFlags & DISPATCH_PROPERTYPUT || wFlags & DISPATCH_PROPERTYPUTREF)
        {
            m_varValue.Clear();
            if( FAILED( VariantCopyInd( &m_varValue, &pDispParams->rgvarg[0])))
                ret= E_FAIL;
        }
        else
            ret= E_POINTER;
        break;
    case 1: //
        if( wFlags & DISPATCH_PROPERTYGET && pVarResult)
        {
            if( FAILED( VariantCopy( pVarResult, &m_varValue)))
                ret= E_FAIL;
        }
        else if( wFlags & DISPATCH_PROPERTYPUT || wFlags & DISPATCH_PROPERTYPUTREF)
        {
            m_varValue.Clear();
            if( FAILED( VariantCopyInd( &m_varValue, &pDispParams->rgvarg[0])))
                ret= E_FAIL;
        }
        else
            ret= E_POINTER;
        break;

    default:
        ret= DISP_E_MEMBERNOTFOUND;
        break;
    }

    return ret;
}
<|endoftext|>


<commit_before>/******************************************************************************
*       SOFA, Simulation Open-Framework Architecture, version 1.0 RC 1        *
*                (c) 2006-2011 MGH, INRIA, USTL, UJF, CNRS                    *
*                                                                             *
* This library is free software; you can redistribute it and/or modify it     *
* under the terms of the GNU Lesser General Public License as published by    *
* the Free Software Foundation; either version 2.1 of the License, or (at     *
* your option) any later version.                                             *
*                                                                             *
* This library is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
* for more details.                                                           *
*                                                                             *
* You should have received a copy of the GNU Lesser General Public License    *
* along with this library; if not, write to the Free Software Foundation,     *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
*******************************************************************************
*                               SOFA :: Modules                               *
*                                                                             *
* Authors: The SOFA Team and external contributors (see Authors.txt)          *
*                                                                             *
* Contact information: contact@sofa-framework.org                             *
******************************************************************************/
#include <sofa/component/collision/FrictionContact.inl>

namespace sofa
{

namespace component
{

namespace collision
{

using namespace defaulttype;
using namespace sofa::helper;
using simulation::Node;

sofa::core::collision::DetectionOutput::ContactId Identifier::cpt=0;
std::list<sofa::core::collision::DetectionOutput::ContactId> Identifier::availableId;

SOFA_DECL_CLASS(FrictionContact)

Creator<Contact::Factory, FrictionContact<PointModel, PointModel> > PointPointFrictionContactClass("FrictionContact",true);
Creator<Contact::Factory, FrictionContact<LineModel, SphereModel> > LineSphereFrictionContactClass("FrictionContact",true);
Creator<Contact::Factory, FrictionContact<LineModel, PointModel> > LinePointFrictionContactClass("FrictionContact",true);
Creator<Contact::Factory, FrictionContact<LineModel, LineModel> > LineLineFrictionContactClass("FrictionContact",true);
Creator<Contact::Factory, FrictionContact<TriangleModel, SphereModel> > TriangleSphereFrictionContactClass("FrictionContact",true);
Creator<Contact::Factory, FrictionContact<TriangleModel, PointModel> > TrianglePointFrictionContactClass("FrictionContact",true);
Creator<Contact::Factory, FrictionContact<TriangleModel, LineModel> > TriangleLineFrictionContactClass("FrictionContact",true);
Creator<Contact::Factory, FrictionContact<TriangleModel, TriangleModel> > TriangleTriangleFrictionContactClass("FrictionContact",true);
Creator<Contact::Factory, FrictionContact<SphereModel, SphereModel> > SphereSphereFrictionContactClass("FrictionContact",true);
Creator<Contact::Factory, FrictionContact<SphereModel, PointModel> > SpherePointFrictionContactClass("FrictionContact",true);
Creator<Contact::Factory, FrictionContact<CapsuleModel, CapsuleModel> > CapsuleCapsuleFrictionContactClass("FrictionContact",true);
Creator<Contact::Factory, FrictionContact<CapsuleModel, TriangleModel> > CapsuleTriangleFrictionContactClass("FrictionContact",true);
Creator<Contact::Factory, FrictionContact<CapsuleModel, SphereModel> > CapsuleSphereFrictionContactClass("FrictionContact",true);
Creator<Contact::Factory, FrictionContact<OBBModel, OBBModel> > OBBOBBFrictionContactClass("FrictionContact",true);
Creator<Contact::Factory, FrictionContact<SphereModel, OBBModel> > SphereOBBFrictionContactClass("FrictionContact",true);
Creator<Contact::Factory, FrictionContact<CapsuleModel, OBBModel> > CapsuleOBBFrictionContactClass("FrictionContact",true);
Creator<Contact::Factory, FrictionContact<TriangleModel, OBBModel> > TriangleOBBFrictionContactClass("FrictionContact",true);
Creator<Contact::Factory, FrictionContact<RigidSphereModel, RigidSphereModel> > RigidSphereRigidSphereFrictionContactClass("FrictionContact",true);
Creator<Contact::Factory, FrictionContact<SphereModel, RigidSphereModel> > SphereRigidSphereFrictionContactClass("FrictionContact",true);
Creator<Contact::Factory, FrictionContact<LineModel, RigidSphereModel> > LineRigidSphereFrictionContactClass("FrictionContact",true);
Creator<Contact::Factory, FrictionContact<TriangleModel, RigidSphereModel> > TriangleRigidSphereFrictionContactClass("FrictionContact",true);
Creator<Contact::Factory, FrictionContact<RigidSphereModel, PointModel> > RigidSpherePointFrictionContactClass("FrictionContact",true);
Creator<Contact::Factory, FrictionContact<CapsuleModel, RigidSphereModel> > CapsuleRigidSphereFrictionContactClass("FrictionContact",true);
Creator<Contact::Factory, FrictionContact<RigidSphereModel, OBBModel> > RigidSphereOBBFrictionContactClass("FrictionContact",true);
Creator<Contact::Factory, FrictionContact<RigidCapsuleModel, RigidCapsuleModel> > RigidCapsuleRigidCapsuleFrictionContactClass("FrictionContact",true);
Creator<Contact::Factory, FrictionContact<CapsuleModel, RigidCapsuleModel> > CapsuleRigidCapsuleFrictionContactClass("FrictionContact",true);
Creator<Contact::Factory, FrictionContact<RigidCapsuleModel, TriangleModel> > RigidCapsuleTriangleFrictionContactClass("FrictionContact",true);
Creator<Contact::Factory, FrictionContact<RigidCapsuleModel, SphereModel> > RigidCapsuleSphereFrictionContactClass("FrictionContact",true);
Creator<Contact::Factory, FrictionContact<RigidCapsuleModel, OBBModel> > RigidCapsuleOBBFrictionContactClass("FrictionContact",true);
Creator<Contact::Factory, FrictionContact<RigidCapsuleModel, RigidSphereModel> > RigidCapsuleRigidSphereFrictionContactClass("FrictionContact",true);

} // namespace collision

} // namespace component

} // namespace sofa
<commit_msg>r10824/sofa : FIX FrictionContact link on osx/clang<commit_after>/******************************************************************************
*       SOFA, Simulation Open-Framework Architecture, version 1.0 RC 1        *
*                (c) 2006-2011 MGH, INRIA, USTL, UJF, CNRS                    *
*                                                                             *
* This library is free software; you can redistribute it and/or modify it     *
* under the terms of the GNU Lesser General Public License as published by    *
* the Free Software Foundation; either version 2.1 of the License, or (at     *
* your option) any later version.                                             *
*                                                                             *
* This library is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
* for more details.                                                           *
*                                                                             *
* You should have received a copy of the GNU Lesser General Public License    *
* along with this library; if not, write to the Free Software Foundation,     *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
*******************************************************************************
*                               SOFA :: Modules                               *
*                                                                             *
* Authors: The SOFA Team and external contributors (see Authors.txt)          *
*                                                                             *
* Contact information: contact@sofa-framework.org                             *
******************************************************************************/
#include <sofa/component/collision/FrictionContact.inl>

#include <sofa/component/collision/RigidContactMapper.inl>
#include <sofa/component/collision/BarycentricContactMapper.inl>

namespace sofa
{

namespace component
{

namespace collision
{

using namespace defaulttype;
using namespace sofa::helper;
using simulation::Node;

sofa::core::collision::DetectionOutput::ContactId Identifier::cpt=0;
std::list<sofa::core::collision::DetectionOutput::ContactId> Identifier::availableId;

SOFA_DECL_CLASS(FrictionContact)

Creator<Contact::Factory, FrictionContact<PointModel, PointModel> > PointPointFrictionContactClass("FrictionContact",true);
Creator<Contact::Factory, FrictionContact<LineModel, SphereModel> > LineSphereFrictionContactClass("FrictionContact",true);
Creator<Contact::Factory, FrictionContact<LineModel, PointModel> > LinePointFrictionContactClass("FrictionContact",true);
Creator<Contact::Factory, FrictionContact<LineModel, LineModel> > LineLineFrictionContactClass("FrictionContact",true);
Creator<Contact::Factory, FrictionContact<TriangleModel, SphereModel> > TriangleSphereFrictionContactClass("FrictionContact",true);
Creator<Contact::Factory, FrictionContact<TriangleModel, PointModel> > TrianglePointFrictionContactClass("FrictionContact",true);
Creator<Contact::Factory, FrictionContact<TriangleModel, LineModel> > TriangleLineFrictionContactClass("FrictionContact",true);
Creator<Contact::Factory, FrictionContact<TriangleModel, TriangleModel> > TriangleTriangleFrictionContactClass("FrictionContact",true);
Creator<Contact::Factory, FrictionContact<SphereModel, SphereModel> > SphereSphereFrictionContactClass("FrictionContact",true);
Creator<Contact::Factory, FrictionContact<SphereModel, PointModel> > SpherePointFrictionContactClass("FrictionContact",true);
Creator<Contact::Factory, FrictionContact<CapsuleModel, CapsuleModel> > CapsuleCapsuleFrictionContactClass("FrictionContact",true);
Creator<Contact::Factory, FrictionContact<CapsuleModel, TriangleModel> > CapsuleTriangleFrictionContactClass("FrictionContact",true);
Creator<Contact::Factory, FrictionContact<CapsuleModel, SphereModel> > CapsuleSphereFrictionContactClass("FrictionContact",true);
Creator<Contact::Factory, FrictionContact<OBBModel, OBBModel> > OBBOBBFrictionContactClass("FrictionContact",true);
Creator<Contact::Factory, FrictionContact<SphereModel, OBBModel> > SphereOBBFrictionContactClass("FrictionContact",true);
Creator<Contact::Factory, FrictionContact<CapsuleModel, OBBModel> > CapsuleOBBFrictionContactClass("FrictionContact",true);
Creator<Contact::Factory, FrictionContact<TriangleModel, OBBModel> > TriangleOBBFrictionContactClass("FrictionContact",true);
Creator<Contact::Factory, FrictionContact<RigidSphereModel, RigidSphereModel> > RigidSphereRigidSphereFrictionContactClass("FrictionContact",true);
Creator<Contact::Factory, FrictionContact<SphereModel, RigidSphereModel> > SphereRigidSphereFrictionContactClass("FrictionContact",true);
Creator<Contact::Factory, FrictionContact<LineModel, RigidSphereModel> > LineRigidSphereFrictionContactClass("FrictionContact",true);
Creator<Contact::Factory, FrictionContact<TriangleModel, RigidSphereModel> > TriangleRigidSphereFrictionContactClass("FrictionContact",true);
Creator<Contact::Factory, FrictionContact<RigidSphereModel, PointModel> > RigidSpherePointFrictionContactClass("FrictionContact",true);
Creator<Contact::Factory, FrictionContact<CapsuleModel, RigidSphereModel> > CapsuleRigidSphereFrictionContactClass("FrictionContact",true);
Creator<Contact::Factory, FrictionContact<RigidSphereModel, OBBModel> > RigidSphereOBBFrictionContactClass("FrictionContact",true);
Creator<Contact::Factory, FrictionContact<RigidCapsuleModel, RigidCapsuleModel> > RigidCapsuleRigidCapsuleFrictionContactClass("FrictionContact",true);
Creator<Contact::Factory, FrictionContact<CapsuleModel, RigidCapsuleModel> > CapsuleRigidCapsuleFrictionContactClass("FrictionContact",true);
Creator<Contact::Factory, FrictionContact<RigidCapsuleModel, TriangleModel> > RigidCapsuleTriangleFrictionContactClass("FrictionContact",true);
Creator<Contact::Factory, FrictionContact<RigidCapsuleModel, SphereModel> > RigidCapsuleSphereFrictionContactClass("FrictionContact",true);
Creator<Contact::Factory, FrictionContact<RigidCapsuleModel, OBBModel> > RigidCapsuleOBBFrictionContactClass("FrictionContact",true);
Creator<Contact::Factory, FrictionContact<RigidCapsuleModel, RigidSphereModel> > RigidCapsuleRigidSphereFrictionContactClass("FrictionContact",true);

} // namespace collision

} // namespace component

} // namespace sofa
<|endoftext|>


<commit_before>#include <sys/resource.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <pthread.h>

static sigset_t DaemonSignalSet;

extern "C" {

/*
 * Signal handler thread for the daemon. Waits for one of the following
 * signals:
 * - SIGINT
 * - SIGTERM
 * - SIGQUIT
 * Once the signal is received, the stop method in the stop class in
 * the Java code is invoked and then the thread exits.
 */
static void *
DaemonSignalHandler(void *)
{
	int signo;
	int stop = 0;

	while (1) {
		sigwait(&DaemonSignalSet, &signo);

		switch (signo) {
			case SIGINT:
			case SIGTERM:
			case SIGQUIT:
				stop = 1;
				break;

			default:
				break;
		}

		if (stop) {
			if (StopDaemon() == JNI_OK) {
				break;
			}
		}
	}

	return 0;
}

}

/*
 * Checks if another instance of the daemon is already running. The running
 * daemon keeps a lock on pidPath. Please note that 'fd' is not closed.
 * This is intentional. Must be called after the process has daemonized
 * itself.
 *
 * @param [out] running - set to true if another instance of the daemon
 *                        is running, set to false otherwise.
 *
 * @return 0 on success, non-zero on failure.
 */
static int
DaemonAlreadyRunning(bool *running)
{
	const char      *caller = "DaemonAlreadyRunning";
	int             retval = 0;
	int             fd;
	struct flock    fl;

	*running = false;

	fd = open(TheDaemonArgs.pidPath.c_str(), O_CREAT | O_RDWR, 0644);
	if (fd < 0) {
		Log(ERR, caller, errno, "open(%s) failed",
			TheDaemonArgs.pidPath.c_str());
		return 1;
	} else {
		fl.l_type = F_WRLCK;
		fl.l_whence = SEEK_SET;
		fl.l_start = 0;
		fl.l_len = 0;

		if (fcntl(fd, F_SETLK, &fl) < 0) {
			if ((errno == EACCES) || (errno == EAGAIN)) {
				*running = true;
				retval = 0;
			} else {
				Log(ERR, caller, errno, "lock(%s) failed",
					TheDaemonArgs.pidPath.c_str());
				retval = 1;
			}
			close(fd);
		} else {
			char	buf[32];

			if (ftruncate(fd, 0) < 0) {
				Log(ERR, caller, errno, "ftruncate() failed");
				retval = 1;
			} else {
				int nbytes = snprintf(buf, sizeof(buf) - 1, "%d", getpid());
				buf[nbytes] = '\0';

				if (write(fd, buf, nbytes) < 0) {
					Log(ERR, caller, errno, "write() failed");
				}
			}

			// keep fd open; fd leak is justified.
		}
	}

	return retval;
}

/*
 * Sends SIGTERM signal to the daemon. The process' pid is obtained from
 * the pidPath.
 *
 * @return 0 on success, non-zero on failure.
 */
static int
DaemonStop(void)
{
	const char  *caller = "DaemonStop";
	int         retval = 0;
	FILE        *fp = 0;
	int         i, pid;

	fp = fopen(TheDaemonArgs.pidPath.c_str(), "r");
	if (fp) {
		i = fscanf(fp, "%d", &pid);
		if (i != 1) {
			Log(ERR, caller, errno,
				"unable to read pid from file %s",
				TheDaemonArgs.pidPath.c_str());
			retval = 1;
		} else {
			if (kill(pid, SIGTERM) < 0) {
				Log(ERR, caller, errno,
					"unable to kill process %d", pid);
				retval = 1;
			}
		}

		fclose(fp);
	} else {
		Log(ERR, caller, errno,
			"unable to open file %s",
			TheDaemonArgs.pidPath.c_str());
		retval = 1;
	}

	return retval;
}

/*
 * Turns the calling process into a daemon process. It does the following:
 * - Sets the umask to 0.
 * - Forks and let the parent exit.
 * - Creates a new session (setsid).
 * - Change directory to the home directory.
 * - Close all the open file descriptors (0, 1, and 2 are most important).
 * - Initialize the Logging.
 * - Check if only a single instance of the daemon is running.
 * - Blocks SIGINT, SIGTERM, SIGQUIT signal.
 * - Starts another thread to handle those events.
 * - Use JNI invoke APIs to load JVM.
 * - Calls the start method in the start class in the Java code.
 *
 * @return 0 on success, non-zero on failure.
 */
static int
Daemonize(void)
{
	const char      *caller = "Daemonize";
	int             retval = 0;
	bool            alreadyRunning;
	pid_t           pid;
	struct rlimit   rl;
	pthread_t       tid;

	umask(0);

	pid = fork();
	if (pid < 0) {
		Log(ERR, caller, errno, "fork() failed");
		return 1;
	}

	if (pid != 0)
		exit(0);

	if (setsid() < 0) {
		Log(ERR, caller, errno, "setsid() failed");
		return 1;
	}

	if (chdir(TheDaemonArgs.home.c_str()) < 0) {
		Log(ERR, caller, errno, "chdir(%s) failed",
			TheDaemonArgs.home.c_str());
		return 1;
	}

	if (getrlimit(RLIMIT_NOFILE, &rl) < 0) {
		Log(ERR, caller, errno, "getrlimit() failed");
		return 1;
	}

	if (rl.rlim_max == RLIM_INFINITY) {
		rl.rlim_max = 1024;
	}

	for (rlim_t r = 0; r < rl.rlim_max; ++r) {
		close((int)r);
	}

	FileLogger *fileLogger = new FileLogger(TheDaemonArgs.logPath.c_str(), TheVerbosity);
	fileLogger->makeLogPath();
	TheLogger = fileLogger;

	Log(INF, caller, "starting daemon");
	LogDaemonArgs();

	retval = DaemonAlreadyRunning(&alreadyRunning);
	if (retval != 0) {
		return retval;
	} else if (alreadyRunning) {
		Log(WRN, caller, "another instance of %s already running",
			TheDaemonArgs.name.c_str());
		return 1;
	}

	sigemptyset(&DaemonSignalSet);
	sigaddset(&DaemonSignalSet, SIGINT);
	sigaddset(&DaemonSignalSet, SIGTERM);
	sigaddset(&DaemonSignalSet, SIGQUIT);

	retval = pthread_sigmask(SIG_BLOCK, &DaemonSignalSet, NULL);
	if (retval != 0) {
		Log(ERR, caller, retval, "pthread_sigmask() failed");
		return 1;
	}

	retval = pthread_create(&tid, 0, DaemonSignalHandler, 0);
	if (retval != 0) {
		Log(ERR, caller, retval, "pthread_create() failed");
		return 1;
	}

	if (StartDaemon() == JNI_OK) {
		Log(INF, caller, "daemon running");
	} else {
		Log(ERR, caller, "failed to call Java code");
		kill(getpid(), SIGTERM);
	}

	retval = pthread_join(tid, 0);
	if (retval != 0) {
		Log(ERR, caller, retval, "pthread_join() failed");
		return 1;
	}

	if (TheJVM) {
		TheJVM->DestroyJavaVM();
		Log(DBG, caller, "JVM destroyed");
	}

	Log(INF, caller, "daemon stopped");

	delete TheLogger;

	return 0;
}
<commit_msg>Use pthread_kill() instead of kill() when StartDedaemon() fails.<commit_after>#include <sys/resource.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <pthread.h>

static sigset_t DaemonSignalSet;

extern "C" {

/*
 * Signal handler thread for the daemon. Waits for one of the following
 * signals:
 * - SIGINT
 * - SIGTERM
 * - SIGQUIT
 * Once the signal is received, the stop method in the stop class in
 * the Java code is invoked and then the thread exits.
 */
static void *
DaemonSignalHandler(void *)
{
	int signo;
	int stop = 0;

	while (1) {
		sigwait(&DaemonSignalSet, &signo);

		switch (signo) {
			case SIGINT:
			case SIGTERM:
			case SIGQUIT:
				stop = 1;
				break;

			default:
				break;
		}

		if (stop) {
			if (StopDaemon() == JNI_OK) {
				break;
			}
		}
	}

	return 0;
}

}

/*
 * Checks if another instance of the daemon is already running. The running
 * daemon keeps a lock on pidPath. Please note that 'fd' is not closed.
 * This is intentional. Must be called after the process has daemonized
 * itself.
 *
 * @param [out] running - set to true if another instance of the daemon
 *                        is running, set to false otherwise.
 *
 * @return 0 on success, non-zero on failure.
 */
static int
DaemonAlreadyRunning(bool *running)
{
	const char      *caller = "DaemonAlreadyRunning";
	int             retval = 0;
	int             fd;
	struct flock    fl;

	*running = false;

	fd = open(TheDaemonArgs.pidPath.c_str(), O_CREAT | O_RDWR, 0644);
	if (fd < 0) {
		Log(ERR, caller, errno, "open(%s) failed",
			TheDaemonArgs.pidPath.c_str());
		return 1;
	} else {
		fl.l_type = F_WRLCK;
		fl.l_whence = SEEK_SET;
		fl.l_start = 0;
		fl.l_len = 0;

		if (fcntl(fd, F_SETLK, &fl) < 0) {
			if ((errno == EACCES) || (errno == EAGAIN)) {
				*running = true;
				retval = 0;
			} else {
				Log(ERR, caller, errno, "lock(%s) failed",
					TheDaemonArgs.pidPath.c_str());
				retval = 1;
			}
			close(fd);
		} else {
			char	buf[32];

			if (ftruncate(fd, 0) < 0) {
				Log(ERR, caller, errno, "ftruncate() failed");
				retval = 1;
			} else {
				int nbytes = snprintf(buf, sizeof(buf) - 1, "%d", getpid());
				buf[nbytes] = '\0';

				if (write(fd, buf, nbytes) < 0) {
					Log(ERR, caller, errno, "write() failed");
				}
			}

			// keep fd open; fd leak is justified.
		}
	}

	return retval;
}

/*
 * Sends SIGTERM signal to the daemon. The process' pid is obtained from
 * the pidPath.
 *
 * @return 0 on success, non-zero on failure.
 */
static int
DaemonStop(void)
{
	const char  *caller = "DaemonStop";
	int         retval = 0;
	FILE        *fp = 0;
	int         i, pid;

	fp = fopen(TheDaemonArgs.pidPath.c_str(), "r");
	if (fp) {
		i = fscanf(fp, "%d", &pid);
		if (i != 1) {
			Log(ERR, caller, errno,
				"unable to read pid from file %s",
				TheDaemonArgs.pidPath.c_str());
			retval = 1;
		} else {
			if (kill(pid, SIGTERM) < 0) {
				Log(ERR, caller, errno,
					"unable to kill process %d", pid);
				retval = 1;
			}
		}

		fclose(fp);
	} else {
		Log(ERR, caller, errno,
			"unable to open file %s",
			TheDaemonArgs.pidPath.c_str());
		retval = 1;
	}

	return retval;
}

/*
 * Turns the calling process into a daemon process. It does the following:
 * - Sets the umask to 0.
 * - Forks and let the parent exit.
 * - Creates a new session (setsid).
 * - Change directory to the home directory.
 * - Close all the open file descriptors (0, 1, and 2 are most important).
 * - Initialize the Logging.
 * - Check if only a single instance of the daemon is running.
 * - Blocks SIGINT, SIGTERM, SIGQUIT signal.
 * - Starts another thread to handle those events.
 * - Use JNI invoke APIs to load JVM.
 * - Calls the start method in the start class in the Java code.
 *
 * @return 0 on success, non-zero on failure.
 */
static int
Daemonize(void)
{
	const char      *caller = "Daemonize";
	int             retval = 0;
	bool            alreadyRunning;
	pid_t           pid;
	struct rlimit   rl;
	pthread_t       tid;

	umask(0);

	pid = fork();
	if (pid < 0) {
		Log(ERR, caller, errno, "fork() failed");
		return 1;
	}

	if (pid != 0)
		exit(0);

	if (setsid() < 0) {
		Log(ERR, caller, errno, "setsid() failed");
		return 1;
	}

	if (chdir(TheDaemonArgs.home.c_str()) < 0) {
		Log(ERR, caller, errno, "chdir(%s) failed",
			TheDaemonArgs.home.c_str());
		return 1;
	}

	if (getrlimit(RLIMIT_NOFILE, &rl) < 0) {
		Log(ERR, caller, errno, "getrlimit() failed");
		return 1;
	}

	if (rl.rlim_max == RLIM_INFINITY) {
		rl.rlim_max = 1024;
	}

	for (rlim_t r = 0; r < rl.rlim_max; ++r) {
		close((int)r);
	}

	FileLogger *fileLogger = new FileLogger(TheDaemonArgs.logPath.c_str(), TheVerbosity);
	fileLogger->makeLogPath();
	TheLogger = fileLogger;

	Log(INF, caller, "starting daemon");
	LogDaemonArgs();

	retval = DaemonAlreadyRunning(&alreadyRunning);
	if (retval != 0) {
		return retval;
	} else if (alreadyRunning) {
		Log(WRN, caller, "another instance of %s already running",
			TheDaemonArgs.name.c_str());
		return 1;
	}

	sigemptyset(&DaemonSignalSet);
	sigaddset(&DaemonSignalSet, SIGINT);
	sigaddset(&DaemonSignalSet, SIGTERM);
	sigaddset(&DaemonSignalSet, SIGQUIT);

	retval = pthread_sigmask(SIG_BLOCK, &DaemonSignalSet, NULL);
	if (retval != 0) {
		Log(ERR, caller, retval, "pthread_sigmask() failed");
		return 1;
	}

	retval = pthread_create(&tid, 0, DaemonSignalHandler, 0);
	if (retval != 0) {
		Log(ERR, caller, retval, "pthread_create() failed");
		return 1;
	}

	if (StartDaemon() == JNI_OK) {
		Log(INF, caller, "daemon running");
	} else {
		Log(ERR, caller, "failed to call Java code");
		pthread_kill(tid, SIGTERM);
	}

	retval = pthread_join(tid, 0);
	if (retval != 0) {
		Log(ERR, caller, retval, "pthread_join() failed");
		return 1;
	}

	if (TheJVM) {
		TheJVM->DestroyJavaVM();
		Log(DBG, caller, "JVM destroyed");
	}

	Log(INF, caller, "daemon stopped");

	delete TheLogger;

	return 0;
}
<|endoftext|>


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

#include <pcl/visualization/cloud_viewer.h>
#include <pcl/visualization/pcl_visualizer.h>

#include <boost/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/foreach.hpp>

namespace pcl
{
  struct cloud_show_base
  {
    virtual void pop () = 0;
    virtual bool popped () const = 0;
    typedef boost::shared_ptr<cloud_show_base> Ptr;
  };

  template <typename CloudT>
  struct cloud_show : cloud_show_base
  {
    cloud_show (const std::string &cloud_name, typename CloudT::ConstPtr cloud,
      boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer) :
      cloud_name (cloud_name), cloud (cloud), viewer (viewer),popped_ (false)
    {}

    template <typename Handler> void
    pop (const Handler &handler)
    {
      double psize = 1.0, opacity = 1.0, linesize =1.0;
      viewer->getPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_LINE_WIDTH, linesize, cloud_name);
      viewer->getPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_OPACITY, opacity, cloud_name);
      viewer->getPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, psize, cloud_name);

      if (!viewer->updatePointCloud (cloud, handler, cloud_name))
      {
        viewer->addPointCloud (cloud, handler, cloud_name);
        viewer->resetCameraViewpoint (cloud_name);
      }

      // viewer->removePointCloud (cloud_name);
      viewer->setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_LINE_WIDTH, linesize, cloud_name);
      viewer->setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_OPACITY, opacity, cloud_name);
      viewer->setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, psize, cloud_name);
      popped_ = true;
    }

    virtual void pop ();

    virtual bool
    popped () const
    {
      return popped_;
    }

    std::string cloud_name;
    typename CloudT::ConstPtr cloud;
    boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer;
    bool popped_;
  };

  typedef pcl::PointCloud<pcl::PointXYZRGB> cc;
  typedef pcl::PointCloud<pcl::PointXYZI> gc;
  typedef pcl::PointCloud<pcl::PointXYZ> mc;

  template <> void
  cloud_show<cc>::pop ()
  {
    pcl::visualization::PointCloudColorHandlerRGBField<pcl::PointXYZRGB> handler (cloud);
    pop (handler);
  }

  template <> void
  cloud_show<gc>::pop ()
  {
    pcl::visualization::PointCloudGeometryHandlerXYZ<pcl::PointXYZI> handler (cloud);
    pop (handler);
  }

  template <> void
  cloud_show<mc>::pop ()
  {
    pcl::visualization::PointCloudGeometryHandlerXYZ<pcl::PointXYZ> handler (cloud);
    pop (handler);
  }
}

struct pcl::visualization::CloudViewer::CloudViewer_impl
{
  ////////////////////////////////////////////////////////////////////////////////////////////
  CloudViewer_impl (const std::string& window_name) :
    window_name_ (window_name), has_cloud_ (false), quit_ (false)
  {
    viewer_thread_ = boost::thread (boost::ref (*this));
    while (!viewer_)
    {
      boost::thread::yield ();
    }
  }

  ~CloudViewer_impl ()
  {
  }

  ////////////////////////////////////////////////////////////////////////////////////////////
  template <typename T> void
  block_post_cloud (const typename T::ConstPtr &cloud, const std::string &name)
  {
    cloud_show_base::Ptr cs (new cloud_show<T>(name,cloud,viewer_));
    {
      boost::mutex::scoped_lock lock (mtx_);
      cloud_shows_.push_back (cs);
    }
    while (!cs->popped ())
    {
      boost::thread::yield ();
    }
  }

  template <typename T> void
  nonblock_post_cloud (const typename T::ConstPtr &cloud, const std::string &name)
  {
    cloud_show_base::Ptr cs (new cloud_show<T>(name,cloud,viewer_));
    {
      boost::mutex::scoped_lock lock (mtx_);

      cloud_shows_.push_back (cs);
    }
  }

  ////////////////////////////////////////////////////////////////////////////////////////////
  void
  operator() ()
  {
    using namespace pcl::visualization;

    viewer_ = boost::shared_ptr<PCLVisualizer>(new PCLVisualizer (window_name_));
    viewer_->setBackgroundColor (0.1, 0.1, 0.1);
    viewer_->addCoordinateSystem (0.1);

    while (!quit_)
    {
      {
        boost::mutex::scoped_lock lock (mtx_);
        while (!cloud_shows_.empty ())
        {
          cloud_shows_.back ()->pop ();
          cloud_shows_.pop_back ();
        }
      }
      {
        boost::mutex::scoped_lock lock (once_mtx);
        BOOST_FOREACH (CallableList::value_type& x, callables_once)
        {
          (x)(*viewer_);
        }
        callables_once.clear ();
      }
      {
        boost::mutex::scoped_lock lock (c_mtx);
        BOOST_FOREACH (CallableMap::value_type& x, callables)
        {
          (x.second)(*viewer_);
        }
      }
      if (viewer_->wasStopped ())
      {
          quit_ = true;
      }else
      {
        boost::mutex::scoped_lock lock (spin_mtx_);
        //TODO some smart waitkey like stuff here, so that wasStoped() can hold for a long time
        //maybe a counter
        viewer_->spinOnce (10); // Give the GUI millis to handle events, then return
      }

    }
    viewer_.reset();
  }

  ////////////////////////////////////////////////////////////////////////////////////////////
  void
  post (VizCallable x, const std::string &key)
  {
    boost::mutex::scoped_lock lock (c_mtx);
    callables[key] = x;
  }

  void
  post (VizCallable x)
  {
    boost::mutex::scoped_lock lock (once_mtx);
    callables_once.push_back (x);

  }

  ////////////////////////////////////////////////////////////////////////////////////////////
  void
  remove (const std::string &key)
  {
    boost::mutex::scoped_lock lock (c_mtx);
    if (callables.find (key) != callables.end ())
    {
      callables.erase (key);
    }
  }

  std::string window_name_;
  boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer_;
  boost::mutex mtx_, spin_mtx_, c_mtx, once_mtx;
  boost::thread viewer_thread_;
  bool has_cloud_;
  bool quit_;
  std::list<boost::shared_ptr<cloud_show_base> > cloud_shows_;
  typedef std::map<std::string, VizCallable> CallableMap;
  CallableMap callables;
  typedef std::list<VizCallable> CallableList;
  CallableList callables_once;
};

pcl::visualization::CloudViewer::CloudViewer (const std::string &window_name) :
  impl_ (new CloudViewer_impl (window_name))
{}

pcl::visualization::CloudViewer::~CloudViewer ()
{
  impl_->quit_ = true;
  impl_->viewer_thread_.join();
}

void
pcl::visualization::CloudViewer::showCloud (const ColorCloud::ConstPtr &cloud,
                                            const std::string &cloudname)
{
  if (!impl_->viewer_ || impl_->viewer_->wasStopped ())
    return;
  impl_->block_post_cloud<ColorCloud>(cloud, cloudname);
}

void
pcl::visualization::CloudViewer::showCloud (const GrayCloud::ConstPtr &cloud,
                                            const std::string &cloudname)
{
  if (!impl_->viewer_ || impl_->viewer_->wasStopped ())
    return;
  impl_->block_post_cloud<GrayCloud>(cloud, cloudname);
}

void
pcl::visualization::CloudViewer::showCloud (const MonochromeCloud::ConstPtr &cloud,
                                            const std::string &cloudname)
{
  if (!impl_->viewer_ || impl_->viewer_->wasStopped ())
    return;
  impl_->block_post_cloud<MonochromeCloud>(cloud, cloudname);
}

void
pcl::visualization::CloudViewer::runOnVisualizationThread (VizCallable x, const std::string &key)
{
  impl_->post (x, key);
}

void
pcl::visualization::CloudViewer::runOnVisualizationThreadOnce (VizCallable x)
{
  impl_->post (x);
}

void
pcl::visualization::CloudViewer::removeVisualizationCallable (const std::string &key)
{
  impl_->remove (key);
}

bool
pcl::visualization::CloudViewer::wasStopped (int millis)
{
  boost::thread::yield (); //allow this to be called in a loop
  return !impl_->viewer_;
}

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

#include <pcl/visualization/cloud_viewer.h>
#include <pcl/visualization/pcl_visualizer.h>

#include <boost/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/foreach.hpp>

namespace pcl
{
  struct cloud_show_base
  {
    virtual void pop () = 0;
    virtual bool popped () const = 0;
    typedef boost::shared_ptr<cloud_show_base> Ptr;
  };

  template <typename CloudT>
  struct cloud_show : cloud_show_base
  {
    cloud_show (const std::string &cloud_name, typename CloudT::ConstPtr cloud,
      boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer) :
      cloud_name (cloud_name), cloud (cloud), viewer (viewer),popped_ (false)
    {}

    template <typename Handler> void
    pop (const Handler &handler)
    {
      double psize = 1.0, opacity = 1.0, linesize =1.0;
      viewer->getPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_LINE_WIDTH, linesize, cloud_name);
      viewer->getPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_OPACITY, opacity, cloud_name);
      viewer->getPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, psize, cloud_name);

      if (!viewer->updatePointCloud (cloud, handler, cloud_name))
      {
        viewer->addPointCloud (cloud, handler, cloud_name);
        viewer->resetCameraViewpoint (cloud_name);
      }

      // viewer->removePointCloud (cloud_name);
      viewer->setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_LINE_WIDTH, linesize, cloud_name);
      viewer->setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_OPACITY, opacity, cloud_name);
      viewer->setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, psize, cloud_name);
      popped_ = true;
    }

    virtual void pop ();

    virtual bool
    popped () const
    {
      return popped_;
    }

    std::string cloud_name;
    typename CloudT::ConstPtr cloud;
    boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer;
    bool popped_;
  };

  typedef pcl::PointCloud<pcl::PointXYZRGB> cc;
  typedef pcl::PointCloud<pcl::PointXYZI> gc;
  typedef pcl::PointCloud<pcl::PointXYZ> mc;

  template <> void
  cloud_show<cc>::pop ()
  {
    pcl::visualization::PointCloudColorHandlerRGBField<pcl::PointXYZRGB> handler (cloud);
    pop (handler);
  }

  template <> void
  cloud_show<gc>::pop ()
  {
    pcl::visualization::PointCloudColorHandlerGenericField<pcl::PointXYZI> handler (cloud, "intensity");
    pop (handler);
  }

  template <> void
  cloud_show<mc>::pop ()
  {
    pcl::visualization::PointCloudGeometryHandlerXYZ<pcl::PointXYZ> handler (cloud);
    pop (handler);
  }
}

struct pcl::visualization::CloudViewer::CloudViewer_impl
{
  ////////////////////////////////////////////////////////////////////////////////////////////
  CloudViewer_impl (const std::string& window_name) :
    window_name_ (window_name), has_cloud_ (false), quit_ (false)
  {
    viewer_thread_ = boost::thread (boost::ref (*this));
    while (!viewer_)
    {
      boost::thread::yield ();
    }
  }

  ~CloudViewer_impl ()
  {
  }

  ////////////////////////////////////////////////////////////////////////////////////////////
  template <typename T> void
  block_post_cloud (const typename T::ConstPtr &cloud, const std::string &name)
  {
    cloud_show_base::Ptr cs (new cloud_show<T>(name,cloud,viewer_));
    {
      boost::mutex::scoped_lock lock (mtx_);
      cloud_shows_.push_back (cs);
    }
    while (!cs->popped ())
    {
      boost::thread::yield ();
    }
  }

  template <typename T> void
  nonblock_post_cloud (const typename T::ConstPtr &cloud, const std::string &name)
  {
    cloud_show_base::Ptr cs (new cloud_show<T>(name,cloud,viewer_));
    {
      boost::mutex::scoped_lock lock (mtx_);

      cloud_shows_.push_back (cs);
    }
  }

  ////////////////////////////////////////////////////////////////////////////////////////////
  void
  operator() ()
  {
    using namespace pcl::visualization;

    viewer_ = boost::shared_ptr<PCLVisualizer>(new PCLVisualizer (window_name_));
    viewer_->setBackgroundColor (0.1, 0.1, 0.1);
    viewer_->addCoordinateSystem (0.1);

    while (!quit_)
    {
      {
        boost::mutex::scoped_lock lock (mtx_);
        while (!cloud_shows_.empty ())
        {
          cloud_shows_.back ()->pop ();
          cloud_shows_.pop_back ();
        }
      }
      {
        boost::mutex::scoped_lock lock (once_mtx);
        BOOST_FOREACH (CallableList::value_type& x, callables_once)
        {
          (x)(*viewer_);
        }
        callables_once.clear ();
      }
      {
        boost::mutex::scoped_lock lock (c_mtx);
        BOOST_FOREACH (CallableMap::value_type& x, callables)
        {
          (x.second)(*viewer_);
        }
      }
      if (viewer_->wasStopped ())
      {
          quit_ = true;
      }else
      {
        boost::mutex::scoped_lock lock (spin_mtx_);
        //TODO some smart waitkey like stuff here, so that wasStoped() can hold for a long time
        //maybe a counter
        viewer_->spinOnce (10); // Give the GUI millis to handle events, then return
      }

    }
    viewer_.reset();
  }

  ////////////////////////////////////////////////////////////////////////////////////////////
  void
  post (VizCallable x, const std::string &key)
  {
    boost::mutex::scoped_lock lock (c_mtx);
    callables[key] = x;
  }

  void
  post (VizCallable x)
  {
    boost::mutex::scoped_lock lock (once_mtx);
    callables_once.push_back (x);

  }

  ////////////////////////////////////////////////////////////////////////////////////////////
  void
  remove (const std::string &key)
  {
    boost::mutex::scoped_lock lock (c_mtx);
    if (callables.find (key) != callables.end ())
    {
      callables.erase (key);
    }
  }

  std::string window_name_;
  boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer_;
  boost::mutex mtx_, spin_mtx_, c_mtx, once_mtx;
  boost::thread viewer_thread_;
  bool has_cloud_;
  bool quit_;
  std::list<boost::shared_ptr<cloud_show_base> > cloud_shows_;
  typedef std::map<std::string, VizCallable> CallableMap;
  CallableMap callables;
  typedef std::list<VizCallable> CallableList;
  CallableList callables_once;
};

pcl::visualization::CloudViewer::CloudViewer (const std::string &window_name) :
  impl_ (new CloudViewer_impl (window_name))
{}

pcl::visualization::CloudViewer::~CloudViewer ()
{
  impl_->quit_ = true;
  impl_->viewer_thread_.join();
}

void
pcl::visualization::CloudViewer::showCloud (const ColorCloud::ConstPtr &cloud,
                                            const std::string &cloudname)
{
  if (!impl_->viewer_ || impl_->viewer_->wasStopped ())
    return;
  impl_->block_post_cloud<ColorCloud>(cloud, cloudname);
}

void
pcl::visualization::CloudViewer::showCloud (const GrayCloud::ConstPtr &cloud,
                                            const std::string &cloudname)
{
  if (!impl_->viewer_ || impl_->viewer_->wasStopped ())
    return;
  impl_->block_post_cloud<GrayCloud>(cloud, cloudname);
}

void
pcl::visualization::CloudViewer::showCloud (const MonochromeCloud::ConstPtr &cloud,
                                            const std::string &cloudname)
{
  if (!impl_->viewer_ || impl_->viewer_->wasStopped ())
    return;
  impl_->block_post_cloud<MonochromeCloud>(cloud, cloudname);
}

void
pcl::visualization::CloudViewer::runOnVisualizationThread (VizCallable x, const std::string &key)
{
  impl_->post (x, key);
}

void
pcl::visualization::CloudViewer::runOnVisualizationThreadOnce (VizCallable x)
{
  impl_->post (x);
}

void
pcl::visualization::CloudViewer::removeVisualizationCallable (const std::string &key)
{
  impl_->remove (key);
}

bool
pcl::visualization::CloudViewer::wasStopped (int millis)
{
  boost::thread::yield (); //allow this to be called in a loop
  return !impl_->viewer_;
}

<|endoftext|>


<commit_before>// Copyright (c) Facebook Inc. and Microsoft Corporation.
// Licensed under the MIT license.

#include "onnx/defs/schema.h"

using AttrType = onnx::OpSchema::AttrType;
using namespace onnx;

OPERATOR_SCHEMA(SimpleRNN)
    .NumInputs(3, 6)
    .NumOutputs(1, 2)
    .SetDoc(R"DOC(
Computes an one-layer simple RNN. This operator is usually supported
via some custom implementation such as CuDNN.

Notations:
`X` - input tensor
`i` - input gate
`t` - time step (t-1 means previous time step)
`Wi` - W parameter weight matrix for input gate
`Ri` - R recurrence weight matrix for input gate
`Wbi` - W parameter bias vector for input gate
`Rbi` - R parameter bias vector for input gate
`WBi` - W parameter weight matrix for backward input gate
`RBi` - R recurrence weight matrix for backward input gate
`WBbi` - WR bias vectors for backward input gate
`RBbi` - RR bias vectors for backward input gate
`ReLU(X)` - max(X, 0)
`tanh(X)` - hyperbolic tangent of X
`H` - Hidden state
`num_directions` - 2 if direction == bidirectional else 1

Equations:
  - Ht = Activation(Wi*Xt + Ri*Ht-1 + Wbi + Rbi)
)DOC")
    .Attr("activation", "The activation function for input gate. It must be "
	  "one of tanh and ReLU. Default `tanh`.",
          AttrType::STRING)
    .Attr("hidden_size", "Number of neurons in the hidden layer", AttrType::INT)
    .Attr("direction", "Specify if the RNN is forward, reverse, or bidirectional. "
          "Must be one of forward (default), reverse, or bidirectional.",
          AttrType::STRING)
    .Attr("clip", "Cell clip threshold. Clipping bounds the elements of a tensor "
          "in the range of [-threshold, +threshold] and is applied to the input "
          "of activations. No clip if not specified.",
          AttrType::FLOAT)
    .Input(0, "input",
           "The input sequences packed (and potentially padded) into one 3-D "
           "tensor with the shape of `[seq_length, batch_size, input_size]`.", "T")
    .Input(1, "W",
	   "The weight tensor for input gate. Concatenation of `Wi` and `WBi` "
           "(if bidirectional). The tensor has shape "
           "`num_directions, hidden_size, input_size]`.", "T")
    .Input(2, "R",
	   "The recurrence weight tensor. Concatenation of `Ri` and `RBi` "
           "(if bidirectional). The tensor has shape "
	   "`[num_directions, hidden_size, hidden_size}`.", "T")
    .Input(3, "B",
	   "The bias tensor for input gate. Concatenation of `[Wbi, Rbi]`, "
           "and `[WBbi, RBbi]` (if bidirectional). The tensor has shape "
           "`[num_directions, 2*hidden_size]`, Optional: If not specified - assumed "
           "to be 0.", "T",
	   true /*optional*/)
    .Input(4, "initial_h",
	   "Optional initial value of the hidden. If not specified - assumed "
	   "to be 0. It has shape either `[num_directions, batch_size, hidden_size]`.",
	   "T", true /*optional*/)
    .Input(5, "seq_lens",
           "Optional tensor specifying lengths of the sequences in a batch. "
           "If not specified - assumed all sequences in the batch to have "
	   "length `seq_length`. It has shape `[batch_size]`.", "T1",
	   true /*optional*/)
    .Output(0, "output",
	    "A tensor that concats all the intermediate output values of the hidden."
	    "It has shape `[seq_length, num_directions, batch_size, hidden_size]`.", "T")
    .Output(1, "output_h",
            "The last output value of the hidden. It has shape "
	    "`[num_directions, batch_size, hidden_size]`.", "T")
    .TypeConstraint("T", { "tensor(float16)", "tensor(float)", "tensor(double)" },
                    "Constrain input and output types to float tensors.")
    .TypeConstraint("T1", { "tensor(int32)" }, "Constrain seq_lens to integer tensor.");

OPERATOR_SCHEMA(GRU)
    .NumInputs(3, 6)
    .NumOutputs(1, 2)
    .SetDoc(R"DOC(
Computes an one-layer GRU. This operator is usually supported via some custom
implementation such as CuDNN.

Notations:
`X` - input tensor
`z` - update gate
`r` - reset gate
`h` - hidden gate
`t` - time step (t-1 means previous time step)
`W[zrh]` - W parameter weight matrix for update, reset, and hidden gates
`R[zrh]` - R recurrence weight matrix for update, reset, and hidden gates
`Wb[zrh]` - W bias vectors for update, reset, and hidden gates
`Rb[zrh]` - R bias vectors for update, reset, and hidden gates
`WB[zrh]` - W parameter weight matrix for backward update, reset, and hidden gates
`RB[zrh]` - R recurrence weight matrix for backward update, reset, and hidden gates
`WBb[zrh]` - W bias vectors for backward update, reset, and hidden gates
`RBb[zrh]` - R bias vectors for backward update, reset, and hidden gates
`tanh(X)` - hyperbolic tangent of X
`sigmoid(X)` - 1 / (1 + e^-X)
`H` - Hidden state
`num_directions` - 2 if direction == bidirectional else 1

Equations (GRU with default activations):
  - zt = sigmoid(Wz*Xt + Rz*Ht-1 + Wbz + Rbz)
  - rt = sigmoid(Wr*Xt + Rr*Ht-1 + Wbr + Rbr)
  - ht = tanh(Wh*Xt + rt*(Rh*Ht-1 + Rbh) + Wbh)
  - H = (1 - zt) (.) ht + it (.) Ht-1
)DOC")
    .Attr("activations", "A list of 3 activation functions for update, reset, and "
	  "hidden gates. The activation functions must be one of sigmoid and tanh. "
          "See the equations for default if not specified.",
          AttrType::STRINGS)
    .Attr("hidden_size", "Number of neurons in the hidden layer", AttrType::INT)
    .Attr("direction", "Specify if the RNN is forward, reverse, or bidirectional. "
          "Must be one of forward (default), reverse, or bidirectional.",
          AttrType::STRING)
    .Attr("clip", "Cell clip threshold. Clipping bounds the elements of a tensor "
          "in the range of [-threshold, +threshold] and is applied to the input "
          "of activations. No clip if not specified.",
          AttrType::FLOAT)
    .Input(0, "input",
           "The input sequences packed (and potentially padded) into one 3-D "
           "tensor with the shape of `[seq_length, batch_size, input_size]`.", "T")
    .Input(1, "W",
	   "The weight tensor for the gates. Concatenation of `W[zrh]` and `WB[zrh]` "
	   "(if bidirectional) along dimension 0. This tensor has shape "
	   "`[num_directions, 3*hidden_size, input_size]`.", "T")
    .Input(2, "R",
	   "The recurrence weight tensor. Concatenation of `R[zrh]` and `RB[zrh]` "
	   "(if bidirectional) along dimension 0. This tensor has shape "
	   "`[num_directions, 3*hidden_size, hidden_size}`.", "T")
    .Input(3, "B",
	   "The bias tensor for the gates. Concatenation of `[Wb[zrh], Rb[zrh]]` and "
           "`[WBb[zrh], RBb[zrh]]` (if bidirectional) along dimension 0. This tensor "
           "has shape `[num_directions, 6*hidden_size]`. Optional: If not specified "
           "- assumed to be 0", "T",
	   true /*optional*/)
    .Input(4, "initial_h",
	   "Optional initial value of the hidden. If not specified - assumed "
	   "to be 0. It has shape `[num_directions, batch_size, hidden_size]`.",
	   "T", true /*optional*/)
    .Input(5, "seq_lens",
           "Optional tensor specifying lengths of the sequences in a batch. "
           "If not specified - assumed all sequences in the batch to have "
	   "length `seq_length`. It has shape `[batch_size]`.",
	   "T1", true /*optional*/)
    .Output(0, "output",
	    "A tensor that concats all the intermediate output values of the "
	    "hidden. It has shape `[seq_length, num_directions, batch_size, hidden_size]`.",
            "T")
    .Output(1, "output_h",
            "The last output value of the hidden. It has shape "
	    "`[num_directions, batch_size, hidden_size]`.", "T")
    .TypeConstraint("T", { "tensor(float16)", "tensor(float)", "tensor(double)" },
                    "Constrain input and output types to float tensors.")
    .TypeConstraint("T1", { "tensor(int32)" }, "Constrain seq_lens to integer tensor.");

OPERATOR_SCHEMA(LSTM)
    .NumInputs(3, 8)
    .NumOutputs(1, 2)
    .SetDoc(R"DOC(
Computes an one-layer LSTM. This operator is usually supported via some
custom implementation such as CuDNN.

Notations:
`X` - input tensor
`i` - input gate
`o` - output gate
`f` - forget gate
`c` - cell gate
`t` - time step (t-1 means previous time step)
`W[iofc]` - W parameter weight matrix for input, output, forget, and cell gates
`R[iofc]` - R recurrence weight matrix for input, output, forget, and cell gates
`Wb[iofc]` - W bias vectors for input, output, forget, and cell gates
`Rb[iofc]` - R bias vectors for input, output, forget, and cell gates
`P[iof]`  - P peephole weight matrix for input, output, and forget gates
`WB[iofc]` - W parameter weight matrix for backward input, output, forget, and cell gates
`RB[iofc]` - R recurrence weight matrix for backward input, output, forget, and cell gates
`WBb[iofc]` - W bias vectors for backward input, output, forget, and cell gates
`RBb[iofc]` - R bias vectors for backward input, output, forget, and cell gates
`PB[iof]`  - P peephole weight matrix for backward input, output, and forget gates
`tanh(X)` - hyperbolic tangent of X
`sigmoid(X)` - 1 / (1 + e^-X)
`H` - Hidden state
`num_directions` - 2 if direction == bidirectional else 1

Equations (forward LSTM with default activations and peepholes):
  - it = sigmoid(Wi*Xt + Ri*Ht-1 + Pi (.) Ct-1 + Wbi + Rbi)
  - ft = sigmoid(Wf*Xt + Rf*Ht-1 + Pf (.) Ct-1 + Wbf + Rbf)
  - ct = tanh(Wc*Xt + Rc*Ht-1 + Wbc + Rbc)
  - Ct = ft (.) Ct-1 + it (.) ct
  - ot = sigmoid(Wo*Xt + Ro*Ht-1 + Po (.) Ct + Wbo + Rbo)
  - H = ot (.) tanh(Ct)
)DOC")
    .Attr("activations", "A list of 4 activation functions for input, output, "
	  "forget, and cell gates. The activation functions must be one of sigmoid "
	  "and tanh. See the equations for default if not specified.",
          AttrType::STRINGS)
    .Attr("hidden_size", "Number of neurons in the hidden layer", AttrType::INT)
    .Attr("direction", "Specify if RNN is forward, reverse, or bidirectional. "
          "Must be one of forward (default), reverse, or bidirectional.",
          AttrType::STRING)
    .Attr("input_forget", "Couple the input and forget gates if 1, default 0.",
          AttrType::INT)
    .Attr("clip", "Cell clip threshold. Clipping bounds the elements of a tensor "
          "in the range of [-threshold, +threshold] and is applied to the input "
          "of activations. No clip if not specified.",
          AttrType::FLOAT)
    .Input(0, "input",
           "The input sequences packed (and potentially padded) into one 3-D "
           "tensor with the shape of `[seq_length, batch_size, input_size]`.")
    .Input(1, "W",
	   "The weight tensor for the gates. Concatenation of `W[iofc]` and "
           "`WB[iofc]` (if bidirectional) along dimension 0. The tensor has shape "
	   "`[num_directions, 4*hidden_size, input_size]`.", "T")
    .Input(2, "R",
	   "The recurrence weight tensor. Concatenation of `R[iofc]` and "
	   "`RB[iofc]` (if bidirectional) along dimension 0. This tensor has shape "
           "`[num_directions, 4*hidden_size, hidden_size}`.", "T")
    .Input(3, "B",
	   "The bias tensor for input gate. Concatenation of `[Wb[iofc], Rb[iofc]]`, "
	   "and `[WBb[iofc], RBb[iofc]]` (if bidirectional) along dimension 0. This "
           "tensor has shape `[num_directions, 8*hidden_size]`. Optional: If not "
	   "specified - assumed to be 0.", "T",
	   true /*optional*/)
    .Input(4, "P",
	   "The weight tensor for peepholes. Concatenation of `P[iof]` and "
	   "`PB[iof]` (if bidirectional) along dimension 0. It has shape "
	   "`[num_directions, 3*hidde_size, hidden_size]`. Optional: If not specified - "
	   "assumed to be 0.", "T",
	   true /*optional*/)
    .Input(5, "initial_h",
           "Optional initial value of the hidden. If not specified - assumed "
           "to be 0. It has shape `[num_directions, batch_size, hidden_size]`.",
	   "T", true /*optional*/)
    .Input(6, "initial_c",
           "Optional initial value of the cell. If not specified - assumed "
	   "to be 0. It has shape `[num_directions, batch_size, hidden_size]`.",
	   "T", true /*optional*/)
    .Input(7, "seq_lens",
           "Optional tensor specifying lengths of the sequences in a batch. "
           "If not specified - assumed all sequences in the batch to have "
	   "length `seq_length`. It has shape `[batch_size]`.", "T1",
	   true /*optional*/)
    .Output(0, "output",
	    "A tensor that concats all the intermediate output values of the hidden."
	    "It has shape `[seq_length, num_directions, batch_size, hidden_size]`.",
            "T")
    .Output(1, "output_h",
            "The last output value of the hidden. It has shape "
	    "`[num_directions, batch_size, hidden_size]`.", "T")
    .TypeConstraint("T", { "tensor(float16)", "tensor(float)", "tensor(double)" },
                    "Constrain input and output types to float tensors.")
    .TypeConstraint("T1", { "tensor(int32)" }, "Constrain seq_lens to integer tensor.");
<commit_msg>Updates<commit_after>// Copyright (c) Facebook Inc. and Microsoft Corporation.
// Licensed under the MIT license.

#include "onnx/defs/schema.h"

using AttrType = onnx::OpSchema::AttrType;
using namespace onnx;

OPERATOR_SCHEMA(SimpleRNN)
    .NumInputs(3, 6)
    .NumOutputs(1, 2)
    .SetDoc(R"DOC(
Computes an one-layer simple RNN. This operator is usually supported
via some custom implementation such as CuDNN.

Notations:
`X` - input tensor
`i` - input gate
`t` - time step (t-1 means previous time step)
`Wi` - W parameter weight matrix for input gate
`Ri` - R recurrence weight matrix for input gate
`Wbi` - W parameter bias vector for input gate
`Rbi` - R parameter bias vector for input gate
`WBi` - W parameter weight matrix for backward input gate
`RBi` - R recurrence weight matrix for backward input gate
`WBbi` - WR bias vectors for backward input gate
`RBbi` - RR bias vectors for backward input gate
`ReLU(X)` - max(X, 0)
`tanh(X)` - hyperbolic tangent of X
`H` - Hidden state
`num_directions` - 2 if direction == bidirectional else 1

Equations:
  - Ht = Activation(Wi*Xt + Ri*Ht-1 + Wbi + Rbi)
)DOC")
    .Attr("activation", "The activation function for input gate. It must be "
	  "one of tanh and ReLU. Default `tanh`.",
          AttrType::STRING)
    .Attr("hidden_size", "Number of neurons in the hidden layer", AttrType::INT)
    .Attr("direction", "Specify if the RNN is forward, reverse, or bidirectional. "
          "Must be one of forward (default), reverse, or bidirectional.",
          AttrType::STRING)
    .Attr("clip", "Cell clip threshold. Clipping bounds the elements of a tensor "
          "in the range of [-threshold, +threshold] and is applied to the input "
          "of activations. No clip if not specified.",
          AttrType::FLOAT)
    .Input(0, "input",
           "The input sequences packed (and potentially padded) into one 3-D "
           "tensor with the shape of `[seq_length, batch_size, input_size]`.", "T")
    .Input(1, "W",
	   "The weight tensor for input gate. Concatenation of `Wi` and `WBi` "
           "(if bidirectional). The tensor has shape "
           "`num_directions, hidden_size, input_size]`.", "T")
    .Input(2, "R",
	   "The recurrence weight tensor. Concatenation of `Ri` and `RBi` "
           "(if bidirectional). The tensor has shape "
	   "`[num_directions, hidden_size, hidden_size}`.", "T")
    .Input(3, "B",
	   "The bias tensor for input gate. Concatenation of `[Wbi, Rbi]`, "
           "and `[WBbi, RBbi]` (if bidirectional). The tensor has shape "
           "`[num_directions, 2*hidden_size]`, Optional: If not specified - assumed "
           "to be 0.", "T",
	   true /*optional*/)
    .Input(4, "initial_h",
	   "Optional initial value of the hidden. If not specified - assumed "
	   "to be 0. It has shape either `[num_directions, batch_size, hidden_size]`.",
	   "T", true /*optional*/)
    .Input(5, "seq_lens",
           "Optional tensor specifying lengths of the sequences in a batch. "
           "If not specified - assumed all sequences in the batch to have "
	   "length `seq_length`. It has shape `[batch_size]`.", "T1",
	   true /*optional*/)
    .Output(0, "output",
	    "A tensor that concats all the intermediate output values of the hidden."
	    "It has shape `[seq_length, num_directions, batch_size, hidden_size]`.", "T")
    .Output(1, "output_h",
            "The last output value of the hidden. It has shape "
	    "`[num_directions, batch_size, hidden_size]`.", "T")
    .TypeConstraint("T", { "tensor(float16)", "tensor(float)", "tensor(double)" },
                    "Constrain input and output types to float tensors.")
    .TypeConstraint("T1", { "tensor(int32)" }, "Constrain seq_lens to integer tensor.");

OPERATOR_SCHEMA(GRU)
    .NumInputs(3, 6)
    .NumOutputs(1, 2)
    .SetDoc(R"DOC(
Computes an one-layer GRU. This operator is usually supported via some custom
implementation such as CuDNN.

Notations:
`X` - input tensor
`z` - update gate
`r` - reset gate
`h` - hidden gate
`t` - time step (t-1 means previous time step)
`W[zrh]` - W parameter weight matrix for update, reset, and hidden gates
`R[zrh]` - R recurrence weight matrix for update, reset, and hidden gates
`Wb[zrh]` - W bias vectors for update, reset, and hidden gates
`Rb[zrh]` - R bias vectors for update, reset, and hidden gates
`WB[zrh]` - W parameter weight matrix for backward update, reset, and hidden gates
`RB[zrh]` - R recurrence weight matrix for backward update, reset, and hidden gates
`WBb[zrh]` - W bias vectors for backward update, reset, and hidden gates
`RBb[zrh]` - R bias vectors for backward update, reset, and hidden gates
`tanh(X)` - hyperbolic tangent of X
`sigmoid(X)` - 1 / (1 + e^-X)
`H` - Hidden state
`num_directions` - 2 if direction == bidirectional else 1

Equations (GRU with default activations):
  - zt = sigmoid(Wz*Xt + Rz*Ht-1 + Wbz + Rbz)
  - rt = sigmoid(Wr*Xt + Rr*Ht-1 + Wbr + Rbr)
  - ht = tanh(Wh*Xt + rt*(Rh*Ht-1 + Rbh) + Wbh)
  - H = (1 - zt) (.) ht + it (.) Ht-1
)DOC")
    .Attr("activations", "A list of 3 activation functions for update, reset, and "
	  "hidden gates. The activation functions must be one of sigmoid and tanh. "
          "See the equations for default if not specified.",
          AttrType::STRINGS)
    .Attr("hidden_size", "Number of neurons in the hidden layer", AttrType::INT)
    .Attr("direction", "Specify if the RNN is forward, reverse, or bidirectional. "
          "Must be one of forward (default), reverse, or bidirectional.",
          AttrType::STRING)
    .Attr("clip", "Cell clip threshold. Clipping bounds the elements of a tensor "
          "in the range of [-threshold, +threshold] and is applied to the input "
          "of activations. No clip if not specified.",
          AttrType::FLOAT)
    .Input(0, "input",
           "The input sequences packed (and potentially padded) into one 3-D "
           "tensor with the shape of `[seq_length, batch_size, input_size]`.", "T")
    .Input(1, "W",
	   "The weight tensor for the gates. Concatenation of `W[zrh]` and `WB[zrh]` "
	   "(if bidirectional) along dimension 0. This tensor has shape "
	   "`[num_directions, 3*hidden_size, input_size]`.", "T")
    .Input(2, "R",
	   "The recurrence weight tensor. Concatenation of `R[zrh]` and `RB[zrh]` "
	   "(if bidirectional) along dimension 0. This tensor has shape "
	   "`[num_directions, 3*hidden_size, hidden_size}`.", "T")
    .Input(3, "B",
	   "The bias tensor for the gates. Concatenation of `[Wb[zrh], Rb[zrh]]` and "
           "`[WBb[zrh], RBb[zrh]]` (if bidirectional) along dimension 0. This tensor "
           "has shape `[num_directions, 6*hidden_size]`. Optional: If not specified "
           "- assumed to be 0", "T",
	   true /*optional*/)
    .Input(4, "initial_h",
	   "Optional initial value of the hidden. If not specified - assumed "
	   "to be 0. It has shape `[num_directions, batch_size, hidden_size]`.",
	   "T", true /*optional*/)
    .Input(5, "seq_lens",
           "Optional tensor specifying lengths of the sequences in a batch. "
           "If not specified - assumed all sequences in the batch to have "
	   "length `seq_length`. It has shape `[batch_size]`.",
	   "T1", true /*optional*/)
    .Output(0, "output",
	    "A tensor that concats all the intermediate output values of the "
	    "hidden. It has shape `[seq_length, num_directions, batch_size, hidden_size]`.",
            "T")
    .Output(1, "output_h",
            "The last output value of the hidden. It has shape "
	    "`[num_directions, batch_size, hidden_size]`.", "T")
    .TypeConstraint("T", { "tensor(float16)", "tensor(float)", "tensor(double)" },
                    "Constrain input and output types to float tensors.")
    .TypeConstraint("T1", { "tensor(int32)" }, "Constrain seq_lens to integer tensor.");

OPERATOR_SCHEMA(LSTM)
    .NumInputs(3, 8)
    .NumOutputs(1, 2)
    .SetDoc(R"DOC(
Computes an one-layer LSTM. This operator is usually supported via some
custom implementation such as CuDNN.

Notations:
`X` - input tensor
`i` - input gate
`o` - output gate
`f` - forget gate
`c` - cell gate
`t` - time step (t-1 means previous time step)
`W[iofc]` - W parameter weight matrix for input, output, forget, and cell gates
`R[iofc]` - R recurrence weight matrix for input, output, forget, and cell gates
`Wb[iofc]` - W bias vectors for input, output, forget, and cell gates
`Rb[iofc]` - R bias vectors for input, output, forget, and cell gates
`P[iof]`  - P peephole weight matrix for input, output, and forget gates
`WB[iofc]` - W parameter weight matrix for backward input, output, forget, and cell gates
`RB[iofc]` - R recurrence weight matrix for backward input, output, forget, and cell gates
`WBb[iofc]` - W bias vectors for backward input, output, forget, and cell gates
`RBb[iofc]` - R bias vectors for backward input, output, forget, and cell gates
`PB[iof]`  - P peephole weight matrix for backward input, output, and forget gates
`tanh(X)` - hyperbolic tangent of X
`sigmoid(X)` - 1 / (1 + e^-X)
`H` - Hidden state
`num_directions` - 2 if direction == bidirectional else 1

Equations (forward LSTM with default activations and peepholes):
  - it = sigmoid(Wi*Xt + Ri*Ht-1 + Pi (.) Ct-1 + Wbi + Rbi)
  - ft = sigmoid(Wf*Xt + Rf*Ht-1 + Pf (.) Ct-1 + Wbf + Rbf)
  - ct = tanh(Wc*Xt + Rc*Ht-1 + Wbc + Rbc)
  - Ct = ft (.) Ct-1 + it (.) ct
  - ot = sigmoid(Wo*Xt + Ro*Ht-1 + Po (.) Ct + Wbo + Rbo)
  - H = ot (.) tanh(Ct)
)DOC")
    .Attr("activations", "A list of 4 activation functions for input, output, "
	  "forget, and cell gates. The activation functions must be one of sigmoid "
	  "and tanh. See the equations for default if not specified.",
          AttrType::STRINGS)
    .Attr("hidden_size", "Number of neurons in the hidden layer", AttrType::INT)
    .Attr("direction", "Specify if RNN is forward, reverse, or bidirectional. "
          "Must be one of forward (default), reverse, or bidirectional.",
          AttrType::STRING)
    .Attr("input_forget", "Couple the input and forget gates if 1, default 0.",
          AttrType::INT)
    .Attr("clip", "Cell clip threshold. Clipping bounds the elements of a tensor "
          "in the range of [-threshold, +threshold] and is applied to the input "
          "of activations. No clip if not specified.",
          AttrType::FLOAT)
    .Input(0, "input",
           "The input sequences packed (and potentially padded) into one 3-D "
           "tensor with the shape of `[seq_length, batch_size, input_size]`.", "T")
    .Input(1, "W",
	   "The weight tensor for the gates. Concatenation of `W[iofc]` and "
           "`WB[iofc]` (if bidirectional) along dimension 0. The tensor has shape "
	   "`[num_directions, 4*hidden_size, input_size]`.", "T")
    .Input(2, "R",
	   "The recurrence weight tensor. Concatenation of `R[iofc]` and "
	   "`RB[iofc]` (if bidirectional) along dimension 0. This tensor has shape "
           "`[num_directions, 4*hidden_size, hidden_size}`.", "T")
    .Input(3, "B",
	   "The bias tensor for input gate. Concatenation of `[Wb[iofc], Rb[iofc]]`, "
	   "and `[WBb[iofc], RBb[iofc]]` (if bidirectional) along dimension 0. This "
           "tensor has shape `[num_directions, 8*hidden_size]`. Optional: If not "
	   "specified - assumed to be 0.", "T",
	   true /*optional*/)
    .Input(4, "P",
	   "The weight tensor for peepholes. Concatenation of `P[iof]` and "
	   "`PB[iof]` (if bidirectional) along dimension 0. It has shape "
	   "`[num_directions, 3*hidde_size, hidden_size]`. Optional: If not specified - "
	   "assumed to be 0.", "T",
	   true /*optional*/)
    .Input(5, "initial_h",
           "Optional initial value of the hidden. If not specified - assumed "
           "to be 0. It has shape `[num_directions, batch_size, hidden_size]`.",
	   "T", true /*optional*/)
    .Input(6, "initial_c",
           "Optional initial value of the cell. If not specified - assumed "
	   "to be 0. It has shape `[num_directions, batch_size, hidden_size]`.",
	   "T", true /*optional*/)
    .Input(7, "seq_lens",
           "Optional tensor specifying lengths of the sequences in a batch. "
           "If not specified - assumed all sequences in the batch to have "
	   "length `seq_length`. It has shape `[batch_size]`.", "T1",
	   true /*optional*/)
    .Output(0, "output",
	    "A tensor that concats all the intermediate output values of the hidden."
	    "It has shape `[seq_length, num_directions, batch_size, hidden_size]`.",
            "T")
    .Output(1, "output_h",
            "The last output value of the hidden. It has shape "
	    "`[num_directions, batch_size, hidden_size]`.", "T")
    .TypeConstraint("T", { "tensor(float16)", "tensor(float)", "tensor(double)" },
                    "Constrain input and output types to float tensors.")
    .TypeConstraint("T1", { "tensor(int32)" }, "Constrain seq_lens to integer tensor.");
<|endoftext|>


<commit_before>//------------------------------------------------------------------------------
//
// Name:       add.cpp
//
// Purpose:    Atomic summation, inspired by:
//             http://simpleopencl.blogspot.com/2013/04/performance-of-atomics-atomics-in.html
//
// HISTORY:    Written by Tim Mattson, June 2011
//             Ported to C++ Wrapper API by Benedict Gaster, September 2011
//             Updated to C++ Wrapper API v1.2 by Tom Deakin and Simon McIntosh-Smith, October 2012
//             Updated to C++ Wrapper v1.2.6 by Tom Deakin, August 2013
//             Rewritten to a different purpose altogther by Jeff Hammond, October 2016
//
//------------------------------------------------------------------------------

#define __CL_ENABLE_EXCEPTIONS

#include <iostream>
#include <fstream>

#include "cl.hpp"
#include "util.hpp"

// pick up device type from compiler command line or from the default type
#ifndef DEVICE
#define DEVICE CL_DEVICE_TYPE_DEFAULT
#endif

int main(int argc, char* argv[])
{
    try {
        cl::Context context(DEVICE);
        cl::Program program(context, util::loadProgram("add.cl"), /* build= */ true);
        cl::CommandQueue queue(context);

        // create host and device data
        int sum=0;
        auto bufferSum = cl::Buffer(context, CL_MEM_READ_WRITE, 1 * sizeof(int));
        // copy host-to-device
        queue.enqueueWriteBuffer(bufferSum, CL_TRUE, 0, 1 * sizeof(int), &sum);

        auto kernel=cl::Kernel(program, "AtomicSum");
        // bind device buffer to first argument in kernel invocation
        kernel.setArg(0,bufferSum);
        // run the kernel
        queue.enqueueNDRangeKernel(kernel, cl::NullRange, cl::NDRange(1024*1024*128), cl::NullRange);
        queue.finish();

        // copy device-to-host
        queue.enqueueReadBuffer(bufferSum,CL_TRUE,0,1 * sizeof(int),&sum);

        std::cout << "Sum: " << sum << std::endl;
    }
    catch (cl::Error err) {
        std::cout << "Exception\n";
        std::cerr << "ERROR: " << err.what() << std::endl;
    }
    return 0;
}
<commit_msg>add verification<commit_after>//------------------------------------------------------------------------------
//
// Name:       add.cpp
//
// Purpose:    Atomic summation, inspired by:
//             http://simpleopencl.blogspot.com/2013/04/performance-of-atomics-atomics-in.html
//
// HISTORY:    Written by Tim Mattson, June 2011
//             Ported to C++ Wrapper API by Benedict Gaster, September 2011
//             Updated to C++ Wrapper API v1.2 by Tom Deakin and Simon McIntosh-Smith, October 2012
//             Updated to C++ Wrapper v1.2.6 by Tom Deakin, August 2013
//             Rewritten to a different purpose altogther by Jeff Hammond, October 2016
//
//------------------------------------------------------------------------------

#define __CL_ENABLE_EXCEPTIONS

#include <iostream>
#include <fstream>

#include "cl.hpp"
#include "util.hpp"

// pick up device type from compiler command line or from the default type
#ifndef DEVICE
#define DEVICE CL_DEVICE_TYPE_DEFAULT
#endif

const auto range = 1024*1024*128;

int main(int argc, char* argv[])
{
    try {
        cl::Context context(DEVICE);
        cl::Program program(context, util::loadProgram("add.cl"), /* build= */ true);
        cl::CommandQueue queue(context);

        // create host and device data
        int sum=0;
        auto bufferSum = cl::Buffer(context, CL_MEM_READ_WRITE, 1 * sizeof(int));
        // copy host-to-device
        queue.enqueueWriteBuffer(bufferSum, CL_TRUE, 0, 1 * sizeof(int), &sum);

        auto kernel=cl::Kernel(program, "AtomicSum");
        // bind device buffer to first argument in kernel invocation
        kernel.setArg(0,bufferSum);
        // run the kernel
        queue.enqueueNDRangeKernel(kernel, cl::NullRange, cl::NDRange(range), cl::NullRange);
        queue.finish();

        // copy device-to-host
        queue.enqueueReadBuffer(bufferSum,CL_TRUE,0,1 * sizeof(int),&sum);

        std::cout << "Sum: " << sum << " (should be " << range << ")" << std::endl;
    }
    catch (cl::Error err) {
        std::cout << "Exception\n";
        std::cerr << "ERROR: " << err.what() << std::endl;
    }
    return 0;
}
<|endoftext|>