<commit_before>// Virvo - Virtual Reality Volume Rendering
// Copyright (C) 1999-2003 University of Stuttgart, 2004-2005 Brown University
// Contact: Jurgen P. Schulze, jschulze@ucsd.edu
//
// This file is part of Virvo.
//
// Virvo 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 (see license.txt); if not, write to the
// Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

#ifdef HAVE_CONFIG_H
#include "vvconfig.h"
#endif

#include "vvcgprogram.h"
#include "vvgltools.h"
#include "vvopengl.h"
#include "vvdebugmsg.h"

#include <iostream>

using std::cerr;
using std::endl;
using std::string;

#ifdef HAVE_CG

vvCgProgram::vvCgProgram(const string& vert, const string& geom, const string& frag)
: vvShaderProgram(vert, geom, frag)
{
  for(int i=0; i<3;i++)
  {
    _shaderId[i] = 0;
    _profile[i] = CGprofile(0);
  }

  _shadersLoaded = loadShaders();
  if(_shadersLoaded)
  {
     vvDebugMsg::msg(0, "vvCgProgram::vvCgProgram() Loading Shaders failed!");
  }
}

vvCgProgram::vvCgProgram(const string& vert, const string& geom, const string& frag)
                         const vvShaderProgram& geoShaderArgs)
: vvShaderProgram(vert, geom, frag, geoShaderArgs)
{
  for(int i=0; i<3;i++)
  {
    _shaderId[i] = 0;
    _profile[i] = CGprofile(0);
  }

  _shadersLoaded = loadShaders();
  if(_shadersLoaded)
  {
     vvDebugMsg::msg(0, "vvCgProgram::vvCgProgram() Loading Shaders failed!");
  }
}

vvCgProgram::~vvCgProgram()
{
  disable();
  if (_program)
  {
    cgDestroyContext(_program);
  }
}

bool vvCgProgram::loadShaders()
{
  cgSetErrorHandler(cgErrorHandler, NULL);
  _program = cgCreateContext();

  if (_program == NULL)
  {
    vvDebugMsg::msg(0, "Can't create Cg context");
  }

  for(int i=0;i<3;i++)
  {
    if(_fileStrings[i].length() == 0)
      continue;

    _profile[i] = cgGLGetLatestProfile(toCgEnum(i));
    cgGLSetOptimalOptions(_profile[i]);
    _shaderId[i] = cgCreateProgram( _program, CG_SOURCE, _fileStrings[i].c_str(), _profile[i], NULL, NULL);

    if (_shaderId[i] == NULL)
    {
      vvDebugMsg::msg(0, "Couldn't load cg-shader!");
      return false;
    }
  }
  return true;
}

void vvCgProgram::enable()
{
  for(int i=0;i<3;i++)
  {
    if(_shaderId[i] == 0)
      continue;

    cgGLLoadProgram(_shaderId[i]);
    cgGLEnableProfile(_profile[i]);
    cgGLBindProgram(_shaderId[i]);
  }
}

void vvCgProgram::disable()
{
  for(int i=0;i<3;i++)
  {
    if(_profile[i] == 0)
      continue;

    cgGLDisableProfile(_profile[i]);
  }
}

void vvCgProgram::cgErrorHandler(CGcontext context, CGerror error, void*)
{
  if(error != CG_NO_ERROR)
    cerr << cgGetErrorString(error) << " (" << static_cast<int>(error) << ")" << endl;
  for(GLint glerr = glGetError(); glerr != GL_NO_ERROR; glerr = glGetError())
  {
    cerr << "GL error: " << gluErrorString(glerr) << endl;
  }
  if(context && error==CG_COMPILER_ERROR)
  {
     if(const char *listing = cgGetLastListing(context))
     {
        cerr << "last listing:" << endl;
        cerr << listing << endl;
     }
  }
}

CGGLenum vvCgProgram::toCgEnum(const int i) const
{
  CGGLenum result;
  switch(i)
  {
  case 0:
    result = CG_GL_VERTEX;
    break;
#if CG_VERSION_NUM >= 2000
  case 1:
    result = CG_GL_GEOMETRY;
    break;
#endif
  case 2:
    result = CG_GL_FRAGMENT;
    break;
  default:
    vvDebugMsg::msg(0, "toCgEnum() unknown ShaderType!");
    result = CG_GL_FRAGMENT;
    break;
  }
  return result;
}

vvCgProgram::ParameterIterator vvCgProgram::initParameter(const string& parameterName)
{
  // check if already initialized
  ParameterIterator paraIterator = _cgParameterNameMaps.find(parameterName);
  if(paraIterator != _cgParameterNameMaps.end())
    return paraIterator;

  CGparameter paraFirst = 0;
  for(int i=0;i<3;i++)
  {
    if(_shaderId[i]==0)
      continue;

    CGparameter param = cgGetNamedParameter(_shaderId[i], parameterName.c_str());

    if(param != NULL && paraFirst == 0)
    {
      paraFirst = param;
    }
    else if(param != NULL && paraFirst != 0)
    {
      cgConnectParameter(paraFirst, param);
    }
  }

  _cgParameterNameMaps[parameterName] = paraFirst;

  if(paraFirst == 0)
  {
    string errmsg = "cgParameter (" + parameterName + ")not found!";
    vvDebugMsg::msg(2, errmsg.c_str());
    return _cgParameterNameMaps.end();
  }

  return _cgParameterNameMaps.find(parameterName);
}

void vvCgProgram::setParameter1f(const string& parameterName, const float& f1)
{
  ParameterIterator it = initParameter(parameterName);
  if(it->second != 0)
    cgSetParameter1f(it->second, f1);
}

void vvCgProgram::setParameter1i(const string& parameterName, const int& i1)
{
  ParameterIterator it = initParameter(parameterName);
  if(it->second != 0)
    cgSetParameter1i(it->second, i1);
}

void vvCgProgram::setParameter3f(const string& parameterName, const float* array)
{
  ParameterIterator it = initParameter(parameterName);
  if(it->second != 0)
    cgSetParameter3fv(it->second, array);
}

void vvCgProgram::setParameter3f(const string& parameterName,
                          const float& f1, const float& f2, const float& f3)
{
  ParameterIterator it = initParameter(parameterName);
  if(it->second != 0)
    cgSetParameter3f(it->second, f1, f2, f3);
}

void vvCgProgram::setParameter4f(const string& parameterName, const float* array)
{
  ParameterIterator it = initParameter(parameterName);
  if(it->second != 0)
    cgSetParameter4fv(it->second, array);
}

void vvCgProgram::setParameter4f(const string& parameterName,
                          const float& f1, const float& f2, const float& f3, const float& f4)
{
  ParameterIterator it = initParameter(parameterName);
  if(it->second != 0)
    cgSetParameter4f(it->second, f1, f2, f3, f4);
}

void vvCgProgram::setParameterArray1i(const string& parameterName, const int* array, const int& count)
{
  ParameterIterator it = initParameter(parameterName);
  if(it->second != 0)
  {
    // transform integers to floats because CG doesn't support uniform integers
    float floats[count];
    for(int i=0;i<count;i++)
      floats[i] = float(array[i]);
    cgGLSetParameterArray1f(it->second, 0, count, floats);
  }
}

void vvCgProgram::setParameterArray3f(const string& parameterName, const float* array, const int& count)
{
  ParameterIterator it = initParameter(parameterName);
  if(it->second != 0)
    cgGLSetParameterArray3f(it->second, 0, 3*count, array);
}

void vvCgProgram::setParameterMatrix4f(const string& parameterName, const float* mat)
{
  ParameterIterator it = initParameter(parameterName);
  if(it->second != 0)
    cgSetMatrixParameterfr(it->second, mat);
}

void vvCgProgram::setParameterMatrix4f(const string& parameterName, const vvMatrix &mat)
{
  float m[16];
  mat.getGL(m);
  setParameterMatrix4f(parameterName, m);
}

void vvCgProgram::setParameterTex1D(const string& parameterName, const unsigned int& ui)
{
  ParameterIterator it = initParameter(parameterName);
  if(it->second != 0)
  {
    cgGLSetTextureParameter(it->second, ui);
    cgGLEnableTextureParameter(it->second);
  }
}

void vvCgProgram::setParameterTex2D(const string& parameterName, const unsigned int& ui)
{
  setParameterTex1D(parameterName, ui);
}

void vvCgProgram::setParameterTex3D(const string& parameterName, const unsigned int& ui)
{
  setParameterTex1D(parameterName, ui);
}

#endif // ifdef HAVE_CG

//============================================================================
// End of File
//============================================================================
// vim: sw=2:expandtab:softtabstop=2:ts=2:cino=\:0g0t0
<commit_msg>Compile fix for Cg<commit_after>// Virvo - Virtual Reality Volume Rendering
// Copyright (C) 1999-2003 University of Stuttgart, 2004-2005 Brown University
// Contact: Jurgen P. Schulze, jschulze@ucsd.edu
//
// This file is part of Virvo.
//
// Virvo 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 (see license.txt); if not, write to the
// Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

#ifdef HAVE_CONFIG_H
#include "vvconfig.h"
#endif

#include "vvcgprogram.h"
#include "vvgltools.h"
#include "vvopengl.h"
#include "vvdebugmsg.h"

#include <iostream>

using std::cerr;
using std::endl;
using std::string;

#ifdef HAVE_CG

vvCgProgram::vvCgProgram(const string& vert, const string& geom, const string& frag)
: vvShaderProgram(vert, geom, frag)
{
  for(int i=0; i<3;i++)
  {
    _shaderId[i] = 0;
    _profile[i] = CGprofile(0);
  }

  _shadersLoaded = loadShaders();
  if(_shadersLoaded)
  {
     vvDebugMsg::msg(0, "vvCgProgram::vvCgProgram() Loading Shaders failed!");
  }
}

vvCgProgram::vvCgProgram(const string& vert, const string& geom, const string& frag,
                         const vvShaderProgram::GeoShaderArgs& geoShaderArgs)
: vvShaderProgram(vert, geom, frag, geoShaderArgs)
{
  for(int i=0; i<3;i++)
  {
    _shaderId[i] = 0;
    _profile[i] = CGprofile(0);
  }

  _shadersLoaded = loadShaders();
  if(_shadersLoaded)
  {
     vvDebugMsg::msg(0, "vvCgProgram::vvCgProgram() Loading Shaders failed!");
  }
}

vvCgProgram::~vvCgProgram()
{
  disable();
  if (_program)
  {
    cgDestroyContext(_program);
  }
}

bool vvCgProgram::loadShaders()
{
  cgSetErrorHandler(cgErrorHandler, NULL);
  _program = cgCreateContext();

  if (_program == NULL)
  {
    vvDebugMsg::msg(0, "Can't create Cg context");
  }

  for(int i=0;i<3;i++)
  {
    if(_fileStrings[i].length() == 0)
      continue;

    _profile[i] = cgGLGetLatestProfile(toCgEnum(i));
    cgGLSetOptimalOptions(_profile[i]);
    _shaderId[i] = cgCreateProgram( _program, CG_SOURCE, _fileStrings[i].c_str(), _profile[i], NULL, NULL);

    if (_shaderId[i] == NULL)
    {
      vvDebugMsg::msg(0, "Couldn't load cg-shader!");
      return false;
    }
  }
  return true;
}

void vvCgProgram::enable()
{
  for(int i=0;i<3;i++)
  {
    if(_shaderId[i] == 0)
      continue;

    cgGLLoadProgram(_shaderId[i]);
    cgGLEnableProfile(_profile[i]);
    cgGLBindProgram(_shaderId[i]);
  }
}

void vvCgProgram::disable()
{
  for(int i=0;i<3;i++)
  {
    if(_profile[i] == 0)
      continue;

    cgGLDisableProfile(_profile[i]);
  }
}

void vvCgProgram::cgErrorHandler(CGcontext context, CGerror error, void*)
{
  if(error != CG_NO_ERROR)
    cerr << cgGetErrorString(error) << " (" << static_cast<int>(error) << ")" << endl;
  for(GLint glerr = glGetError(); glerr != GL_NO_ERROR; glerr = glGetError())
  {
    cerr << "GL error: " << gluErrorString(glerr) << endl;
  }
  if(context && error==CG_COMPILER_ERROR)
  {
     if(const char *listing = cgGetLastListing(context))
     {
        cerr << "last listing:" << endl;
        cerr << listing << endl;
     }
  }
}

CGGLenum vvCgProgram::toCgEnum(const int i) const
{
  CGGLenum result;
  switch(i)
  {
  case 0:
    result = CG_GL_VERTEX;
    break;
#if CG_VERSION_NUM >= 2000
  case 1:
    result = CG_GL_GEOMETRY;
    break;
#endif
  case 2:
    result = CG_GL_FRAGMENT;
    break;
  default:
    vvDebugMsg::msg(0, "toCgEnum() unknown ShaderType!");
    result = CG_GL_FRAGMENT;
    break;
  }
  return result;
}

vvCgProgram::ParameterIterator vvCgProgram::initParameter(const string& parameterName)
{
  // check if already initialized
  ParameterIterator paraIterator = _cgParameterNameMaps.find(parameterName);
  if(paraIterator != _cgParameterNameMaps.end())
    return paraIterator;

  CGparameter paraFirst = 0;
  for(int i=0;i<3;i++)
  {
    if(_shaderId[i]==0)
      continue;

    CGparameter param = cgGetNamedParameter(_shaderId[i], parameterName.c_str());

    if(param != NULL && paraFirst == 0)
    {
      paraFirst = param;
    }
    else if(param != NULL && paraFirst != 0)
    {
      cgConnectParameter(paraFirst, param);
    }
  }

  _cgParameterNameMaps[parameterName] = paraFirst;

  if(paraFirst == 0)
  {
    string errmsg = "cgParameter (" + parameterName + ")not found!";
    vvDebugMsg::msg(2, errmsg.c_str());
    return _cgParameterNameMaps.end();
  }

  return _cgParameterNameMaps.find(parameterName);
}

void vvCgProgram::setParameter1f(const string& parameterName, const float& f1)
{
  ParameterIterator it = initParameter(parameterName);
  if(it->second != 0)
    cgSetParameter1f(it->second, f1);
}

void vvCgProgram::setParameter1i(const string& parameterName, const int& i1)
{
  ParameterIterator it = initParameter(parameterName);
  if(it->second != 0)
    cgSetParameter1i(it->second, i1);
}

void vvCgProgram::setParameter3f(const string& parameterName, const float* array)
{
  ParameterIterator it = initParameter(parameterName);
  if(it->second != 0)
    cgSetParameter3fv(it->second, array);
}

void vvCgProgram::setParameter3f(const string& parameterName,
                          const float& f1, const float& f2, const float& f3)
{
  ParameterIterator it = initParameter(parameterName);
  if(it->second != 0)
    cgSetParameter3f(it->second, f1, f2, f3);
}

void vvCgProgram::setParameter4f(const string& parameterName, const float* array)
{
  ParameterIterator it = initParameter(parameterName);
  if(it->second != 0)
    cgSetParameter4fv(it->second, array);
}

void vvCgProgram::setParameter4f(const string& parameterName,
                          const float& f1, const float& f2, const float& f3, const float& f4)
{
  ParameterIterator it = initParameter(parameterName);
  if(it->second != 0)
    cgSetParameter4f(it->second, f1, f2, f3, f4);
}

void vvCgProgram::setParameterArray1i(const string& parameterName, const int* array, const int& count)
{
  ParameterIterator it = initParameter(parameterName);
  if(it->second != 0)
  {
    // transform integers to floats because CG doesn't support uniform integers
    float floats[count];
    for(int i=0;i<count;i++)
      floats[i] = float(array[i]);
    cgGLSetParameterArray1f(it->second, 0, count, floats);
  }
}

void vvCgProgram::setParameterArray3f(const string& parameterName, const float* array, const int& count)
{
  ParameterIterator it = initParameter(parameterName);
  if(it->second != 0)
    cgGLSetParameterArray3f(it->second, 0, 3*count, array);
}

void vvCgProgram::setParameterMatrix4f(const string& parameterName, const float* mat)
{
  ParameterIterator it = initParameter(parameterName);
  if(it->second != 0)
    cgSetMatrixParameterfr(it->second, mat);
}

void vvCgProgram::setParameterMatrix4f(const string& parameterName, const vvMatrix &mat)
{
  float m[16];
  mat.getGL(m);
  setParameterMatrix4f(parameterName, m);
}

void vvCgProgram::setParameterTex1D(const string& parameterName, const unsigned int& ui)
{
  ParameterIterator it = initParameter(parameterName);
  if(it->second != 0)
  {
    cgGLSetTextureParameter(it->second, ui);
    cgGLEnableTextureParameter(it->second);
  }
}

void vvCgProgram::setParameterTex2D(const string& parameterName, const unsigned int& ui)
{
  setParameterTex1D(parameterName, ui);
}

void vvCgProgram::setParameterTex3D(const string& parameterName, const unsigned int& ui)
{
  setParameterTex1D(parameterName, ui);
}

#endif // ifdef HAVE_CG

//============================================================================
// End of File
//============================================================================
// vim: sw=2:expandtab:softtabstop=2:ts=2:cino=\:0g0t0
<|endoftext|>


<commit_before>// Copyright 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "array.h"
#include "benchmark.h"

#include <random>
#include <iostream>

using namespace nda;

// The standard matrix notation is to refer to elements by 'row,
// column'. To make this efficient for typical programs, we're going
// to make the second dimension the dense dim. This shape has the
// option of making the size of the matrix compile-time constant via
// the template parameters.
template <index_t Rows = UNK, index_t Cols = UNK>
using matrix_shape = shape<dim<UNK, Rows>, dense_dim<UNK, Cols>>;

// A matrix or matrix_ref is an array or array_ref with Shape =
// matrix_shape.
template <typename T, index_t Rows = UNK, index_t Cols = UNK,
          typename Alloc = std::allocator<T>>
using matrix = array<T, matrix_shape<Rows, Cols>, Alloc>;
template <typename T, index_t Rows = UNK, index_t Cols = UNK>
using matrix_ref = array_ref<T, matrix_shape<Rows, Cols>>;

// A textbook implementation of matrix multiplication. This is very simple,
// but it is slow, primarily because of poor locality of the loads of b. The
// reduction loop is innermost.
template <typename TAB, typename TC, index_t Rows, index_t Cols>
__attribute__((noinline))
void multiply_reduce_cols(const matrix_ref<TAB>& a, const matrix_ref<TAB>& b,
                          const matrix_ref<TC, Rows, Cols>& c) {
  for (index_t i : c.i()) {
    for (index_t j : c.j()) {
      c(i, j) = 0;
      for (index_t k : a.j()) {
        c(i, j) += a(i, k) * b(k, j);
      }
    }
  }
}

// This implementation moves the reduction loop between the rows and columns
// loops. This avoids the locality problem for the loads from b. This also is
// an easier loop to vectorize (it does not vectorize a reduction variable).
template <typename TAB, typename TC, index_t Rows, index_t Cols>
__attribute__((noinline))
void multiply_reduce_rows(const matrix_ref<TAB>& a, const matrix_ref<TAB>& b,
                          const matrix_ref<TC, Rows, Cols>& c) {
  for (index_t i : c.i()) {
    for (index_t j : c.j()) {
      c(i, j) = 0;
    }
    for (index_t k : a.j()) {
      for (index_t j : c.j()) {
        c(i, j) += a(i, k) * b(k, j);
      }
    }
  }
}

// This implementation reorders the reduction loop innermost. This vectorizes
// well, but has poor locality. However, this will be a useful helper function
// for the tiled implementation below.
template <typename TAB, typename TC, index_t Rows, index_t Cols>
__attribute__((always_inline))
void multiply_reduce_matrices(const matrix_ref<TAB>& a, const matrix_ref<TAB>& b,
                              const matrix_ref<TC, Rows, Cols>& c) {
  for (index_t i : c.i()) {
    for (index_t j : c.j()) {
      c(i, j) = 0;
    }
  }
  for (index_t k : a.j()) {
    for (index_t i : c.i()) {
      for (index_t j : c.j()) {
        c(i, j) += a(i, k) * b(k, j);
      }
    }
  }
}

// This implementation of matrix multiplication splits the loops over
// the output matrix into chunks, and reorders the small loops
// innermost to form tiles. This implementation should allow the compiler
// to keep all of the accumulators for the output in registers.
// For the matrix size benchmarked in main, this runs in ~0.44ms.
// This appears to achieve ~70% of the peak theoretical throughput
// of my machine.
template <typename TAB, typename TC>
__attribute__((noinline))
void multiply_reduce_tiles(const matrix_ref<TAB>& a, const matrix_ref<TAB>& b,
                           const matrix_ref<TC>& c) {
  // Adjust this depending on the target architecture. For AVX2,
  // vectors are 256-bit.
  constexpr index_t vector_size = 32 / sizeof(TC);

  // We want the tiles to be as big as possible without spilling any
  // of the accumulator registers to the stack.
  constexpr index_t tile_rows = 3;
  constexpr index_t tile_cols = vector_size * 4;

  for (auto io : split<tile_rows>(c.i())) {
    for (auto jo : split<tile_cols>(c.j())) {
      // Make a reference to this tile of the output.
      auto c_tile = c(io, jo);
#if 0
      // TODO: This should work, but it's slow, probably due to potential
      // aliasing that we can't fix due to https://bugs.llvm.org/show_bug.cgi?id=45863
      multiply_reduce_matrices(a, b, c_tile);
#elif 0
      // TODO: This should work, but it's slow, probably due to potential
      // aliasing that we can't fix due to https://bugs.llvm.org/show_bug.cgi?id=45863
      for (index_t i : c_tile.i()) {
        for (index_t j : c_tile.j()) {
          c_tile(i, j) = 0;
        }
      }
      for (index_t k : a.j()) {
        for (index_t i : c_tile.i()) {
          for (index_t j : c_tile.j()) {
            c_tile(i, j) += a(i, k) * b(k, j);
          }
        }
      }
#else
      TC buffer[tile_rows * tile_cols] = { 0.0f };
      matrix_ref<TC, tile_rows, tile_cols> accumulator(buffer, make_compact(c_tile.shape()));
      for (index_t k : a.j()) {
        for (index_t i : c_tile.i()) {
          for (index_t j : c_tile.j()) {
            accumulator(i, j) += a(i, k) * b(k, j);
          }
        }
      }
#if 0
      // TODO: This should work, but it's slow, it appears to
      // blow up the nice in-register accumulation of the loop
      // above.
      copy(accumulator, c_tile);
#else
      for (index_t i : c_tile.i()) {
        for (index_t j : c_tile.j()) {
          c_tile(i, j) = accumulator(i, j);
        }
      }
#endif
#endif
    }
  }
}

int main(int, const char**) {
  // Define two input matrices.
  constexpr index_t M = 24;
  constexpr index_t K = 10000;
  constexpr index_t N = 64;
  matrix<float> a({M, K});
  matrix<float> b({K, N});

  // 'for_each_value' calls the given function with a reference to
  // each value in the array. Use this to randomly initialize the
  // matrices with random values.
  std::mt19937_64 rng;
  std::uniform_real_distribution<float> uniform(0, 1);
  a.for_each_value([&](float& x) { x = uniform(rng); });
  b.for_each_value([&](float& x) { x = uniform(rng); });

  // Compute the result using all matrix multiply methods.
  matrix<float> c_reduce_cols({M, N});
  double reduce_cols_time = benchmark([&]() {
    multiply_reduce_cols(a.ref(), b.ref(), c_reduce_cols.ref());
  });
  std::cout << "reduce_cols time: " << reduce_cols_time * 1e3 << " ms" << std::endl;

  matrix<float> c_reduce_rows({M, N});
  double reduce_rows_time = benchmark([&]() {
    multiply_reduce_rows(a.ref(), b.ref(), c_reduce_rows.ref());
  });
  std::cout << "reduce_rows time: " << reduce_rows_time * 1e3 << " ms" << std::endl;

  matrix<float> c_reduce_tiles({M, N});
  double reduce_tiles_time = benchmark([&]() {
    multiply_reduce_tiles(a.ref(), b.ref(), c_reduce_tiles.ref());
  });
  std::cout << "reduce_tiles time: " << reduce_tiles_time * 1e3 << " ms" << std::endl;

  // Verify the results from all methods are equal.
  const float epsilon = 1e-4f;
  for (index_t i = 0; i < M; i++) {
    for (index_t j = 0; j < N; j++) {
      if (std::abs(c_reduce_rows(i, j) - c_reduce_cols(i, j)) > epsilon) {
        std::cout
          << "c_reduce_rows(" << i << ", " << j << ") = " << c_reduce_rows(i, j)
          << " != c_reduce_cols(" << i << ", " << j << ") = " << c_reduce_cols(i, j) << std::endl;
        return -1;
      }
      if (std::abs(c_reduce_tiles(i, j) - c_reduce_cols(i, j)) > epsilon) {
        std::cout
          << "c_reduce_tiles(" << i << ", " << j << ") = " << c_reduce_tiles(i, j)
          << " != c_reduce_cols(" << i << ", " << j << ") = " << c_reduce_cols(i, j) << std::endl;
        return -1;
      }
    }
  }
  return 0;
}

<commit_msg>Less redundant declaration of accumulator.<commit_after>// Copyright 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "array.h"
#include "benchmark.h"

#include <random>
#include <iostream>

using namespace nda;

// The standard matrix notation is to refer to elements by 'row,
// column'. To make this efficient for typical programs, we're going
// to make the second dimension the dense dim. This shape has the
// option of making the size of the matrix compile-time constant via
// the template parameters.
template <index_t Rows = UNK, index_t Cols = UNK>
using matrix_shape = shape<dim<UNK, Rows>, dense_dim<UNK, Cols>>;

// A matrix or matrix_ref is an array or array_ref with Shape =
// matrix_shape.
template <typename T, index_t Rows = UNK, index_t Cols = UNK,
          typename Alloc = std::allocator<T>>
using matrix = array<T, matrix_shape<Rows, Cols>, Alloc>;
template <typename T, index_t Rows = UNK, index_t Cols = UNK>
using matrix_ref = array_ref<T, matrix_shape<Rows, Cols>>;

// A textbook implementation of matrix multiplication. This is very simple,
// but it is slow, primarily because of poor locality of the loads of b. The
// reduction loop is innermost.
template <typename TAB, typename TC, index_t Rows, index_t Cols>
__attribute__((noinline))
void multiply_reduce_cols(const matrix_ref<TAB>& a, const matrix_ref<TAB>& b,
                          const matrix_ref<TC, Rows, Cols>& c) {
  for (index_t i : c.i()) {
    for (index_t j : c.j()) {
      c(i, j) = 0;
      for (index_t k : a.j()) {
        c(i, j) += a(i, k) * b(k, j);
      }
    }
  }
}

// This implementation moves the reduction loop between the rows and columns
// loops. This avoids the locality problem for the loads from b. This also is
// an easier loop to vectorize (it does not vectorize a reduction variable).
template <typename TAB, typename TC, index_t Rows, index_t Cols>
__attribute__((noinline))
void multiply_reduce_rows(const matrix_ref<TAB>& a, const matrix_ref<TAB>& b,
                          const matrix_ref<TC, Rows, Cols>& c) {
  for (index_t i : c.i()) {
    for (index_t j : c.j()) {
      c(i, j) = 0;
    }
    for (index_t k : a.j()) {
      for (index_t j : c.j()) {
        c(i, j) += a(i, k) * b(k, j);
      }
    }
  }
}

// This implementation reorders the reduction loop innermost. This vectorizes
// well, but has poor locality. However, this will be a useful helper function
// for the tiled implementation below.
template <typename TAB, typename TC, index_t Rows, index_t Cols>
__attribute__((always_inline))
void multiply_reduce_matrices(const matrix_ref<TAB>& a, const matrix_ref<TAB>& b,
                              const matrix_ref<TC, Rows, Cols>& c) {
  for (index_t i : c.i()) {
    for (index_t j : c.j()) {
      c(i, j) = 0;
    }
  }
  for (index_t k : a.j()) {
    for (index_t i : c.i()) {
      for (index_t j : c.j()) {
        c(i, j) += a(i, k) * b(k, j);
      }
    }
  }
}

// This implementation of matrix multiplication splits the loops over
// the output matrix into chunks, and reorders the small loops
// innermost to form tiles. This implementation should allow the compiler
// to keep all of the accumulators for the output in registers.
// For the matrix size benchmarked in main, this runs in ~0.44ms.
// This appears to achieve ~70% of the peak theoretical throughput
// of my machine.
template <typename TAB, typename TC>
__attribute__((noinline))
void multiply_reduce_tiles(const matrix_ref<TAB>& a, const matrix_ref<TAB>& b,
                           const matrix_ref<TC>& c) {
  // Adjust this depending on the target architecture. For AVX2,
  // vectors are 256-bit.
  constexpr index_t vector_size = 32 / sizeof(TC);

  // We want the tiles to be as big as possible without spilling any
  // of the accumulator registers to the stack.
  constexpr index_t tile_rows = 3;
  constexpr index_t tile_cols = vector_size * 4;

  for (auto io : split<tile_rows>(c.i())) {
    for (auto jo : split<tile_cols>(c.j())) {
      // Make a reference to this tile of the output.
      auto c_tile = c(io, jo);
#if 0
      // TODO: This should work, but it's slow, probably due to potential
      // aliasing that we can't fix due to https://bugs.llvm.org/show_bug.cgi?id=45863
      multiply_reduce_matrices(a, b, c_tile);
#elif 0
      // TODO: This should work, but it's slow, probably due to potential
      // aliasing that we can't fix due to https://bugs.llvm.org/show_bug.cgi?id=45863
      for (index_t i : c_tile.i()) {
        for (index_t j : c_tile.j()) {
          c_tile(i, j) = 0;
        }
      }
      for (index_t k : a.j()) {
        for (index_t i : c_tile.i()) {
          for (index_t j : c_tile.j()) {
            c_tile(i, j) += a(i, k) * b(k, j);
          }
        }
      }
#else
      TC buffer[tile_rows * tile_cols] = { 0.0f };
      auto accumulator = make_array_ref(buffer, make_compact(c_tile.shape()));
      for (index_t k : a.j()) {
        for (index_t i : c_tile.i()) {
          for (index_t j : c_tile.j()) {
            accumulator(i, j) += a(i, k) * b(k, j);
          }
        }
      }
#if 0
      // TODO: This should work, but it's slow, it appears to
      // blow up the nice in-register accumulation of the loop
      // above.
      copy(accumulator, c_tile);
#else
      for (index_t i : c_tile.i()) {
        for (index_t j : c_tile.j()) {
          c_tile(i, j) = accumulator(i, j);
        }
      }
#endif
#endif
    }
  }
}

int main(int, const char**) {
  // Define two input matrices.
  constexpr index_t M = 24;
  constexpr index_t K = 10000;
  constexpr index_t N = 64;
  matrix<float> a({M, K});
  matrix<float> b({K, N});

  // 'for_each_value' calls the given function with a reference to
  // each value in the array. Use this to randomly initialize the
  // matrices with random values.
  std::mt19937_64 rng;
  std::uniform_real_distribution<float> uniform(0, 1);
  a.for_each_value([&](float& x) { x = uniform(rng); });
  b.for_each_value([&](float& x) { x = uniform(rng); });

  // Compute the result using all matrix multiply methods.
  matrix<float> c_reduce_cols({M, N});
  double reduce_cols_time = benchmark([&]() {
    multiply_reduce_cols(a.ref(), b.ref(), c_reduce_cols.ref());
  });
  std::cout << "reduce_cols time: " << reduce_cols_time * 1e3 << " ms" << std::endl;

  matrix<float> c_reduce_rows({M, N});
  double reduce_rows_time = benchmark([&]() {
    multiply_reduce_rows(a.ref(), b.ref(), c_reduce_rows.ref());
  });
  std::cout << "reduce_rows time: " << reduce_rows_time * 1e3 << " ms" << std::endl;

  matrix<float> c_reduce_tiles({M, N});
  double reduce_tiles_time = benchmark([&]() {
    multiply_reduce_tiles(a.ref(), b.ref(), c_reduce_tiles.ref());
  });
  std::cout << "reduce_tiles time: " << reduce_tiles_time * 1e3 << " ms" << std::endl;

  // Verify the results from all methods are equal.
  const float epsilon = 1e-4f;
  for (index_t i = 0; i < M; i++) {
    for (index_t j = 0; j < N; j++) {
      if (std::abs(c_reduce_rows(i, j) - c_reduce_cols(i, j)) > epsilon) {
        std::cout
          << "c_reduce_rows(" << i << ", " << j << ") = " << c_reduce_rows(i, j)
          << " != c_reduce_cols(" << i << ", " << j << ") = " << c_reduce_cols(i, j) << std::endl;
        return -1;
      }
      if (std::abs(c_reduce_tiles(i, j) - c_reduce_cols(i, j)) > epsilon) {
        std::cout
          << "c_reduce_tiles(" << i << ", " << j << ") = " << c_reduce_tiles(i, j)
          << " != c_reduce_cols(" << i << ", " << j << ") = " << c_reduce_cols(i, j) << std::endl;
        return -1;
      }
    }
  }
  return 0;
}

<|endoftext|>


<commit_before>/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:

    /*
    * This function returns the last Node of a linked list.
    */
    ListNode *getListTail(ListNode *head) {
        if(head == NULL)
            return NULL;
        while(head->next != NULL)
            head = head->next;
        return head;
    }

    /*
    * This function makes out whether a linked list has a circle;
    */
    ListNode *getMeetPoint(ListNode *head) {
        ListNode* slow = head;
        ListNode* fast = head;
        while(fast != NULL && fast->next != NULL) {
            slow = slow->next;
            fast = fast->next->next;
            if(slow == fast)
                return fast;
        }
        return NULL;
    }

    /*
    * This function returns the start node of circle in a linked list;
    */
    ListNode *getStartOfCirle(ListNode *head, ListNode *meetPoint) {
        while(head != meetPoint) {
            head = head->next;
            meetPoint = meetPoint->next;
        }
        return head;
    }

    /*
    * This function returns the first intersection of two linked list.
    * If two linked lists have no intersection, return NULL;
    */
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        ListNode *tailA = getListTail(headA);
        if(tailA != NULL) {
            tailA->next = headB;
            ListNode *meetPoint = getMeetPoint(headA);
            if(meetPoint != NULL) {
                ListNode *intersectionNode = getStartOfCirle(headA, meetPoint);
                tailA->next = NULL;
                return intersectionNode;
            }
        }
        return NULL;
    }
};
<commit_msg>Update IntersectionofTwoLinkedLists.cpp<commit_after>/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    int getListLength(ListNode *head) {
        int length = 0;
        while(head != NULL) {
            length++;
            head = head->next;
        }
        return length;
    }

    ListNode *removeFromHead(ListNode *head, int len) {
        for(;len > 0; len--)
            head = head->next;
        return head;
    }

    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        if(headA == NULL || headB == NULL)
            return NULL;
        int lenA = getListLength(headA);
        int lenB = getListLength(headB);
        ListNode *tempNodeA;
        ListNode *tempNodeB;
        if(lenA > lenB) {
            tempNodeA = removeFromHead(headA, lenA - lenB);
            tempNodeB = headB;
        } else {
            tempNodeA = removeFromHead(headB, lenB - lenA);
            tempNodeB = headA;
        }
        while(tempNodeA != tempNodeB && tempNodeA != NULL && tempNodeB != NULL) {
            tempNodeA = tempNodeA->next;
            tempNodeB = tempNodeB->next;
        }
        return tempNodeA;
    }
<|endoftext|>


<commit_before>#pragma once
/*
**  Copyright (C) 2012 Aldebaran Robotics
**  See COPYING for the license
*/

#ifndef _SRC_OBJECT_P_HPP_
#define _SRC_OBJECT_P_HPP_

#include <iostream>
#include <string>
#include <boost/thread/recursive_mutex.hpp>

#include <qi/atomic.hpp>

#include <qitype/api.hpp>
#include <qitype/signature.hpp>
#include <qi/future.hpp>
#include <qitype/anyobject.hpp>
#include <qitype/metasignal.hpp>
#include <qitype/metamethod.hpp>
#include <qitype/signal.hpp>

namespace qi {

  class EventLoop;
  class ManageablePrivate
  {
  public:
    ManageablePrivate();
    // SignalLinks that target us. Needed to be able to disconnect upon destruction
    std::vector<SignalSubscriber>       registrations;
    mutable boost::mutex                        registrationsMutex;
    Manageable::TimedMutexPtr           objectMutex; //returned by mutex()
    bool                                dying;
    // Event loop in which calls are made if set
    EventLoop                          *eventLoop;

    bool statsEnabled;
    bool traceEnabled;
    ObjectStatistics stats;
    qi::atomic<int> traceId;
  };

};

#endif  // _SRC_OBJECT_P_HPP_
<commit_msg>use qi::Atomic instead of qi::atomic<commit_after>#pragma once
/*
**  Copyright (C) 2012 Aldebaran Robotics
**  See COPYING for the license
*/

#ifndef _SRC_OBJECT_P_HPP_
#define _SRC_OBJECT_P_HPP_

#include <iostream>
#include <string>
#include <boost/thread/recursive_mutex.hpp>

#include <qi/atomic.hpp>

#include <qitype/api.hpp>
#include <qitype/signature.hpp>
#include <qi/future.hpp>
#include <qitype/anyobject.hpp>
#include <qitype/metasignal.hpp>
#include <qitype/metamethod.hpp>
#include <qitype/signal.hpp>

namespace qi {

  class EventLoop;
  class ManageablePrivate
  {
  public:
    ManageablePrivate();
    // SignalLinks that target us. Needed to be able to disconnect upon destruction
    std::vector<SignalSubscriber>       registrations;
    mutable boost::mutex                        registrationsMutex;
    Manageable::TimedMutexPtr           objectMutex; //returned by mutex()
    bool                                dying;
    // Event loop in which calls are made if set
    EventLoop                          *eventLoop;

    bool statsEnabled;
    bool traceEnabled;
    ObjectStatistics stats;
    qi::Atomic<int> traceId;
  };

};

#endif  // _SRC_OBJECT_P_HPP_
<|endoftext|>


<commit_before>/*
 * libjingle
 * Copyright 2014 Google Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  1. Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 *  2. 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.
 *  3. The name of the author may not be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
 */

#if defined(LIBPEERCONNECTION_LIB) || defined(LIBPEERCONNECTION_IMPLEMENTATION)

#include "talk/media/webrtc/webrtcmediaengine.h"
#include "talk/media/webrtc/webrtcvideoengine.h"
#include "talk/media/webrtc/webrtcvideoengine2.h"
#include "talk/media/webrtc/webrtcvoiceengine.h"
#include "webrtc/system_wrappers/interface/field_trial.h"

namespace cricket {

class WebRtcMediaEngine
    : public CompositeMediaEngine<WebRtcVoiceEngine, WebRtcVideoEngine> {
 public:
  WebRtcMediaEngine() {}
  WebRtcMediaEngine(webrtc::AudioDeviceModule* adm,
                    webrtc::AudioDeviceModule* adm_sc,
                    WebRtcVideoEncoderFactory* encoder_factory,
                    WebRtcVideoDecoderFactory* decoder_factory) {
    voice_.SetAudioDeviceModule(adm, adm_sc);
    video_.SetExternalEncoderFactory(encoder_factory);
    video_.SetExternalDecoderFactory(decoder_factory);
  }
};

class WebRtcMediaEngine2
    : public CompositeMediaEngine<WebRtcVoiceEngine, WebRtcVideoEngine2> {
 public:
  WebRtcMediaEngine2(webrtc::AudioDeviceModule* adm,
                     webrtc::AudioDeviceModule* adm_sc,
                     WebRtcVideoEncoderFactory* encoder_factory,
                     WebRtcVideoDecoderFactory* decoder_factory) {
    voice_.SetAudioDeviceModule(adm, adm_sc);
    video_.SetExternalDecoderFactory(decoder_factory);
    video_.SetExternalEncoderFactory(encoder_factory);
  }
};

}  // namespace cricket

WRME_EXPORT
cricket::MediaEngineInterface* CreateWebRtcMediaEngine(
    webrtc::AudioDeviceModule* adm,
    webrtc::AudioDeviceModule* adm_sc,
    cricket::WebRtcVideoEncoderFactory* encoder_factory,
    cricket::WebRtcVideoDecoderFactory* decoder_factory) {
  if (webrtc::field_trial::FindFullName("WebRTC-NewVideoAPI") == "Enabled") {
    return new cricket::WebRtcMediaEngine2(adm, adm_sc, encoder_factory,
                                           decoder_factory);
  }
  return new cricket::WebRtcMediaEngine(adm, adm_sc, encoder_factory,
                                        decoder_factory);
}

WRME_EXPORT
void DestroyWebRtcMediaEngine(cricket::MediaEngineInterface* media_engine) {
  delete media_engine;
}

namespace cricket {

// Used by ChannelManager when no media engine is passed in to it
// explicitly (acts as a default).
MediaEngineInterface* WebRtcMediaEngineFactory::Create() {
  return new cricket::WebRtcMediaEngine();
}

// Used by PeerConnectionFactory to create a media engine passed into
// ChannelManager.
MediaEngineInterface* WebRtcMediaEngineFactory::Create(
    webrtc::AudioDeviceModule* adm,
    webrtc::AudioDeviceModule* adm_sc,
    WebRtcVideoEncoderFactory* encoder_factory,
    WebRtcVideoDecoderFactory* decoder_factory) {
  return CreateWebRtcMediaEngine(adm, adm_sc, encoder_factory, decoder_factory);
}

}  // namespace cricket

#endif  // defined(LIBPEERCONNECTION_LIB) ||
        // defined(LIBPEERCONNECTION_IMPLEMENTATION)
<commit_msg>Set WebRtcVideoEngine2 as the WebRtcMediaEngine.<commit_after>/*
 * libjingle
 * Copyright 2014 Google Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  1. Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 *  2. 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.
 *  3. The name of the author may not be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
 */

#if defined(LIBPEERCONNECTION_LIB) || defined(LIBPEERCONNECTION_IMPLEMENTATION)

#include "talk/media/webrtc/webrtcmediaengine.h"
#include "talk/media/webrtc/webrtcvideoengine.h"
#include "talk/media/webrtc/webrtcvideoengine2.h"
#include "talk/media/webrtc/webrtcvoiceengine.h"
#include "webrtc/system_wrappers/interface/field_trial.h"

namespace cricket {

class WebRtcMediaEngine
    : public CompositeMediaEngine<WebRtcVoiceEngine, WebRtcVideoEngine> {
 public:
  WebRtcMediaEngine() {}
  WebRtcMediaEngine(webrtc::AudioDeviceModule* adm,
                    webrtc::AudioDeviceModule* adm_sc,
                    WebRtcVideoEncoderFactory* encoder_factory,
                    WebRtcVideoDecoderFactory* decoder_factory) {
    voice_.SetAudioDeviceModule(adm, adm_sc);
    video_.SetExternalEncoderFactory(encoder_factory);
    video_.SetExternalDecoderFactory(decoder_factory);
  }
};

class WebRtcMediaEngine2
    : public CompositeMediaEngine<WebRtcVoiceEngine, WebRtcVideoEngine2> {
 public:
  WebRtcMediaEngine2(webrtc::AudioDeviceModule* adm,
                     webrtc::AudioDeviceModule* adm_sc,
                     WebRtcVideoEncoderFactory* encoder_factory,
                     WebRtcVideoDecoderFactory* decoder_factory) {
    voice_.SetAudioDeviceModule(adm, adm_sc);
    video_.SetExternalDecoderFactory(decoder_factory);
    video_.SetExternalEncoderFactory(encoder_factory);
  }
};

}  // namespace cricket

WRME_EXPORT
cricket::MediaEngineInterface* CreateWebRtcMediaEngine(
    webrtc::AudioDeviceModule* adm,
    webrtc::AudioDeviceModule* adm_sc,
    cricket::WebRtcVideoEncoderFactory* encoder_factory,
    cricket::WebRtcVideoDecoderFactory* decoder_factory) {
  return new cricket::WebRtcMediaEngine2(adm, adm_sc, encoder_factory,
                                         decoder_factory);
}

WRME_EXPORT
void DestroyWebRtcMediaEngine(cricket::MediaEngineInterface* media_engine) {
  delete media_engine;
}

namespace cricket {

// Used by ChannelManager when no media engine is passed in to it
// explicitly (acts as a default).
MediaEngineInterface* WebRtcMediaEngineFactory::Create() {
  return new cricket::WebRtcMediaEngine();
}

// Used by PeerConnectionFactory to create a media engine passed into
// ChannelManager.
MediaEngineInterface* WebRtcMediaEngineFactory::Create(
    webrtc::AudioDeviceModule* adm,
    webrtc::AudioDeviceModule* adm_sc,
    WebRtcVideoEncoderFactory* encoder_factory,
    WebRtcVideoDecoderFactory* decoder_factory) {
  return CreateWebRtcMediaEngine(adm, adm_sc, encoder_factory, decoder_factory);
}

}  // namespace cricket

#endif  // defined(LIBPEERCONNECTION_LIB) ||
        // defined(LIBPEERCONNECTION_IMPLEMENTATION)
<|endoftext|>


<commit_before>/*
 * Copyright 2016 C. Brett Witherspoon
 */

#include <chrono>
#include <iostream>
#include <utility>
#include <tuple>

#include <signum/fixed.hpp>
#include <signum/util/priority.hpp>
#include <signum/opencl/session.hpp>

static const size_t buff_size = 32*1024*1024;

using namespace signum;

void opencl_scalar_fixed_to_float()
{
    opencl::session session("", "fixed_to_float.cl");

    auto kernel = session.create_kernel("fixed_to_float");

    kernel.create_buffer(0, buff_size / 2, false);
    kernel.create_buffer(1, buff_size, true);

    void *ptr0;
    size_t size0;

    std::tie(ptr0, size0) = kernel.map_buffer(0, true);

    auto buf0 = static_cast<cl_short *>(ptr0);

    for (auto i = 0U; i < size0 / sizeof(cl_short); ++i)
    {
        buf0[i] = i;
    }

    kernel.unmap_buffer(0, std::make_pair(ptr0, size0));

    auto start = std::chrono::steady_clock::now();
    kernel.enqueue(buff_size / sizeof(cl_float));
    kernel.wait();
    auto end = std::chrono::steady_clock::now();
    std::chrono::duration<double> diff = end - start;
    std::cout << __func__ << ": " << diff.count() / 1e6 << " us ";

    void *ptr1;
    size_t size1;

    std::tie(ptr1, size1) = kernel.map_buffer(1, false);

    auto buf1 = static_cast<cl_float *>(ptr1);

    kernel.unmap_buffer(1, std::make_pair(ptr1, size1));

    // The compiler is sensitive about unused variables
    (void)buf1;
}

void opencl_vector_fixed_to_float()
{
    opencl::session session("", "fixed_to_float.cl");

    auto kernel = session.create_kernel("fixed4_to_float4");

    kernel.create_buffer(0, buff_size / 2, false);
    kernel.create_buffer(1, buff_size, true);

    void *ptr0;
    size_t size0;

    std::tie(ptr0, size0) = kernel.map_buffer(0, true);

    auto buf0 = static_cast<cl_short *>(ptr0);

    for (auto i = 0U; i < size0 / sizeof(cl_short); ++i)
    {
        buf0[i] = i;
    }

    kernel.unmap_buffer(0, std::make_pair(ptr0, size0));

    auto start = std::chrono::steady_clock::now();
    kernel.enqueue(buff_size / sizeof(cl_float) / 4);
    kernel.wait();
    auto end = std::chrono::steady_clock::now();
    std::chrono::duration<double> diff = end - start;
    std::cout << __func__ << ": " << diff.count() / 1e6 << " us ";

    void *ptr1;
    size_t size1;

    std::tie(ptr1, size1) = kernel.map_buffer(1, false);

    auto buf1 = static_cast<cl_float *>(ptr1);

    kernel.unmap_buffer(1, std::make_pair(ptr1, size1));

    // The compiler is sensitive about unused variables
    (void)buf1;
}

void cpu_fixed_to_float()
{
    std::vector<short> buf0(buff_size / sizeof(short));
    std::vector<float> buf1(buff_size / sizeof(short));

    for (auto i = 0U; i < buf0.size(); ++i)
    {
        buf0[i] = i;
    }

    auto start = std::chrono::steady_clock::now();
    for (auto i = 0U; i < buf0.size(); ++i)
    {
        buf1[i] = signum::fixed_to_floating<float>(buf0[i]);
    }
    auto end = std::chrono::steady_clock::now();
    std::chrono::duration<double> diff = end - start;
    std::cout << __func__ << ": " << diff.count() / 1e6 << " us ";

    // The compiler is sensitive about unused variables
    (void)buf1;
}

int main (int argc, char *argv[])
{
    util::set_realtime_priority();

    cpu_fixed_to_float();
    opencl_scalar_fixed_to_float();
    opencl_vector_fixed_to_float();

    return 0;
}
<commit_msg>examples: fix opencl fixed to float<commit_after>/*
 * Copyright 2016 C. Brett Witherspoon
 */

#include <chrono>
#include <iostream>
#include <utility>
#include <tuple>

#include <signum/fixed.hpp>
#include <signum/util/priority.hpp>
#include <signum/opencl/session.hpp>

static const size_t buff_size = 32*1024*1024;

using namespace signum;

void opencl_scalar_fixed_to_float()
{
    opencl::session session("", "opencl_fixed_to_float.cl");

    auto kernel = session.create_kernel("fixed_to_float");

    kernel.create_buffer(0, buff_size / 2, false);
    kernel.create_buffer(1, buff_size, true);

    void *ptr0;
    size_t size0;

    std::tie(ptr0, size0) = kernel.map_buffer(0, true);

    auto buf0 = static_cast<cl_short *>(ptr0);

    for (auto i = 0U; i < size0 / sizeof(cl_short); ++i)
    {
        buf0[i] = i;
    }

    kernel.unmap_buffer(0, std::make_pair(ptr0, size0));

    auto start = std::chrono::steady_clock::now();
    kernel.enqueue(buff_size / sizeof(cl_float));
    kernel.wait();
    auto end = std::chrono::steady_clock::now();
    std::chrono::duration<double> diff = end - start;
    std::cout << __func__ << ": " << diff.count() / 1e6 << " us " << std::endl;

    void *ptr1;
    size_t size1;

    std::tie(ptr1, size1) = kernel.map_buffer(1, false);

    auto buf1 = static_cast<cl_float *>(ptr1);

    kernel.unmap_buffer(1, std::make_pair(ptr1, size1));

    // The compiler is sensitive about unused variables
    (void)buf1;
}

void opencl_vector_fixed_to_float()
{
    opencl::session session("", "opencl_fixed_to_float.cl");

    auto kernel = session.create_kernel("fixed4_to_float4");

    kernel.create_buffer(0, buff_size / 2, false);
    kernel.create_buffer(1, buff_size, true);

    void *ptr0;
    size_t size0;

    std::tie(ptr0, size0) = kernel.map_buffer(0, true);

    auto buf0 = static_cast<cl_short *>(ptr0);

    for (auto i = 0U; i < size0 / sizeof(cl_short); ++i)
    {
        buf0[i] = i;
    }

    kernel.unmap_buffer(0, std::make_pair(ptr0, size0));

    auto start = std::chrono::steady_clock::now();
    kernel.enqueue(buff_size / sizeof(cl_float) / 4);
    kernel.wait();
    auto end = std::chrono::steady_clock::now();
    std::chrono::duration<double> diff = end - start;
    std::cout << __func__ << ": " << diff.count() / 1e6 << " us " << std::endl;

    void *ptr1;
    size_t size1;

    std::tie(ptr1, size1) = kernel.map_buffer(1, false);

    auto buf1 = static_cast<cl_float *>(ptr1);

    kernel.unmap_buffer(1, std::make_pair(ptr1, size1));

    // The compiler is sensitive about unused variables
    (void)buf1;
}

void cpu_fixed_to_float()
{
    std::vector<short> buf0(buff_size / sizeof(short));
    std::vector<float> buf1(buff_size / sizeof(short));

    for (auto i = 0U; i < buf0.size(); ++i)
    {
        buf0[i] = i;
    }

    auto start = std::chrono::steady_clock::now();
    for (auto i = 0U; i < buf0.size(); ++i)
    {
        buf1[i] = signum::fixed_to_floating<float>(buf0[i]);
    }
    auto end = std::chrono::steady_clock::now();
    std::chrono::duration<double> diff = end - start;
    std::cout << __func__ << ": " << diff.count() / 1e6 << " us " << std::endl;

    // The compiler is sensitive about unused variables
    (void)buf1;
}

int main (int argc, char *argv[])
{
    util::set_realtime_priority();

    cpu_fixed_to_float();
    opencl_scalar_fixed_to_float();
    opencl_vector_fixed_to_float();

    return 0;
}
<|endoftext|>


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

// INCLUDES
#include <string>
#include <OpenSim/version.h>
#include <OpenSim/Common/Storage.h>
#include <OpenSim/Common/IO.h>
#include <OpenSim/Common/VisibleProperties.h>
#include <OpenSim/Common/ScaleSet.h>
#include <OpenSim/Common/LoadOpenSimLibrary.h>
#include <OpenSim/Simulation/Model/Model.h>
#include <OpenSim/Actuators/LinearSetPoint.h>
#include <OpenSim/DynamicsEngines/SdfastEngine/SdfastFileWriter.h>

using namespace std;
using namespace OpenSim;

static void PrintUsage(const char *aProgName, ostream &aOStream);

//______________________________________________________________________________
/**
 * Program to read an xml file for an openSim Model and generate
 * SDFast corresponding code.
 *
 * @param argc Number of command line arguments (should be 2 or more).
 * @param argv Command line arguments:  mkModel -IM inFile and at least one of [-SD SdfastFile] [-OM SimulationModelFile] [-D OutputDirectory]
 */
int main(int argc,char **argv)
{
	LoadOpenSimLibrary("osimActuators");
	LoadOpenSimLibrary("osimSimmKinematicsEngine");

	// PARSE COMMAND LINE
	static string unassigned = "Unassigned";
	string inName = unassigned;
	string sdfastName = unassigned;
	string headerName = unassigned;
	string modelLibraryName = unassigned;
	string sourceName = unassigned;
	string simModelName = unassigned;
	string folderName = ".";
	string option = "";

	if (argc < 3)
	{
		PrintUsage(argv[0], cout);
		exit(-1);
	}
	else {		// Don't know maybe user needs help or have special needs
		int i;
		for(i=1; i<=(argc-1); i++) {
			option = argv[i];

			// PRINT THE USAGE OPTIONS
			if((option=="-help")||(option=="-h")||(option=="-Help")||(option=="-H")||
				(option=="-usage")||(option=="-u")||(option=="-Usage")||(option=="-U")) {
					PrintUsage(argv[0], cout);
					return(0);
					// IDENTIFY SETUP FILE
				}
				else if((option=="-IM")||(option=="-InputModel")) {
					inName = argv[++i];
				}
				else if((option=="-SD")||(option=="-SystemDescription")) {
					sdfastName = argv[++i];
				}
#if 0
				else if((option=="-FF")||(option=="-ForwardFile")) {
					sourceName = argv[++i];
				}
				else if((option=="-MH")||(option=="-ModelHeader")) {
					headerName = argv[++i];
				}
#endif
				else if((option=="-ML")||(option=="-ModelLibrary")) {
					modelLibraryName = argv[++i];
				}
				else if((option=="-OM")||(option=="-OutputModel")) {
					simModelName = argv[++i];
				}
				else if((option=="-D")||(option=="-Directory")) {
					folderName = argv[++i];
				}
				else {
					cout << "Unrecognized option " << option << " on command line... Ignored" << endl;
					PrintUsage(argv[0], cout);
					return(0);
				}
		}
	}

	try {
		if (inName != unassigned)
		{
			// Construct the model
			Model *model = new Model(inName);
			model->setup();
			//model->peteTest();

			// Create SdfastFileWriter object and write out selected files
			SdfastFileWriter sfw(model, folderName);

			if (sdfastName != unassigned)
				sfw.writeSdfastFile(sdfastName);

			if (sourceName != unassigned) {
				if (headerName != unassigned) sfw.writeModelSourceFile(sourceName, headerName);
				else sfw.writeModelSourceFile(sourceName, "model.h");
			}

			if (headerName != unassigned)
				sfw.writeModelHeaderFile(headerName);

			if (simModelName != unassigned)
				sfw.writeSimulationModelFile(simModelName, modelLibraryName);

			delete model;
		}
	}
	catch(Exception &x) {
		x.print(cout);
	}

}

//_____________________________________________________________________________
/**
 * Print the usage for this application
 */
void PrintUsage(const char *aProgName, ostream &aOStream)
{
	string progName=IO::GetFileNameFromURI(aProgName);
	aOStream<<"\n\n"<<progName<<":\n"<<Version_And_Date()<<"\n\n";
	aOStream<<"Option                    Argument         Action / Notes\n";
	aOStream<<"------                    --------         --------------\n";
	aOStream<<"-Help, -H                                  Print the command-line options for "<<progName<<".\n";
	aOStream<<"-InputModel, -IM          ModelFile        Input SimmKinematicsEngine model file (XML format).\n";
	aOStream<<"-SystemDescription, -SD   FileName         Output SDFast system description file (model.sd in SIMM)\n";
#if 0
	aOStream<<"-ForwardFile, -FF         FileName         Output forward dynamics C file (sdfor.c in SIMM)\n";
	aOStream<<"-ModelHeader, -MH         FileName         Output model header file (model.h in SIMM)\n";
#endif
	aOStream<<"-ModelLibrary, -ML        FileName         The compiled SD/Fast model for computing the dynamics for this model\n";
	aOStream<<"-OuputModel, -OM          ModelFile        Output SDfastEngine model file (XML format).\n";
	aOStream<<"-Directory, -D            DirectoryName    Directory into which to write output.\n";
}
<commit_msg>Warn if user tries to make an sdfast-based osim model without specifying model_library<commit_after>// mkModel.cpp
// Author: Ayman Habib
/* Copyright (c) 2005, Stanford University and Ayman Habib.
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject
 * to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

// INCLUDES
#include <string>
#include <OpenSim/version.h>
#include <OpenSim/Common/Storage.h>
#include <OpenSim/Common/IO.h>
#include <OpenSim/Common/VisibleProperties.h>
#include <OpenSim/Common/ScaleSet.h>
#include <OpenSim/Common/LoadOpenSimLibrary.h>
#include <OpenSim/Simulation/Model/Model.h>
#include <OpenSim/Actuators/LinearSetPoint.h>
#include <OpenSim/DynamicsEngines/SdfastEngine/SdfastFileWriter.h>

using namespace std;
using namespace OpenSim;

static void PrintUsage(const char *aProgName, ostream &aOStream);

//______________________________________________________________________________
/**
 * Program to read an xml file for an openSim Model and generate
 * SDFast corresponding code.
 *
 * @param argc Number of command line arguments (should be 2 or more).
 * @param argv Command line arguments:  mkModel -IM inFile and at least one of [-SD SdfastFile] [-OM SimulationModelFile] [-D OutputDirectory]
 */
int main(int argc,char **argv)
{
	LoadOpenSimLibrary("osimActuators");
	LoadOpenSimLibrary("osimSimmKinematicsEngine");

	// PARSE COMMAND LINE
	static string unassigned = "Unassigned";
	string inName = unassigned;
	string sdfastName = unassigned;
	string headerName = unassigned;
	string modelLibraryName = unassigned;
	string sourceName = unassigned;
	string simModelName = unassigned;
	string folderName = ".";
	string option = "";

	if (argc < 3)
	{
		PrintUsage(argv[0], cout);
		exit(-1);
	}
	else {		// Don't know maybe user needs help or have special needs
		int i;
		for(i=1; i<=(argc-1); i++) {
			option = argv[i];

			// PRINT THE USAGE OPTIONS
			if((option=="-help")||(option=="-h")||(option=="-Help")||(option=="-H")||
				(option=="-usage")||(option=="-u")||(option=="-Usage")||(option=="-U")) {
					PrintUsage(argv[0], cout);
					return(0);
					// IDENTIFY SETUP FILE
				}
				else if((option=="-IM")||(option=="-InputModel")) {
					inName = argv[++i];
				}
				else if((option=="-SD")||(option=="-SystemDescription")) {
					sdfastName = argv[++i];
				}
#if 0
				else if((option=="-FF")||(option=="-ForwardFile")) {
					sourceName = argv[++i];
				}
				else if((option=="-MH")||(option=="-ModelHeader")) {
					headerName = argv[++i];
				}
#endif
				else if((option=="-ML")||(option=="-ModelLibrary")) {
					modelLibraryName = argv[++i];
				}
				else if((option=="-OM")||(option=="-OutputModel")) {
					simModelName = argv[++i];
				}
				else if((option=="-D")||(option=="-Directory")) {
					folderName = argv[++i];
				}
				else {
					cout << "Unrecognized option " << option << " on command line... Ignored" << endl;
					PrintUsage(argv[0], cout);
					return(0);
				}
		}
	}

	try {
		if (inName != unassigned)
		{
			// Construct the model
			Model *model = new Model(inName);
			model->setup();
			//model->peteTest();

			// Create SdfastFileWriter object and write out selected files
			SdfastFileWriter sfw(model, folderName);

			if (sdfastName != unassigned)
				sfw.writeSdfastFile(sdfastName);

			if (sourceName != unassigned) {
				if (headerName != unassigned) sfw.writeModelSourceFile(sourceName, headerName);
				else sfw.writeModelSourceFile(sourceName, "model.h");
			}

			if (headerName != unassigned)
				sfw.writeModelHeaderFile(headerName);

			if (simModelName != unassigned) {
				if(modelLibraryName == unassigned)
					std::cerr << "WARNING: Generating an SDFast-based OpenSim model with no model library (-ML/-ModelLibrary not specified)." << std::endl;
				sfw.writeSimulationModelFile(simModelName, modelLibraryName);
			}

			delete model;
		}
	}
	catch(Exception &x) {
		x.print(cout);
	}

}

//_____________________________________________________________________________
/**
 * Print the usage for this application
 */
void PrintUsage(const char *aProgName, ostream &aOStream)
{
	string progName=IO::GetFileNameFromURI(aProgName);
	aOStream<<"\n\n"<<progName<<":\n"<<Version_And_Date()<<"\n\n";
	aOStream<<"Option                    Argument         Action / Notes\n";
	aOStream<<"------                    --------         --------------\n";
	aOStream<<"-Help, -H                                  Print the command-line options for "<<progName<<".\n";
	aOStream<<"-InputModel, -IM          ModelFile        Input SimmKinematicsEngine model file (XML format).\n";
	aOStream<<"-SystemDescription, -SD   FileName         Output SDFast system description file (model.sd in SIMM)\n";
#if 0
	aOStream<<"-ForwardFile, -FF         FileName         Output forward dynamics C file (sdfor.c in SIMM)\n";
	aOStream<<"-ModelHeader, -MH         FileName         Output model header file (model.h in SIMM)\n";
#endif
	aOStream<<"-ModelLibrary, -ML        FileName         The compiled SD/Fast model for computing the dynamics for this model\n";
	aOStream<<"-OuputModel, -OM          ModelFile        Output SDfastEngine model file (XML format).\n";
	aOStream<<"-Directory, -D            DirectoryName    Directory into which to write output.\n";
}
<|endoftext|>


<commit_before>#include "band.h"

namespace sirius {

template <typename T>
int Band::residuals(K_point* kp__,
                    int ispn__,
                    int N__,
                    int num_bands__,
                    std::vector<double>& eval__,
                    std::vector<double>& eval_old__,
                    matrix<T>& evec__,
                    Wave_functions<false>& hphi__,
                    Wave_functions<false>& ophi__,
                    Wave_functions<false>& hpsi__,
                    Wave_functions<false>& opsi__,
                    Wave_functions<false>& res__,
                    std::vector<double>& h_diag__,
                    std::vector<double>& o_diag__)
{
    PROFILE_WITH_TIMER("sirius::Band::residuals");

    auto& itso = ctx_.iterative_solver_input_section();
    bool converge_by_energy = (itso.converge_by_energy_ == 1);

    /* norm of residuals */
    std::vector<double> res_norm(num_bands__);

    int n = 0;
    if (converge_by_energy)
    {
        std::vector<double> eval_tmp(num_bands__);

        /* main trick here: first estimate energy difference, and only then compute unconverged residuals */
        for (int i = 0; i < num_bands__; i++)
        {
            bool take_res = true;
            if (itso.converge_occupied_ && kp__->band_occupancy(i + ispn__ * ctx_.num_fv_states()) < 1e-10) take_res = false;

            if (take_res && std::abs(eval__[i] - eval_old__[i]) > itso.energy_tolerance_)
            {
                std::memcpy(&evec__(0, num_bands__ + n), &evec__(0, i), N__ * sizeof(T));
                eval_tmp[n++] = eval__[i];
            }
        }
        // TODO: do this on GPU

        /* create alias for eigen-vectors corresponding to unconverged residuals */
        matrix<T> evec_tmp;
        if (ctx_.processing_unit() == CPU)
        {
            evec_tmp = matrix<T>(&evec__(0, num_bands__), evec__.ld(), n);
        }
        #ifdef __GPU
        if (ctx_.processing_unit() == GPU)
        {
            evec_tmp = matrix<T>(evec__.template at<CPU>(0, num_bands__), evec__.template at<GPU>(0, num_bands__), evec__.ld(), n);
            /* move matrix of eigen-vectors to GPU */
            acc::copyin(evec_tmp.template at<GPU>(), evec_tmp.ld(), evec_tmp.template at<CPU>(), evec_tmp.ld(), N__, n);
        }
        #endif

        /* compute H\Psi_{i} = \sum_{mu} H\phi_{mu} * Z_{mu, i} */
        hpsi__.transform_from<T>(hphi__, N__, evec_tmp, n);
        /* compute O\Psi_{i} = \sum_{mu} O\phi_{mu} * Z_{mu, i} */
        opsi__.transform_from<T>(ophi__, N__, evec_tmp, n);

        residuals_aux(kp__, n, eval_tmp, hpsi__, opsi__, res__, h_diag__, o_diag__, res_norm);

        int nmax = n;
        n = 0;
        for (int i = 0; i < nmax; i++)
        {
            /* take the residual if it's norm is above the threshold */
            if (res_norm[i] > itso.residual_tolerance_)
            {
                /* shift unconverged residuals to the beginning of array */
                if (n != i)
                {
                    switch (ctx_.processing_unit())
                    {
                        case CPU:
                        {
                            std::memcpy(&res__(0, n), &res__(0, i), res__.num_gvec_loc() * sizeof(double_complex));
                            break;
                        }
                        case GPU:
                        {
                            #ifdef __GPU
                            acc::copy(res__.coeffs().at<GPU>(0, n), res__.coeffs().at<GPU>(0, i), res__.num_gvec_loc());
                            #else
                            TERMINATE_NO_GPU
                            #endif
                            break;
                        }
                    }
                }
                n++;
            }
        }
        #if (__VERBOSITY > 2)
        if (kp__->comm().rank() == 0)
        {
            DUMP("initial and final number of residuals : %i %i", nmax, n);
        }
        #endif
    }
    else
    {
        /* compute H\Psi_{i} = \sum_{mu} H\phi_{mu} * Z_{mu, i} */
        hpsi__.transform_from<T>(hphi__, N__, evec__, num_bands__);
        /* compute O\Psi_{i} = \sum_{mu} O\phi_{mu} * Z_{mu, i} */
        opsi__.transform_from<T>(ophi__, N__, evec__, num_bands__);

        residuals_aux(kp__, num_bands__, eval__, hpsi__, opsi__, res__, h_diag__, o_diag__, res_norm);

        for (int i = 0; i < num_bands__; i++)
        {
            bool take_res = true;
            if (itso.converge_occupied_ && kp__->band_occupancy(i + ispn__ * ctx_.num_fv_states()) < 1e-10) take_res = false;

            /* take the residual if it's norm is above the threshold */
            if (take_res && res_norm[i] > itso.residual_tolerance_)
            {
                /* shift unconverged residuals to the beginning of array */
                if (n != i)
                {
                    switch (ctx_.processing_unit())
                    {
                        case CPU:
                        {
                            std::memcpy(&res__(0, n), &res__(0, i), res__.num_gvec_loc() * sizeof(double_complex));
                            break;
                        }
                        case GPU:
                        {
                            #ifdef __GPU
                            acc::copy(res__.coeffs().at<GPU>(0, n), res__.coeffs().at<GPU>(0, i), res__.num_gvec_loc());
                            #else
                            TERMINATE_NO_GPU
                            #endif
                            break;
                        }
                    }
                }
                n++;
            }
        }
    }

    return n;
}

template int Band::residuals<double_complex>(K_point* kp__,
                                             int ispn__,
                                             int N__,
                                             int num_bands__,
                                             std::vector<double>& eval__,
                                             std::vector<double>& eval_old__,
                                             matrix<double_complex>& evec__,
                                             Wave_functions<false>& hphi__,
                                             Wave_functions<false>& ophi__,
                                             Wave_functions<false>& hpsi__,
                                             Wave_functions<false>& opsi__,
                                             Wave_functions<false>& res__,
                                             std::vector<double>& h_diag__,
                                             std::vector<double>& o_diag__);

template int Band::residuals<double>(K_point* kp__,
                                     int ispn__,
                                     int N__,
                                     int num_bands__,
                                     std::vector<double>& eval__,
                                     std::vector<double>& eval_old__,
                                     matrix<double>& evec__,
                                     Wave_functions<false>& hphi__,
                                     Wave_functions<false>& ophi__,
                                     Wave_functions<false>& hpsi__,
                                     Wave_functions<false>& opsi__,
                                     Wave_functions<false>& res__,
                                     std::vector<double>& h_diag__,
                                     std::vector<double>& o_diag__);

};
<commit_msg>try to orthogonalize<commit_after>#include "band.h"

namespace sirius {

template <typename T>
int Band::residuals(K_point* kp__,
                    int ispn__,
                    int N__,
                    int num_bands__,
                    std::vector<double>& eval__,
                    std::vector<double>& eval_old__,
                    matrix<T>& evec__,
                    Wave_functions<false>& hphi__,
                    Wave_functions<false>& ophi__,
                    Wave_functions<false>& hpsi__,
                    Wave_functions<false>& opsi__,
                    Wave_functions<false>& res__,
                    std::vector<double>& h_diag__,
                    std::vector<double>& o_diag__)
{
    PROFILE_WITH_TIMER("sirius::Band::residuals");

    auto& itso = ctx_.iterative_solver_input_section();
    bool converge_by_energy = (itso.converge_by_energy_ == 1);

    /* norm of residuals */
    std::vector<double> res_norm(num_bands__);

    int n = 0;
    if (converge_by_energy)
    {
        std::vector<double> eval_tmp(num_bands__);

        /* main trick here: first estimate energy difference, and only then compute unconverged residuals */
        for (int i = 0; i < num_bands__; i++)
        {
            bool take_res = true;
            if (itso.converge_occupied_ && kp__->band_occupancy(i + ispn__ * ctx_.num_fv_states()) < 1e-10) take_res = false;

            if (take_res && std::abs(eval__[i] - eval_old__[i]) > itso.energy_tolerance_)
            {
                std::memcpy(&evec__(0, num_bands__ + n), &evec__(0, i), N__ * sizeof(T));
                eval_tmp[n++] = eval__[i];
            }
        }
        // TODO: do this on GPU

        /* create alias for eigen-vectors corresponding to unconverged residuals */
        matrix<T> evec_tmp;
        if (ctx_.processing_unit() == CPU)
        {
            evec_tmp = matrix<T>(&evec__(0, num_bands__), evec__.ld(), n);
        }
        #ifdef __GPU
        if (ctx_.processing_unit() == GPU)
        {
            evec_tmp = matrix<T>(evec__.template at<CPU>(0, num_bands__), evec__.template at<GPU>(0, num_bands__), evec__.ld(), n);
            /* move matrix of eigen-vectors to GPU */
            acc::copyin(evec_tmp.template at<GPU>(), evec_tmp.ld(), evec_tmp.template at<CPU>(), evec_tmp.ld(), N__, n);
        }
        #endif

        /* compute H\Psi_{i} = \sum_{mu} H\phi_{mu} * Z_{mu, i} */
        hpsi__.transform_from<T>(hphi__, N__, evec_tmp, n);
        /* compute O\Psi_{i} = \sum_{mu} O\phi_{mu} * Z_{mu, i} */
        opsi__.transform_from<T>(ophi__, N__, evec_tmp, n);

        residuals_aux(kp__, n, eval_tmp, hpsi__, opsi__, res__, h_diag__, o_diag__, res_norm);

        int nmax = n;
        n = 0;
        for (int i = 0; i < nmax; i++)
        {
            /* take the residual if it's norm is above the threshold */
            if (res_norm[i] > itso.residual_tolerance_)
            {
                /* shift unconverged residuals to the beginning of array */
                if (n != i)
                {
                    switch (ctx_.processing_unit())
                    {
                        case CPU:
                        {
                            std::memcpy(&res__(0, n), &res__(0, i), res__.num_gvec_loc() * sizeof(double_complex));
                            break;
                        }
                        case GPU:
                        {
                            #ifdef __GPU
                            acc::copy(res__.coeffs().at<GPU>(0, n), res__.coeffs().at<GPU>(0, i), res__.num_gvec_loc());
                            #else
                            TERMINATE_NO_GPU
                            #endif
                            break;
                        }
                    }
                }
                n++;
            }
        }
        #if (__VERBOSITY > 2)
        if (kp__->comm().rank() == 0)
        {
            DUMP("initial and final number of residuals : %i %i", nmax, n);
        }
        #endif
    }
    else
    {
        /* compute H\Psi_{i} = \sum_{mu} H\phi_{mu} * Z_{mu, i} */
        hpsi__.transform_from<T>(hphi__, N__, evec__, num_bands__);
        /* compute O\Psi_{i} = \sum_{mu} O\phi_{mu} * Z_{mu, i} */
        opsi__.transform_from<T>(ophi__, N__, evec__, num_bands__);

        residuals_aux(kp__, num_bands__, eval__, hpsi__, opsi__, res__, h_diag__, o_diag__, res_norm);

        for (int i = 0; i < num_bands__; i++)
        {
            bool take_res = true;
            if (itso.converge_occupied_ && kp__->band_occupancy(i + ispn__ * ctx_.num_fv_states()) < 1e-10) take_res = false;

            /* take the residual if it's norm is above the threshold */
            if (take_res && res_norm[i] > itso.residual_tolerance_)
            {
                /* shift unconverged residuals to the beginning of array */
                if (n != i)
                {
                    switch (ctx_.processing_unit())
                    {
                        case CPU:
                        {
                            std::memcpy(&res__(0, n), &res__(0, i), res__.num_gvec_loc() * sizeof(double_complex));
                            break;
                        }
                        case GPU:
                        {
                            #ifdef __GPU
                            acc::copy(res__.coeffs().at<GPU>(0, n), res__.coeffs().at<GPU>(0, i), res__.num_gvec_loc());
                            #else
                            TERMINATE_NO_GPU
                            #endif
                            break;
                        }
                    }
                }
                n++;
            }
        }
    }

    return n;
}

template <>
int Band::orthogonalize<double_complex>(K_point* kp__,
                                        int N__,
                                        int n__,
                                        Wave_functions<false>& phi__,
                                        Wave_functions<false>& res__)
{
    return n__;
}

template <>
int Band::orthogonalize<double>(K_point* kp__,
                                int N__,
                                int n__,
                                Wave_functions<false>& phi__,
                                Wave_functions<false>& res__)
{
    //return n__;

    /* { phi_i, i in [0, N) }
       { res_i, i in [0, n) }

       take res_0, orthogonalize to all phi, check norm, accept or rejec
       take res_1, orthogonalize to all phi and res_0, check norm, accept or rejec

    */

    auto inner = [kp__](double_complex* f, double_complex* g)
    {
        double prod = 0;
        for (int igk = 0; igk < kp__->num_gkvec_loc(); igk++)
                prod += 2.0 * (f[igk].real() * g[igk].real() + f[igk].imag() * g[igk].imag());
        prod -= f[0].real() * g[0].real();
        return prod;
    };

    int n = 0;
    /* loop over all available residuals */
    for (int i = 0; i < n__; i++)
    {
        if (i != n) std::memcpy(&res__(0, n), &res__(0, i), kp__->num_gkvec_loc() * sizeof(double_complex));

        /*loop over current basis */
        for (int j = 0; j < N__; j++)
        {
            double prod = inner(&phi__(0, j), &res__(0, n));

            for (int igk = 0; igk < kp__->num_gkvec_loc(); igk++)
                res__(igk, n) -= prod * phi__(igk, j);
        }

        for (int j = 0; j < n; j++)
        {
            double prod = inner(&res__(0, j), &res__(0, n));

            for (int igk = 0; igk < kp__->num_gkvec_loc(); igk++)
                res__(igk, n) -= prod * res__(igk, j);
        }
        double norm = inner(&res__(0, n), &res__(0, n));

        if (std::abs(norm) > 0.01)
        {
            norm = 1.0 / std::sqrt(norm);
            for (int igk = 0; igk < kp__->num_gkvec_loc(); igk++)
                res__(igk, n) *= norm;
            n++;
        }
    }

    printf("initial and final number of residuals: %i %i\n", n__, n);

    return n;
}

template int Band::residuals<double_complex>(K_point* kp__,
                                             int ispn__,
                                             int N__,
                                             int num_bands__,
                                             std::vector<double>& eval__,
                                             std::vector<double>& eval_old__,
                                             matrix<double_complex>& evec__,
                                             Wave_functions<false>& hphi__,
                                             Wave_functions<false>& ophi__,
                                             Wave_functions<false>& hpsi__,
                                             Wave_functions<false>& opsi__,
                                             Wave_functions<false>& res__,
                                             std::vector<double>& h_diag__,
                                             std::vector<double>& o_diag__);

template int Band::residuals<double>(K_point* kp__,
                                     int ispn__,
                                     int N__,
                                     int num_bands__,
                                     std::vector<double>& eval__,
                                     std::vector<double>& eval_old__,
                                     matrix<double>& evec__,
                                     Wave_functions<false>& hphi__,
                                     Wave_functions<false>& ophi__,
                                     Wave_functions<false>& hpsi__,
                                     Wave_functions<false>& opsi__,
                                     Wave_functions<false>& res__,
                                     std::vector<double>& h_diag__,
                                     std::vector<double>& o_diag__);

//template int Band::orthogonalize<double_complex>(K_point* kp__,
//                                                 int N__,
//                                                 int n__,
//                                                 Wave_functions<false>& phi__,
//                                                 Wave_functions<false>& res__);
//
//template int Band::orthogonalize<double>(K_point* kp__,
//                                         int N__,
//                                         int n__,
//                                         Wave_functions<false>& phi__,
//                                         Wave_functions<false>& res__);
};
<|endoftext|>


<commit_before>// $Id$
AliAnalysisTaskSAJF* AddTaskEmcalJets_pPb_Eliane(
   const char *nRhosCh        = "rhoCh",
   const char *nRhosChEm      = "rhoChEm",
   const char *nRhosEm        = "rhoEm",
   const Double_t scale       = 1.0,
   const Double_t radius      = 0.2,
   const char* usedTracks     = "PicoTracks",
   const char* outClusName    = "caloClustersCorr",
   const Double_t minTrackPt  = 0.15,
   const Double_t minClusterPt = 0.30,
   const char *CentEst         = "V0A"
)
{

	//>>  This task calls a jet finder (EMCal Jet) and then analyzes the jet with an analyzer ()

	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
	//
	//    Run the jet finder (general tasks)
    //
	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
	gROOT->LoadMacro("$ALICE_PHYSICS/PWGJE/EMCALJetTasks/macros/AddTaskEmcalJet.C");

    //hard coded variables for the jet finder
	const Int_t RecScheme  =1;         //RecombinationScheme: 0=E_scheme, 1=pt_scheme
	const Double_t minJetPt    = 0.1;  // is supposed to make the jet analysis faster as the jet container don't get so big

	// Some constants for the jet finders
	const Int_t cKT                 = 0;
	const Int_t cANTIKT             = 1;
	const Int_t cFULLJETS           = 0;
	const Int_t cCHARGEDJETS        = 1;
	const Int_t cNEUTRALJETS        = 2;

	char *typeTPC                = "TPC";
	char *typeEMC                = "EMC";

     //probably not needed SA task uses 0.6 and the radius fed into the jet finder
	//float AreaCut = 0.6*radius*radius*TMath::Pi();

	TString nJets("");

   // Here are the jet finders
	AliEmcalJetTask* jetFinderTask = AddTaskEmcalJet(AliEmcalJetTask::kAKT | AliEmcalJetTask::kFullJet,usedTracks,outClusName,minTrackPt,minClusterPt,0.005,radius,RecScheme,"Jet",minJetPt);
	//const UInt_t type           = AliEmcalJetTask::kAKT | AliEmcalJetTask::kFullJet | AliEmcalJetTask::kR040Jet,
	//but the last info should match the "radius" info,
	//I don'T know if this is checked within the code to avoide confusion
	nJets=jetFinderTask->GetName();

	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
	//
	//    Run the rho tasks (general tasks)
    //
	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
	gROOT->LoadMacro("$ALICE_PHYSICS/PWGJE/EMCALJetTasks/macros/AddTaskRhoSparse.C");

	TF1 *sfunc=new TF1("sfunc","[0]*x*x+[1]*x+[2]",-1,100);
	sfunc->SetParameter(0,0.0);
	sfunc->SetParameter(1,0.0);
	sfunc->SetParameter(2,scale);

	TString scaledname(Form("%s_Scaled", nRhosCh));
	TString newrhoname(Form("%s_All", nRhosCh));
	//TString scaledname(Form("%s_Scaled", newrhoname));

//	AliAnalysisTaskRhoSparse *rhochtask = AddTaskRhoSparse(jetFinderTaskChBack->GetName(),jetFinderTaskChSig->GetName(),usedTracks,outClusName,nRhosCh,radius,typeTPC,0.01,0,0,sfunc,0,kTRUE,nRhosCh);
//	rhochtask->SetCentralityEstimator(CentEst);

//	AliAnalysisTaskRhoSparse *rhochalltask = AddTaskRhoSparse(jetFinderTaskChBackall->GetName(),jetFinderTaskChSig->GetName(),usedTracks,outClusName,newrhoname,radius,0,0.0,0,0,sfunc,0,kTRUE,newrhoname);
//	rhochtask->SetCentralityEstimator(CentEst);

//	AliAnalysisTaskRhoSparse *rhochemtask = AddTaskRhoSparse(jetFinderTaskChEmBack->GetName(),jetFinderTask->GetName(),usedTracks,outClusName,nRhosChEm,radius,typeEMC,0.01,0,0,0,0,kTRUE,nRhosChEm);
//	rhochemtask->SetCentralityEstimator(CentEst);

	/*
	--->>	no idea what that is about

		gROOT->LoadMacro("$ALICE_PHYSICS/PWGJE/EMCALJetTasks/macros/AddTaskDeltaPt.C");

		TString deltaname(Form("DeltaPt_%s_Scaled", nRhosCh));
		AliAnalysisTaskDeltaPt* deltapt = AddTaskDeltaPt(usedTracks,outClusName,nJets,"","","","","",scaledname,radius,AreaCut,minTrackPt,minClusterPt,typeEMC,deltaname);
		deltapt->SetCentralityEstimator(CentEst);

		TString chdeltaname(Form("DeltaPt_%s", nRhosCh));
		AliAnalysisTaskDeltaPt* deltaptch = AddTaskDeltaPt(usedTracks,"",nJetsCh,"","","","","",nRhosCh,radius,AreaCut,minTrackPt,minClusterPt,typeTPC,chdeltaname);
		deltaptch->SetCentralityEstimator(CentEst);

		TString emcdeltaname(Form("DeltaPt_%s", nRhosChEm));
		AliAnalysisTaskDeltaPt* deltaptEMC = AddTaskDeltaPt(usedTracks,outClusName,nJets,"","","","","",nRhosChEm,radius,AreaCut,minTrackPt,minClusterPt,typeEMC,emcdeltaname);
		deltaptEMC->SetCentralityEstimator(CentEst);

		gROOT->LoadMacro("$ALICE_PHYSICS/PWGJE/EMCALJetTasks/macros/AddTaskScale.C");

		Int_t radlabel=(Int_t)floor(radius*100+0.5);
		Int_t mincluslabel=(Int_t)floor(minClusterPt*1000+0.5);
		Int_t mintracklabel=(Int_t)floor(minTrackPt*1000+0.5);
		TString scalename(Form("Scale_R0%d", radlabel));

		AliAnalysisTaskScale* scaletask = AddTaskScale(usedTracks,outClusName,minTrackPt,minClusterPt,scalename);
		scaletask->SetCentralityEstimator(CentEst);
		scaletask->SetScaleFunction(sfunc);
	 */
	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
	//
	//    Run the jet analyzer (personal task)
	//
	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    //create the according class object for the Taks
	gROOT->LoadMacro("$ALICE_PHYSICS/PWGJE/EMCALJetTasks/macros/AddTaskSAJF.C");
	AliAnalysisTaskSAJF* JetAnalysisEliane = AddTaskSAJF(usedTracks,outClusName,jetFinderTask->GetName(),"",radius,1.0,0.6,"EMCAL",0,"EmcalJets_pPb_Eliane");

	//That might be important!!
	//spectratask->SetCentralityEstimator(CentEst);

	//what is the scalefactor about
	//--->> I need to add the correct centrality estimator!! spectratask->SetCentralityEstimator(CentEst);
    //where is fNcentBins defined?  ali analysistask emcal  0-10, 10-30, 30-50

	return JetAnalysisEliane;
}
<commit_msg>some updates on the Jet Task from Eliane<commit_after>// $Id$
AliAnalysisTaskSAJF* AddTaskEmcalJets_pPb_Eliane(
   const char *nRhosCh        = "rhoCh",
   const char *nRhosChEm      = "rhoChEm",
   const char *nRhosEm        = "rhoEm",
   const Double_t scale       = 1.0,
   const Double_t radius      = 0.2,
   const char* usedTracks     = "PicoTracks",
   const char* outClusName    = "caloClustersCorr",
   const Double_t minTrackPt  = 0.15,
   const Double_t minClusterPt = 0.30,
   const char *CentEst         = "V0A"
)
{

	//>>  This task calls a jet finder (EMCal Jet) and then analyzes the jet with an analyzer ()

	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
	//
	//    Run the jet finder (general tasks)
    //
	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
	gROOT->LoadMacro("$ALICE_PHYSICS/PWGJE/EMCALJetTasks/macros/AddTaskEmcalJet.C");

    //hard coded variables for the jet finder
	const Int_t RecScheme  =1;         //RecombinationScheme: 0=E_scheme, 1=pt_scheme
	const Double_t minJetPt    = 0.1;  // is supposed to make the jet analysis faster as the jet container don't get so big

	// Some constants for the jet finders
	const Int_t cKT                 = 0;
	const Int_t cANTIKT             = 1;
	const Int_t cFULLJETS           = 0;
	const Int_t cCHARGEDJETS        = 1;
	const Int_t cNEUTRALJETS        = 2;

	char *typeTPC                = "TPC";
	char *typeEMC                = "EMC";

     //probably not needed SA task uses 0.6 and the radius fed into the jet finder
	//float AreaCut = 0.6*radius*radius*TMath::Pi();

	TString nJets("");

   // Here are the jet finders
	AliEmcalJetTask* jetFinderTask = AddTaskEmcalJet(AliEmcalJetTask::kAKT | AliEmcalJetTask::kFullJet,usedTracks,outClusName,minTrackPt,minClusterPt,0.005,radius,RecScheme,"Jet",minJetPt);
	//const UInt_t type           = AliEmcalJetTask::kAKT | AliEmcalJetTask::kFullJet | AliEmcalJetTask::kR040Jet,
	//but the last info should match the "radius" info,
	//I don't know if this is checked within the code to avoide confusion
	nJets=jetFinderTask->GetName();

	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
	//
	//    Run the rho tasks (general tasks)
    //
	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
	gROOT->LoadMacro("$ALICE_PHYSICS/PWGJE/EMCALJetTasks/macros/AddTaskRhoSparse.C");

	TF1 *sfunc=new TF1("sfunc","[0]*x*x+[1]*x+[2]",-1,100);
	sfunc->SetParameter(0,0.0);
	sfunc->SetParameter(1,0.0);
	sfunc->SetParameter(2,scale);

	TString scaledname(Form("%s_Scaled", nRhosCh));
	TString newrhoname(Form("%s_All", nRhosCh));
	//TString scaledname(Form("%s_Scaled", newrhoname));

//	AliAnalysisTaskRhoSparse *rhochtask = AddTaskRhoSparse(jetFinderTaskChBack->GetName(),jetFinderTaskChSig->GetName(),usedTracks,outClusName,nRhosCh,radius,typeTPC,0.01,0,0,sfunc,0,kTRUE,nRhosCh);
//	rhochtask->SetCentralityEstimator(CentEst);

//	AliAnalysisTaskRhoSparse *rhochalltask = AddTaskRhoSparse(jetFinderTaskChBackall->GetName(),jetFinderTaskChSig->GetName(),usedTracks,outClusName,newrhoname,radius,0,0.0,0,0,sfunc,0,kTRUE,newrhoname);
//	rhochtask->SetCentralityEstimator(CentEst);

//	AliAnalysisTaskRhoSparse *rhochemtask = AddTaskRhoSparse(jetFinderTaskChEmBack->GetName(),jetFinderTask->GetName(),usedTracks,outClusName,nRhosChEm,radius,typeEMC,0.01,0,0,0,0,kTRUE,nRhosChEm);
//	rhochemtask->SetCentralityEstimator(CentEst);

	/*
	--->>	no idea what that is about

		gROOT->LoadMacro("$ALICE_PHYSICS/PWGJE/EMCALJetTasks/macros/AddTaskDeltaPt.C");

		TString deltaname(Form("DeltaPt_%s_Scaled", nRhosCh));
		AliAnalysisTaskDeltaPt* deltapt = AddTaskDeltaPt(usedTracks,outClusName,nJets,"","","","","",scaledname,radius,AreaCut,minTrackPt,minClusterPt,typeEMC,deltaname);
		deltapt->SetCentralityEstimator(CentEst);

		TString chdeltaname(Form("DeltaPt_%s", nRhosCh));
		AliAnalysisTaskDeltaPt* deltaptch = AddTaskDeltaPt(usedTracks,"",nJetsCh,"","","","","",nRhosCh,radius,AreaCut,minTrackPt,minClusterPt,typeTPC,chdeltaname);
		deltaptch->SetCentralityEstimator(CentEst);

		TString emcdeltaname(Form("DeltaPt_%s", nRhosChEm));
		AliAnalysisTaskDeltaPt* deltaptEMC = AddTaskDeltaPt(usedTracks,outClusName,nJets,"","","","","",nRhosChEm,radius,AreaCut,minTrackPt,minClusterPt,typeEMC,emcdeltaname);
		deltaptEMC->SetCentralityEstimator(CentEst);

		gROOT->LoadMacro("$ALICE_PHYSICS/PWGJE/EMCALJetTasks/macros/AddTaskScale.C");

		Int_t radlabel=(Int_t)floor(radius*100+0.5);
		Int_t mincluslabel=(Int_t)floor(minClusterPt*1000+0.5);
		Int_t mintracklabel=(Int_t)floor(minTrackPt*1000+0.5);
		TString scalename(Form("Scale_R0%d", radlabel));

		AliAnalysisTaskScale* scaletask = AddTaskScale(usedTracks,outClusName,minTrackPt,minClusterPt,scalename);
		scaletask->SetCentralityEstimator(CentEst);
		scaletask->SetScaleFunction(sfunc);
	 */
	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
	//
	//    Run the jet analyzer (personal task)
	//
	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    //create the according class object for the Taks
	gROOT->LoadMacro("$ALICE_PHYSICS/PWGJE/EMCALJetTasks/macros/AddTaskSAJF.C");
	AliAnalysisTaskSAJF* JetAnalysisEliane = AddTaskSAJF(usedTracks,outClusName,jetFinderTask->GetName(),"",radius,1.0,0.6,"EMCAL",0,"EmcalJets_pPb_Eliane");

	//That might be important!!
	//spectratask->SetCentralityEstimator(CentEst);

	//what is the scalefactor about
	//--->> I need to add the correct centrality estimator!! spectratask->SetCentralityEstimator(CentEst);
    //where is fNcentBins defined?  ali analysistask emcal  0-10, 10-30, 30-50

	return JetAnalysisEliane;
}
<|endoftext|>