<commit_before>/*
 * This is part of the FL library, a C++ Bayesian filtering library
 * (https://github.com/filtering-library)
 *
 * Copyright (c) 2014 Jan Issac (jan.issac@gmail.com)
 * Copyright (c) 2014 Manuel Wuthrich (manuel.wuthrich@gmail.com)
 *
 * Max-Planck Institute for Intelligent Systems, AMD Lab
 * University of Southern California, CLMC Lab
 *
 * This Source Code Form is subject to the terms of the MIT License (MIT).
 * A copy of the license can be found in the LICENSE file distributed with this
 * source code.
 */

/**
 * \file linear_observation_model_test.hpp
 * \date October 2014
 * \author Jan Issac (jan.issac@gmail.com)
 */

#include <gtest/gtest.h>

#include <Eigen/Dense>

#include <cmath>
#include <iostream>

#include <fl/util/types.hpp>
#include <fl/model/observation/linear_observation_model.hpp>

class LinearObservationModelTests:
    public testing::Test
{
public:
    enum: signed int
    {
        ObsrvDim = 20,
        StateDim = 10
    };

    typedef Eigen::Matrix<fl::Real, StateDim, 1> State;
    typedef Eigen::Matrix<fl::Real, ObsrvDim, 1> Obsrv;
    typedef fl::LinearObservationModel<Obsrv, State> LinearModel;

    typedef Eigen::Matrix<fl::Real, Eigen::Dynamic, 1> StateX;
    typedef Eigen::Matrix<fl::Real, Eigen::Dynamic, 1> ObsrvX;
    typedef fl::LinearObservationModel<ObsrvX, StateX> LinearModelX;

    typedef typename LinearModel::Noise Noise;
    typedef typename LinearModelX::Noise NoiseX;

    template <typename Model>
    void init_dimension_test(Model&& model)
    {
        EXPECT_EQ(model.obsrv_dimension(), ObsrvDim);
        EXPECT_EQ(model.noise_dimension(), ObsrvDim);
        EXPECT_EQ(model.state_dimension(), StateDim);

        EXPECT_EQ(model.sensor_matrix().rows(), ObsrvDim);
        EXPECT_EQ(model.sensor_matrix().cols(), StateDim);

        EXPECT_EQ(model.noise_matrix().rows(), ObsrvDim);
        EXPECT_EQ(model.noise_matrix().cols(), ObsrvDim);
    }

    template <typename Model>
    void init_sensor_matrix_value_test(Model&& model)
    {
        EXPECT_TRUE(model.sensor_matrix().isIdentity());
    }

    template <typename Model>
    void init_noise_matrix_value_test(Model&& model)
    {
        EXPECT_TRUE(model.noise_matrix().isIdentity());
    }

    template <typename Model>
    void sensor_matrix_value_test(Model&& model)
    {
        auto sensor_matrix = model.create_sensor_matrix();
        sensor_matrix.setRandom();
        model.sensor_matrix(sensor_matrix);
        EXPECT_TRUE(fl::are_similar(model.sensor_matrix(), sensor_matrix));
    }

    template <typename Model>
    void noise_matrix_value_test(Model&& model)
    {
        auto noise_matrix = model.create_noise_matrix();
        noise_matrix.setRandom();
        model.noise_matrix(noise_matrix);
        EXPECT_TRUE(fl::are_similar(model.noise_matrix(), noise_matrix));
    }

    template <typename Model>
    void expected_observation_test(Model&& model)
    {
        auto x = State(model.state_dimension());
        auto y = Obsrv(model.obsrv_dimension());

        x.setRandom();
        y.topRows(model.state_dimension()) = x;

        EXPECT_TRUE(fl::are_similar(model.expected_observation(x), y));
    }

    template <typename Model>
    void observation_with_zero_noise_test(Model&& model)
    {
        auto x = State(model.state_dimension());
        auto y = Obsrv(model.obsrv_dimension());
        auto v = Noise(model.noise_dimension());

        x.setRandom();
        v.setZero();
        y.topRows(model.state_dimension()) = x;

        EXPECT_TRUE(fl::are_similar(model.observation(x, v), y));
    }

    template <typename Model>
    void observation_test(Model&& model)
    {
        auto x = State(model.state_dimension());
        auto y = Obsrv(model.obsrv_dimension());
        auto v = Noise(model.noise_dimension());

        x.setRandom();
        v.setRandom();
        y.topRows(model.state_dimension()) = x;
        y += v;

        EXPECT_TRUE(fl::are_similar(model.observation(x, v), y));
    }
};

// == Initial dimension tests =============================================== //

TEST_F(LinearObservationModelTests, init_fixed_dimension)
{
    init_dimension_test(LinearModel());
}

TEST_F(LinearObservationModelTests, init_fixed_dimension_dynamic_constr)
{
    init_dimension_test(LinearModel(ObsrvDim, StateDim));
}

TEST_F(LinearObservationModelTests, init_dynamic_dimension)
{
    init_dimension_test(LinearModelX(ObsrvDim, StateDim));
}

// == Initial sensor matrix tests =========================================== //

TEST_F(LinearObservationModelTests, init_fixed_sensor_matrix_value)
{
    init_sensor_matrix_value_test(LinearModel());
}

TEST_F(LinearObservationModelTests, init_fixed_sensor_matrix_value_dynamic_constr)
{
    init_sensor_matrix_value_test(LinearModel(ObsrvDim, StateDim));
}

TEST_F(LinearObservationModelTests, init_dynamic_sensor_matrix_value)
{
    init_sensor_matrix_value_test(LinearModelX(ObsrvDim, StateDim));
}

// == Initial noise matrix tests ============================================ //

TEST_F(LinearObservationModelTests, init_fixed_noise_matrix_value)
{
    init_noise_matrix_value_test(LinearModel());
}

TEST_F(LinearObservationModelTests, init_fixed_noise_matrix_value_dynamic_constr)
{
    init_noise_matrix_value_test(LinearModel(ObsrvDim, StateDim));
}

TEST_F(LinearObservationModelTests, init_dynamic_noise_matrix_value)
{
    init_noise_matrix_value_test(LinearModelX(ObsrvDim, StateDim));
}

// == Sensor matrix tests =================================================== //

TEST_F(LinearObservationModelTests, sensor_matrix_fixed)
{
    sensor_matrix_value_test(LinearModel());
}

TEST_F(LinearObservationModelTests, sensor_matrix_fixed_dynamic_constr)
{
    sensor_matrix_value_test(LinearModel(ObsrvDim, StateDim));
}

TEST_F(LinearObservationModelTests, sensor_matrix_dynamic)
{
    sensor_matrix_value_test(LinearModelX(ObsrvDim, StateDim));
}

// == Noise matrix tests ==================================================== //

TEST_F(LinearObservationModelTests, noise_matrix_fixed)
{
    noise_matrix_value_test(LinearModel());
}

TEST_F(LinearObservationModelTests, noise_matrix_fixed_dynamic_constr)
{
    noise_matrix_value_test(LinearModel(ObsrvDim, StateDim));
}

TEST_F(LinearObservationModelTests, noise_matrix_dynamic)
{
    noise_matrix_value_test(LinearModelX(ObsrvDim, StateDim));
}

// == expected_observation ================================================== //

TEST_F(LinearObservationModelTests, expected_observation_fixed)
{
    expected_observation_test(LinearModel());
}

TEST_F(LinearObservationModelTests, expected_observation_dynamic_constr)
{
    expected_observation_test(LinearModel(ObsrvDim, StateDim));
}

TEST_F(LinearObservationModelTests, expected_observation_dynamic)
{
    expected_observation_test(LinearModelX(ObsrvDim, StateDim));
}

// == observation with zero noise =========================================== //

TEST_F(LinearObservationModelTests, observation_with_zero_noise_fixed)
{
    observation_with_zero_noise_test(LinearModel());
}

TEST_F(LinearObservationModelTests, observation_with_zero_noise_dynamic_constr)
{
    observation_with_zero_noise_test(LinearModel(ObsrvDim, StateDim));
}

TEST_F(LinearObservationModelTests, observation_with_zero_noise_dynamic)
{
    observation_with_zero_noise_test(LinearModelX(ObsrvDim, StateDim));
}

// == observation =========================================================== //

TEST_F(LinearObservationModelTests, observation_fixed)
{
    observation_test(LinearModel());
}

TEST_F(LinearObservationModelTests, observation_dynamic_constr)
{
    observation_test(LinearModel(ObsrvDim, StateDim));
}

TEST_F(LinearObservationModelTests, observation_dynamic)
{
    observation_test(LinearModelX(ObsrvDim, StateDim));
}

/// \todo missing probability and log_probability tests
<commit_msg>Transformed unit test to a typed test for static and dynamic memory allocation testing<commit_after>/*
 * This is part of the FL library, a C++ Bayesian filtering library
 * (https://github.com/filtering-library)
 *
 * Copyright (c) 2014 Jan Issac (jan.issac@gmail.com)
 * Copyright (c) 2014 Manuel Wuthrich (manuel.wuthrich@gmail.com)
 *
 * Max-Planck Institute for Intelligent Systems, AMD Lab
 * University of Southern California, CLMC Lab
 *
 * This Source Code Form is subject to the terms of the MIT License (MIT).
 * A copy of the license can be found in the LICENSE file distributed with this
 * source code.
 */

/**
 * \file linear_observation_model_test.hpp
 * \date October 2014
 * \author Jan Issac (jan.issac@gmail.com)
 */

#include <gtest/gtest.h>
#include "../../typecast.hpp"

#include <Eigen/Dense>

#include <cmath>
#include <iostream>

#include <fl/util/types.hpp>
#include <fl/model/observation/linear_observation_model.hpp>

template <typename TestType>
class LinearObservationModelTest:
    public testing::Test
{
public:
    enum: signed int
    {
        StateDim = 10,
        ObsrvDim = 20,

        StateSize = fl::TestSize<StateDim, TestType>::Value,
        ObsrvSize = fl::TestSize<ObsrvDim, TestType>::Value
    };

    typedef Eigen::Matrix<fl::Real, StateSize, 1> State;
    typedef Eigen::Matrix<fl::Real, ObsrvSize, 1> Obsrv;
    typedef fl::LinearObservationModel<Obsrv, State> LinearModel;

    typedef typename LinearModel::Noise Noise;

    LinearObservationModelTest()
        : model(LinearModel(ObsrvDim, StateDim))
    { }

    void init_dimension_test()
    {
        EXPECT_EQ(model.obsrv_dimension(), ObsrvDim);
        EXPECT_EQ(model.noise_dimension(), ObsrvDim);
        EXPECT_EQ(model.state_dimension(), StateDim);

        EXPECT_EQ(model.sensor_matrix().rows(), ObsrvDim);
        EXPECT_EQ(model.sensor_matrix().cols(), StateDim);

        EXPECT_EQ(model.noise_matrix().rows(), ObsrvDim);
        EXPECT_EQ(model.noise_matrix().cols(), ObsrvDim);
    }

    void init_sensor_matrix_value_test()
    {
        EXPECT_TRUE(model.sensor_matrix().isIdentity());
    }

    void init_noise_matrix_value_test()
    {
        EXPECT_TRUE(model.noise_matrix().isIdentity());
    }

    void sensor_matrix_value_test()
    {
        auto sensor_matrix = model.create_sensor_matrix();
        sensor_matrix.setRandom();
        model.sensor_matrix(sensor_matrix);
        EXPECT_TRUE(fl::are_similar(model.sensor_matrix(), sensor_matrix));
    }

    void noise_matrix_value_test()
    {
        auto noise_matrix = model.create_noise_matrix();
        noise_matrix.setRandom();
        model.noise_matrix(noise_matrix);
        EXPECT_TRUE(fl::are_similar(model.noise_matrix(), noise_matrix));
    }

    void expected_observation_test()
    {
        auto x = State(model.state_dimension());
        auto y = Obsrv(model.obsrv_dimension());

        x.setRandom();
        y.setZero();
        y.topRows(model.state_dimension()) = x;

        EXPECT_TRUE(fl::are_similar(model.expected_observation(x), y));
    }

    void observation_with_zero_noise_test()
    {
        auto x = State(model.state_dimension());
        auto y = Obsrv(model.obsrv_dimension());
        auto v = Noise(model.noise_dimension());

        x.setRandom();
        v.setZero();
        y.setZero();
        y.topRows(model.state_dimension()) = x;

        EXPECT_TRUE(fl::are_similar(model.observation(x, v), y));
    }

    void observation_test()
    {
        auto x = State(model.state_dimension());
        auto y = Obsrv(model.obsrv_dimension());
        auto v = Noise(model.noise_dimension());

        x.setRandom();
        v.setRandom();
        y.setZero();
        y.topRows(model.state_dimension()) = x;
        y += v;

        EXPECT_TRUE(fl::are_similar(model.observation(x, v), y));
    }

protected:
    LinearModel model;
};

typedef ::testing::Types<
            fl::StaticTest,
            fl::DynamicTest
        > TestTypes;

TYPED_TEST_CASE(LinearObservationModelTest, TestTypes);

TYPED_TEST(LinearObservationModelTest, init_dimension)
{
    TestFixture::init_dimension_test();
}

TYPED_TEST(LinearObservationModelTest, init_sensor_matrix_value)
{
    TestFixture::init_sensor_matrix_value_test();
}

TYPED_TEST(LinearObservationModelTest, init_noise_matrix_value)
{
    TestFixture::init_noise_matrix_value_test();
}

TYPED_TEST(LinearObservationModelTest, sensor_matrix)
{
    TestFixture::sensor_matrix_value_test();
}

TYPED_TEST(LinearObservationModelTest, noise_matrix)
{
    TestFixture::noise_matrix_value_test();
}

TYPED_TEST(LinearObservationModelTest, expected_observation)
{
    TestFixture::expected_observation_test();
}

TYPED_TEST(LinearObservationModelTest, observation_with_zero_noise)
{
    TestFixture::observation_with_zero_noise_test();
}

TYPED_TEST(LinearObservationModelTest, observation)
{
    TestFixture::observation_test();
}

/// \todo missing probability and log_probability tests
<|endoftext|>


<commit_before>/*=========================================================================
 *
 *  Copyright NumFOCUS
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0.txt
 *
 *  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 "itkMedianImageFilter.h"
#include "itkImageRegionSplitterSlowDimension.h"
#include "itkExtractImageFilter.h"
#include "itkPipeline.h"
#include "itkInputImage.h"
#include "itkOutputImage.h"
#include "itkSupportInputImageTypes.h"
#include "itkRGBPixel.h"
#include "itkRGBToLuminanceImageFilter.h"
#include "itkNumericTraits.h"

template<typename TImage>
int
MedianFilter(itk::wasm::Pipeline & pipeline, const TImage * inputImage)
{
  using ImageType = TImage;

  pipeline.get_option("InputImage")->required();

  using OutputImageType = itk::wasm::OutputImage<ImageType>;
  OutputImageType outputImage;
  pipeline.add_option("OutputImage", outputImage, "The output image")->required();

  unsigned int radius = 1;
  pipeline.add_option("-r,--radius", radius, "Kernel radius in pixels");

  unsigned int maxTotalSplits = 1;
  pipeline.add_option("-m,--max-splits", maxTotalSplits, "Max total processing splits");

  unsigned int split = 1;
  pipeline.add_option("-s,--split", split, "Split to process");

  ITK_WASM_PARSE(pipeline);

  using SmoothingFilterType = itk::MedianImageFilter< ImageType, ImageType >;
  auto smoother = SmoothingFilterType::New();
  smoother->SetInput( inputImage );
  smoother->SetRadius( radius );

  using ROIFilterType = itk::ExtractImageFilter< ImageType, ImageType >;
  auto roiFilter = ROIFilterType::New();
  roiFilter->InPlaceOn();
  if (maxTotalSplits > 1)
  {
    smoother->UpdateOutputInformation();
    using RegionType = typename ImageType::RegionType;
    smoother->UpdateOutputInformation();
    const RegionType largestRegion( smoother->GetOutput()->GetLargestPossibleRegion() );

    using SplitterType = itk::ImageRegionSplitterSlowDimension;
    auto splitter = SplitterType::New();
    const unsigned int numberOfSplits = splitter->GetNumberOfSplits( largestRegion, maxTotalSplits );
    if (split >= numberOfSplits)
    {
      std::cerr << "Error: requested split: " << split << " is outside the number of splits: " << numberOfSplits << std::endl;
      return EXIT_FAILURE;
    }

    RegionType requestedRegion( largestRegion );
    splitter->GetSplit( split, numberOfSplits, requestedRegion );
    roiFilter->SetInput( smoother->GetOutput() );
    roiFilter->SetExtractionRegion( requestedRegion );
    roiFilter->Update();
    outputImage.Set( roiFilter->GetOutput() );
  }
  else
  {
    smoother->Update();
    outputImage.Set( smoother->GetOutput() );
  }

  return EXIT_SUCCESS;
}

template<typename TImage>
class PipelineFunctor
{
public:
  int operator()(itk::wasm::Pipeline & pipeline)
  {
    using ImageType = TImage;

    using InputImageType = itk::wasm::InputImage<ImageType>;
    InputImageType inputImage;
    pipeline.add_option("InputImage", inputImage, "The input image");

    ITK_WASM_PRE_PARSE(pipeline);

    return MedianFilter<ImageType>(pipeline, inputImage.Get());
  }
};

template<unsigned int VDimension>
class PipelineFunctor<itk::Image<itk::RGBPixel<uint8_t>, VDimension>>
{
public:
  int operator()(itk::wasm::Pipeline & pipeline)
  {
    constexpr unsigned int Dimension = VDimension;
    using PixelType = itk::RGBPixel<uint8_t>;
    using ImageType = itk::Image<PixelType, Dimension>;

    using InputImageType = itk::wasm::InputImage<ImageType>;
    InputImageType inputImage;
    pipeline.add_option("InputImage", inputImage, "The input image");

    ITK_WASM_PRE_PARSE(pipeline);

    using ScalarImageType = itk::Image<uint8_t, Dimension>;

    using LuminanceFilterType = itk::RGBToLuminanceImageFilter<ImageType, ScalarImageType>;
    auto luminanceFilter = LuminanceFilterType::New();
    luminanceFilter->SetInput( inputImage.Get() );
    luminanceFilter->Update();

    return MedianFilter<ScalarImageType>(pipeline, luminanceFilter->GetOutput());
  }
};

int main( int argc, char * argv[] )
{
  itk::wasm::Pipeline pipeline("Apply a median filter to an image", argc, argv);

  return itk::wasm::SupportInputImageTypes<PipelineFunctor,
   uint8_t,
   itk::RGBPixel< uint8_t >,
   float>
  ::Dimensions<2U,3U>("InputImage", pipeline);
}
<commit_msg>test(MedianFilterTest): Use SupportInputImageTypesNoVectorImage<commit_after>/*=========================================================================
 *
 *  Copyright NumFOCUS
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0.txt
 *
 *  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 "itkMedianImageFilter.h"
#include "itkImageRegionSplitterSlowDimension.h"
#include "itkExtractImageFilter.h"
#include "itkPipeline.h"
#include "itkInputImage.h"
#include "itkOutputImage.h"
#include "itkSupportInputImageTypesNoVectorImage.h"
#include "itkRGBPixel.h"
#include "itkRGBToLuminanceImageFilter.h"
#include "itkNumericTraits.h"

template<typename TImage>
int
MedianFilter(itk::wasm::Pipeline & pipeline, const TImage * inputImage)
{
  using ImageType = TImage;

  pipeline.get_option("InputImage")->required();

  using OutputImageType = itk::wasm::OutputImage<ImageType>;
  OutputImageType outputImage;
  pipeline.add_option("OutputImage", outputImage, "The output image")->required();

  unsigned int radius = 1;
  pipeline.add_option("-r,--radius", radius, "Kernel radius in pixels");

  unsigned int maxTotalSplits = 1;
  pipeline.add_option("-m,--max-splits", maxTotalSplits, "Max total processing splits");

  unsigned int split = 1;
  pipeline.add_option("-s,--split", split, "Split to process");

  ITK_WASM_PARSE(pipeline);

  using SmoothingFilterType = itk::MedianImageFilter< ImageType, ImageType >;
  auto smoother = SmoothingFilterType::New();
  smoother->SetInput( inputImage );
  smoother->SetRadius( radius );

  using ROIFilterType = itk::ExtractImageFilter< ImageType, ImageType >;
  auto roiFilter = ROIFilterType::New();
  roiFilter->InPlaceOn();
  if (maxTotalSplits > 1)
  {
    smoother->UpdateOutputInformation();
    using RegionType = typename ImageType::RegionType;
    smoother->UpdateOutputInformation();
    const RegionType largestRegion( smoother->GetOutput()->GetLargestPossibleRegion() );

    using SplitterType = itk::ImageRegionSplitterSlowDimension;
    auto splitter = SplitterType::New();
    const unsigned int numberOfSplits = splitter->GetNumberOfSplits( largestRegion, maxTotalSplits );
    if (split >= numberOfSplits)
    {
      std::cerr << "Error: requested split: " << split << " is outside the number of splits: " << numberOfSplits << std::endl;
      return EXIT_FAILURE;
    }

    RegionType requestedRegion( largestRegion );
    splitter->GetSplit( split, numberOfSplits, requestedRegion );
    roiFilter->SetInput( smoother->GetOutput() );
    roiFilter->SetExtractionRegion( requestedRegion );
    roiFilter->Update();
    outputImage.Set( roiFilter->GetOutput() );
  }
  else
  {
    smoother->Update();
    outputImage.Set( smoother->GetOutput() );
  }

  return EXIT_SUCCESS;
}

template<typename TImage>
class PipelineFunctor
{
public:
  int operator()(itk::wasm::Pipeline & pipeline)
  {
    using ImageType = TImage;

    using InputImageType = itk::wasm::InputImage<ImageType>;
    InputImageType inputImage;
    pipeline.add_option("InputImage", inputImage, "The input image");

    ITK_WASM_PRE_PARSE(pipeline);

    return MedianFilter<ImageType>(pipeline, inputImage.Get());
  }
};

template<unsigned int VDimension>
class PipelineFunctor<itk::Image<itk::RGBPixel<uint8_t>, VDimension>>
{
public:
  int operator()(itk::wasm::Pipeline & pipeline)
  {
    constexpr unsigned int Dimension = VDimension;
    using PixelType = itk::RGBPixel<uint8_t>;
    using ImageType = itk::Image<PixelType, Dimension>;

    using InputImageType = itk::wasm::InputImage<ImageType>;
    InputImageType inputImage;
    pipeline.add_option("InputImage", inputImage, "The input image");

    ITK_WASM_PRE_PARSE(pipeline);

    using ScalarImageType = itk::Image<uint8_t, Dimension>;

    using LuminanceFilterType = itk::RGBToLuminanceImageFilter<ImageType, ScalarImageType>;
    auto luminanceFilter = LuminanceFilterType::New();
    luminanceFilter->SetInput( inputImage.Get() );
    luminanceFilter->Update();

    return MedianFilter<ScalarImageType>(pipeline, luminanceFilter->GetOutput());
  }
};

int main( int argc, char * argv[] )
{
  itk::wasm::Pipeline pipeline("Apply a median filter to an image", argc, argv);

  return itk::wasm::SupportInputImageTypesNoVectorImage<PipelineFunctor,
   uint8_t,
   itk::RGBPixel< uint8_t >,
   float>
  ::Dimensions<2U,3U>("InputImage", pipeline);
}
<|endoftext|>


<commit_before>/**
    Copyright (c) 2017 Vicente Romero. All rights reserved.
    Licensed under the MIT License.
    See LICENSE file in the project root for full license information.
*/

#include <cstdio>
#include <cstring>
#include <string>

#include "compress.h"
#include "constants.h"
#include "decompress.h"

using namespace std;

struct ExecConfig {
    bool help_opt;
    bool decompress_opt;
    bool stdout_opt;
    bool force_opt;
    bool keep_opt;
    bool version_opt;
    string in_file_name;
    string out_file_name;
    FILE *in_file;
    FILE *out_file;

    ExecConfig() {
        help_opt        = false;
        decompress_opt  = false;
        stdout_opt      = false;
        force_opt       = false;
        keep_opt        = false;
        version_opt     = false;
        in_file         = stdin;
        out_file        = stdout;
    }

    ~ExecConfig() {
        if((in_file != nullptr) && (in_file != stdin)) {
            fclose(in_file);
        }

        if((out_file != nullptr) && (out_file != stdout)) {
            fclose(out_file);
        }
    }
};

static const char *kZjumpCompressedExt      = ".zjump";
static const char *kZjumpDecompressedExt    = ".orig";

static void DisplayVersionNumber() {
    uint32_t major = kZjumpVersion / 10000;
    uint32_t minor = (kZjumpVersion / 100) % 100;
    uint32_t patch = kZjumpVersion % 100;
    fprintf(stderr, "zjump %u.%u.%u\n", major, minor, patch);
}

static void Usage(const char *name)
{
    fprintf(stderr,
"zjump, a file compressor/decompressor\n"
"\n"
"Usage: %s [OPTIONS] [FILE]\n"
"\n"
"  -c, --stdout         Write on standard output\n"
"  -d, --decompress     Decompress FILE\n"
"  -f, --force          Force to overwrite the output file\n"
"  -k, --keep           Keep the input file (do not delete it)\n"
"  -h, --help           Output this help and exit\n"
"  -V, --version        Display version number\n"
"\n"
"If no FILE is given, zjump compresses or decompresses\n"
"from standard input to standard output."
"\n",
    name);
}

static void SetOutputFileName(ExecConfig* config) {
    if(config->stdout_opt || (config->in_file_name.empty())) {
        return;
    }

    if(config->decompress_opt) {
        size_t last_dot = config->in_file_name.find_last_of('.');

        if( (last_dot == string::npos) ||
            (config->in_file_name.compare(last_dot, string::npos, kZjumpCompressedExt) != 0)) {
            config->out_file_name = config->in_file_name + kZjumpDecompressedExt;
        } else {
            config->out_file_name = config->in_file_name.substr(0, last_dot);
        }
    } else {
        config->out_file_name = config->in_file_name + kZjumpCompressedExt;
    }
}

static int ParseOptions(int argc, char **argv, ExecConfig* config) {
    for(int i=1; i<argc; ++i) {
        if((strcmp(argv[i], "-c") == 0) || (strcmp(argv[i], "--stdout") == 0)) {
            config->stdout_opt = true;
        } else if((strcmp(argv[i], "-d") == 0) || (strcmp(argv[i], "--decompress") == 0)) {
            config->decompress_opt = true;
        } else if((strcmp(argv[i], "-f") == 0) || (strcmp(argv[i], "--force") == 0)) {
            config->force_opt = true;
        } else if((strcmp(argv[i], "-k") == 0) || (strcmp(argv[i], "--keep") == 0)) {
            config->keep_opt = true;
        } else if((strcmp(argv[i], "-h") == 0) || (strcmp(argv[i], "--help") == 0)) {
            config->help_opt = true;
        } else if((strcmp(argv[i], "-V") == 0) || (strcmp(argv[i], "--version") == 0)) {
            config->version_opt = true;
        } else if(argv[i][0] == '-') {
            fprintf(stderr, "Unrecognized option: '%s'\n", argv[i]);
        } else {
            return i;
        }
    }

    return argc;
}

static ZjumpErrorCode ValidateOptions(int argc, char **argv, int last_opt, ExecConfig* config) {
    if(config->help_opt) {
        return ZJUMP_NO_ERROR;
    }

    int last_args = argc - last_opt;
    if(last_args > 1) {
        fprintf(stderr, "Incorrect arguments. Use -h to display more information\n");
        return ZJUMP_ERROR_ARGUMENT;
    } else if(last_args == 1) {
        config->in_file_name = argv[last_opt];
        SetOutputFileName(config);
    }

    return ZJUMP_NO_ERROR;
}

static bool FileExists(const char* file_name) {
    FILE *file = fopen(file_name, "rb");
    if(file == nullptr) {
        return false;
    } else {
        fclose(file);
        return true;
    }
}

static ZjumpErrorCode ValidateOutput(const ExecConfig& config) {
    if(config.force_opt) {
        return ZJUMP_NO_ERROR;
    }

    if(config.out_file_name.empty()) {
        return ZJUMP_NO_ERROR;
    }

    const char *out_file_name = config.out_file_name.c_str();

    if(FileExists(out_file_name)) {
        fprintf(stderr, "Output file %s already exists.\n", out_file_name);
        return ZJUMP_ERROR_FILE;
    }

    return ZJUMP_NO_ERROR;
}

static ZjumpErrorCode OpenFiles(ExecConfig* config) {
    if(!config->in_file_name.empty()) {
        const char *in_file_name = config->in_file_name.c_str();

        config->in_file = fopen(in_file_name, "rb");

        if(config->in_file == nullptr) {
            perror(in_file_name);
            return ZJUMP_ERROR_FILE;
        }
    }

    if(!config->out_file_name.empty()) {
        const char *out_file_name = config->out_file_name.c_str();

        config->out_file = fopen(out_file_name, "wb");

        if(config->out_file == nullptr) {
            perror(out_file_name);
            return ZJUMP_ERROR_FILE;
        }
    }

    return ZJUMP_NO_ERROR;
}

static ZjumpErrorCode RemoveInput(const ExecConfig& config) {
    if(config.keep_opt) {
        return ZJUMP_NO_ERROR;
    }

    if(config.in_file == stdin) {
        return ZJUMP_NO_ERROR;
    }

    const char *in_file_name = config.in_file_name.c_str();
    if(remove(in_file_name) != 0) {
        perror(in_file_name);
        return ZJUMP_ERROR_FILE;
    }

    return ZJUMP_NO_ERROR;
}

int main(int argc, char **argv) {
    ExecConfig config;

    int last_opt = ParseOptions(argc, argv, &config);

    int ret_code = ValidateOptions(argc, argv, last_opt, &config);
    if(ret_code != ZJUMP_NO_ERROR) {
        return ret_code;
    }

    if(config.version_opt) {
        DisplayVersionNumber();
        return ZJUMP_NO_ERROR;
    }

    if(config.help_opt) {
        Usage(argv[0]);
        return ZJUMP_NO_ERROR;
    }

    ret_code = ValidateOutput(config);
    if(ret_code != ZJUMP_NO_ERROR) {
        return ret_code;
    }

    ret_code = OpenFiles(&config);
    if(ret_code != ZJUMP_NO_ERROR) {
        return ret_code;
    }

    if(config.decompress_opt) {
        Decompressor decompressor;
        ret_code = decompressor.Decompress(config.in_file, config.out_file);
        if(ret_code != ZJUMP_NO_ERROR) {
            return ret_code;
        }
    } else {
        Compressor compressor;
        ret_code = compressor.Compress(config.in_file, config.out_file);
        if(ret_code != ZJUMP_NO_ERROR) {
            return ret_code;
        }
    }

    ret_code = RemoveInput(config);
    if(ret_code != ZJUMP_NO_ERROR) {
        return ret_code;
    }

    return ZJUMP_NO_ERROR;
}

<commit_msg>added --license option<commit_after>/**
    Copyright (c) 2017 Vicente Romero. All rights reserved.
    Licensed under the MIT License.
    See LICENSE file in the project root for full license information.
*/

#include <cstdio>
#include <cstring>
#include <string>

#include "compress.h"
#include "constants.h"
#include "decompress.h"

using namespace std;

struct ExecConfig {
    bool help_opt;
    bool decompress_opt;
    bool stdout_opt;
    bool force_opt;
    bool keep_opt;
    bool version_opt;
    bool license_opt;
    string in_file_name;
    string out_file_name;
    FILE *in_file;
    FILE *out_file;

    ExecConfig() {
        help_opt        = false;
        decompress_opt  = false;
        stdout_opt      = false;
        force_opt       = false;
        keep_opt        = false;
        version_opt     = false;
        license_opt     = false;
        in_file         = stdin;
        out_file        = stdout;
    }

    ~ExecConfig() {
        if((in_file != nullptr) && (in_file != stdin)) {
            fclose(in_file);
        }

        if((out_file != nullptr) && (out_file != stdout)) {
            fclose(out_file);
        }
    }
};

static const char *kZjumpCompressedExt      = ".zjump";
static const char *kZjumpDecompressedExt    = ".orig";

static void DisplayVersionNumber() {
    uint32_t major = kZjumpVersion / 10000;
    uint32_t minor = (kZjumpVersion / 100) % 100;
    uint32_t patch = kZjumpVersion % 100;
    fprintf(stderr, "zjump %u.%u.%u\n", major, minor, patch);
}

static void DisplayLicense() {
    fprintf(stderr,
"Copyright (c) 2017 Vicente Romero. All rights reserved.\n"
"Licensed under the MIT License. See LICENSE file, which is included in the\n"
"zjump source distribution, for full license information.\n"
    );
}

static void Usage(const char *name)
{
    fprintf(stderr,
"zjump, a data compressor/decompressor\n"
"\n"
"Usage: %s [OPTIONS] [FILE]\n"
"\n"
"  -c, --stdout         Write on standard output\n"
"  -d, --decompress     Decompress FILE\n"
"  -f, --force          Force to overwrite the output file\n"
"  -h, --help           Output this help and exit\n"
"  -k, --keep           Keep the input file (do not delete it)\n"
"  -L, --license        Display software license\n"
"  -V, --version        Display version number\n"
"\n"
"If no FILE is given, zjump compresses or decompresses\n"
"from standard input to standard output."
"\n",
    name);
}

static void SetOutputFileName(ExecConfig* config) {
    if(config->stdout_opt || (config->in_file_name.empty())) {
        return;
    }

    if(config->decompress_opt) {
        size_t last_dot = config->in_file_name.find_last_of('.');

        if( (last_dot == string::npos) ||
            (config->in_file_name.compare(last_dot, string::npos, kZjumpCompressedExt) != 0)) {
            config->out_file_name = config->in_file_name + kZjumpDecompressedExt;
        } else {
            config->out_file_name = config->in_file_name.substr(0, last_dot);
        }
    } else {
        config->out_file_name = config->in_file_name + kZjumpCompressedExt;
    }
}

static int ParseOptions(int argc, char **argv, ExecConfig* config) {
    for(int i=1; i<argc; ++i) {
        if((strcmp(argv[i], "-c") == 0) || (strcmp(argv[i], "--stdout") == 0)) {
            config->stdout_opt = true;
        } else if((strcmp(argv[i], "-d") == 0) || (strcmp(argv[i], "--decompress") == 0)) {
            config->decompress_opt = true;
        } else if((strcmp(argv[i], "-f") == 0) || (strcmp(argv[i], "--force") == 0)) {
            config->force_opt = true;
        } else if((strcmp(argv[i], "-h") == 0) || (strcmp(argv[i], "--help") == 0)) {
            config->help_opt = true;
        } else if((strcmp(argv[i], "-k") == 0) || (strcmp(argv[i], "--keep") == 0)) {
            config->keep_opt = true;
        } else if((strcmp(argv[i], "-L") == 0) || (strcmp(argv[i], "--license") == 0)) {
            config->license_opt = true;
        } else if((strcmp(argv[i], "-V") == 0) || (strcmp(argv[i], "--version") == 0)) {
            config->version_opt = true;
        } else if(argv[i][0] == '-') {
            fprintf(stderr, "Unrecognized option: '%s'\n", argv[i]);
        } else {
            return i;
        }
    }

    return argc;
}

static ZjumpErrorCode ValidateOptions(int argc, char **argv, int last_opt, ExecConfig* config) {
    if(config->help_opt) {
        return ZJUMP_NO_ERROR;
    }

    int last_args = argc - last_opt;
    if(last_args > 1) {
        fprintf(stderr, "Incorrect arguments. Use -h to display more information\n");
        return ZJUMP_ERROR_ARGUMENT;
    } else if(last_args == 1) {
        config->in_file_name = argv[last_opt];
        SetOutputFileName(config);
    }

    return ZJUMP_NO_ERROR;
}

static bool FileExists(const char* file_name) {
    FILE *file = fopen(file_name, "rb");
    if(file == nullptr) {
        return false;
    } else {
        fclose(file);
        return true;
    }
}

static ZjumpErrorCode ValidateOutput(const ExecConfig& config) {
    if(config.force_opt) {
        return ZJUMP_NO_ERROR;
    }

    if(config.out_file_name.empty()) {
        return ZJUMP_NO_ERROR;
    }

    const char *out_file_name = config.out_file_name.c_str();

    if(FileExists(out_file_name)) {
        fprintf(stderr, "Output file %s already exists.\n", out_file_name);
        return ZJUMP_ERROR_FILE;
    }

    return ZJUMP_NO_ERROR;
}

static ZjumpErrorCode OpenFiles(ExecConfig* config) {
    if(!config->in_file_name.empty()) {
        const char *in_file_name = config->in_file_name.c_str();

        config->in_file = fopen(in_file_name, "rb");

        if(config->in_file == nullptr) {
            perror(in_file_name);
            return ZJUMP_ERROR_FILE;
        }
    }

    if(!config->out_file_name.empty()) {
        const char *out_file_name = config->out_file_name.c_str();

        config->out_file = fopen(out_file_name, "wb");

        if(config->out_file == nullptr) {
            perror(out_file_name);
            return ZJUMP_ERROR_FILE;
        }
    }

    return ZJUMP_NO_ERROR;
}

static ZjumpErrorCode RemoveInput(const ExecConfig& config) {
    if(config.keep_opt) {
        return ZJUMP_NO_ERROR;
    }

    if(config.in_file == stdin) {
        return ZJUMP_NO_ERROR;
    }

    const char *in_file_name = config.in_file_name.c_str();
    if(remove(in_file_name) != 0) {
        perror(in_file_name);
        return ZJUMP_ERROR_FILE;
    }

    return ZJUMP_NO_ERROR;
}

int main(int argc, char **argv) {
    ExecConfig config;

    int last_opt = ParseOptions(argc, argv, &config);

    int ret_code = ValidateOptions(argc, argv, last_opt, &config);
    if(ret_code != ZJUMP_NO_ERROR) {
        return ret_code;
    }

    if(config.version_opt || config.license_opt) {
        DisplayVersionNumber();
        DisplayLicense();
        return ZJUMP_NO_ERROR;
    }

    if(config.help_opt) {
        Usage(argv[0]);
        return ZJUMP_NO_ERROR;
    }

    ret_code = ValidateOutput(config);
    if(ret_code != ZJUMP_NO_ERROR) {
        return ret_code;
    }

    ret_code = OpenFiles(&config);
    if(ret_code != ZJUMP_NO_ERROR) {
        return ret_code;
    }

    if(config.decompress_opt) {
        Decompressor decompressor;
        ret_code = decompressor.Decompress(config.in_file, config.out_file);
        if(ret_code != ZJUMP_NO_ERROR) {
            return ret_code;
        }
    } else {
        Compressor compressor;
        ret_code = compressor.Compress(config.in_file, config.out_file);
        if(ret_code != ZJUMP_NO_ERROR) {
            return ret_code;
        }
    }

    ret_code = RemoveInput(config);
    if(ret_code != ZJUMP_NO_ERROR) {
        return ret_code;
    }

    return ZJUMP_NO_ERROR;
}

<|endoftext|>


<commit_before>/*
Copyright (c) 2019 Advanced Micro Devices, Inc. All rights reserved.
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 WARRANNTY OF ANY KIND, EXPRESS OR
IMPLIED, INNCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANNY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER INN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR INN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

// Simple test for hipLaunchCooperativeKernelMultiDevice API.

/* HIT_START
 * BUILD: %t %s ../../test_common.cpp EXCLUDE_HIP_PLATFORM all
 * TEST: %t
 * HIT_END
 */

#include "hip/hip_runtime.h"
#include "hip/hip_runtime_api.h"
#include <iostream>
#include <fstream>
#include <vector>
#include <thread>
#include <chrono>
#include "hip/hip_cooperative_groups.h"
#include "test_common.h"

using namespace std::chrono;

const static uint NumOfLoopIterrations = 16 * 1024;
const static uint BufferSizeInDwords = 28672 * NumOfLoopIterrations;
const static uint numQueues = 4;
const static uint numIter = 100;
constexpr uint NumKernelArgs = 4;
constexpr uint MaxGPUs = 8;

#include <stdio.h>
/*
namespace cg = cooperative_groups;
using namespace cooperative_groups;
*/

__global__ void test_gws(uint* buf, uint bufSize, long* tmpBuf, long* result)
{
    extern __shared__ long tmp[];
    uint groups = gridDim.x;
    uint group_id = blockIdx.x;
    uint local_id = threadIdx.x;
    uint chunk = gridDim.x * blockDim.x;

    uint i = group_id * blockDim.x + local_id;
    long sum = 0;
    while (i < bufSize) {
      sum += buf[i];
      i += chunk;
    }
    tmp[local_id] = sum;
    __syncthreads();
    i = 0;
    if (local_id == 0) {
        sum = 0;
        while (i < blockDim.x) {
          sum += tmp[i];
          i++;
        }
        tmpBuf[group_id] = sum;
    }

    // wait
    cooperative_groups::this_grid().sync();

    if (((blockIdx.x * blockDim.x) + threadIdx.x) == 0) {
        for (uint i = 1; i < groups; ++i) {
          sum += tmpBuf[i];
       }
       //*result = sum;
       result[1 + cooperative_groups::this_multi_grid().grid_rank()] = sum;
    }
    cooperative_groups::this_multi_grid().sync();
    if (cooperative_groups::this_multi_grid().grid_rank() == 0) {
      sum = 0;
      for (uint i = 1; i <= cooperative_groups::this_multi_grid().num_grids(); ++i) {
        sum += result[i];
      }
      *result = sum;
    }
}

int main() {
  float *A, *B;
  uint* dA[MaxGPUs];
  long* dB[MaxGPUs];
  long* dC;
  hipModule_t Module;
  hipStream_t stream[MaxGPUs];

  uint32_t* init = new uint32_t[BufferSizeInDwords];
  for (uint32_t i = 0; i < BufferSizeInDwords; ++i) {
    init[i] = i;
  }

  int nGpu = 0;
  HIPCHECK(hipGetDeviceCount(&nGpu));
  size_t copySizeInDwords = BufferSizeInDwords / nGpu;
  hipDeviceProp_t deviceProp[MaxGPUs];

  for (int i = 0; i < nGpu; i++) {
    HIPCHECK(hipSetDevice(i));

    // Calculate the device occupancy to know how many blocks can be run concurrently
    hipGetDeviceProperties(&deviceProp[i], 0);
    if (!deviceProp[i].cooperativeMultiDeviceLaunch) {
      printf("Device doesn't support cooperative launch!");
      passed();
      return 0;
    }
    size_t SIZE = copySizeInDwords * sizeof(uint);

    HIPCHECK(hipMalloc((void**)&dA[i], SIZE));
    if (i == 0) {
      HIPCHECK(hipHostMalloc((void**)&dC, (nGpu + 1) * sizeof(long), hipHostMallocCoherent));
    }
    HIPCHECK(hipMemcpy(dA[i], &init[i * copySizeInDwords] , SIZE, hipMemcpyHostToDevice));
    HIPCHECK(hipStreamCreate(&stream[i]));
  }

  dim3 dimBlock;
  dim3 dimGrid;
  dimGrid.x = 1;
  dimGrid.y = 1;
  dimGrid.z = 1;
  dimBlock.x = 64;
  dimBlock.y = 1;
  dimBlock.z = 1;

  int numBlocks = 0;
  uint workgroups[3] = {64, 128, 256};

  hipLaunchParams* launchParamsList = new hipLaunchParams[nGpu];

  system_clock::time_point start = system_clock::now();

  for (uint set = 0; set < 3; ++set) {
    void* args[MaxGPUs * NumKernelArgs];
    std::cout << "---------- Test#" << set << "---------------\n";
    for (int i = 0; i < nGpu; i++) {
      HIPCHECK(hipSetDevice(i));
      dimBlock.x = workgroups[set];
      HIPCHECK(hipOccupancyMaxActiveBlocksPerMultiprocessor(&numBlocks,
      (hipFunction_t)test_gws, dimBlock.x * dimBlock.y * dimBlock.z, dimBlock.x * sizeof(long)));

      std::cout << "GPU(" << i << ") Block size: " << dimBlock.x << " Num blocks per CU: " << numBlocks << "\n";

      dimGrid.x = deviceProp[i].multiProcessorCount * std::min(numBlocks, 32);
      HIPCHECK(hipMalloc((void**)&dB[i], dimGrid.x * sizeof(long)));

      args[i * NumKernelArgs]     = (void*)&dA[i];
      args[i * NumKernelArgs + 1] = (void*)&copySizeInDwords;
      args[i * NumKernelArgs + 2] = (void*)&dB[i];
      args[i * NumKernelArgs + 3] = (void*)&dC;

      launchParamsList[i].func = reinterpret_cast<void*>(test_gws);
      launchParamsList[i].gridDim = dimGrid;
      launchParamsList[i].blockDim = dimBlock;
      launchParamsList[i].sharedMem = dimBlock.x * sizeof(long);
      launchParamsList[i].stream = stream[i];
      launchParamsList[i].args = &args[i * NumKernelArgs];
    }

    hipLaunchCooperativeKernelMultiDevice(launchParamsList, nGpu, 0);

    HIPCHECK(hipMemcpy(init, dC, sizeof(long), hipMemcpyDeviceToHost));

    if (*dC != (((long)(BufferSizeInDwords) * (BufferSizeInDwords - 1)) / 2)) {
      std::cout << "Data validation failed for grid size = " << dimGrid.x << " and block size = " << dimBlock.x << "\n";
      std::cout << "Test failed! \n";
    }
    for (int i = 0; i < nGpu; i++) {
      hipFree(dB[i]);
    }
  }
  system_clock::time_point end = system_clock::now();

  delete [] launchParamsList;

  std::chrono::duration<double> elapsed_seconds = end - start;

  std::time_t end_time = std::chrono::system_clock::to_time_t(end);

  std::cout << "finished computation at " << std::ctime(&end_time) <<
    "elapsed time: " << elapsed_seconds.count() << "s\n";

  hipSetDevice(0);
  hipFree(dC);
  for (int i = 0; i < nGpu; i++) {
    hipFree(dA[i]);
    HIPCHECK(hipStreamDestroy(stream[i]));
  }
  delete [] init;
  passed();
  return 0;
}
<commit_msg>[dtest] Update hipLaunchCoopMultiKernel.cpp (#1844)<commit_after>/*
Copyright (c) 2019 Advanced Micro Devices, Inc. All rights reserved.
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 WARRANNTY OF ANY KIND, EXPRESS OR
IMPLIED, INNCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANNY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER INN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR INN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

// Simple test for hipLaunchCooperativeKernelMultiDevice API.

/* HIT_START
 * BUILD: %t %s ../../test_common.cpp EXCLUDE_HIP_PLATFORM all
 * TEST: %t
 * HIT_END
 */

#include "hip/hip_runtime.h"
#include "hip/hip_runtime_api.h"
#include <iostream>
#include <fstream>
#include <vector>
#include <thread>
#include <chrono>
#include "hip/hip_cooperative_groups.h"
#include "test_common.h"

using namespace std::chrono;

const static uint NumOfLoopIterrations = 16 * 1024;
const static uint BufferSizeInDwords = 28672 * NumOfLoopIterrations;
const static uint numQueues = 4;
const static uint numIter = 100;
constexpr uint NumKernelArgs = 4;
constexpr uint MaxGPUs = 8;

#include <stdio.h>
/*
namespace cg = cooperative_groups;
using namespace cooperative_groups;
*/

__global__ void test_gws(uint* buf, uint bufSize, long* tmpBuf, long* result)
{
    extern __shared__ long tmp[];
    uint groups = gridDim.x;
    uint group_id = blockIdx.x;
    uint local_id = threadIdx.x;
    uint chunk = gridDim.x * blockDim.x;

    uint i = group_id * blockDim.x + local_id;
    long sum = 0;
    while (i < bufSize) {
      sum += buf[i];
      i += chunk;
    }
    tmp[local_id] = sum;
    __syncthreads();
    i = 0;
    if (local_id == 0) {
        sum = 0;
        while (i < blockDim.x) {
          sum += tmp[i];
          i++;
        }
        tmpBuf[group_id] = sum;
    }

    // wait
    cooperative_groups::this_grid().sync();

    if (((blockIdx.x * blockDim.x) + threadIdx.x) == 0) {
        for (uint i = 1; i < groups; ++i) {
          sum += tmpBuf[i];
       }
       //*result = sum;
       result[1 + cooperative_groups::this_multi_grid().grid_rank()] = sum;
    }
    cooperative_groups::this_multi_grid().sync();
    if (cooperative_groups::this_multi_grid().grid_rank() == 0) {
      sum = 0;
      for (uint i = 1; i <= cooperative_groups::this_multi_grid().num_grids(); ++i) {
        sum += result[i];
      }
      *result = sum;
    }
}

int main() {
  float *A, *B;
  uint* dA[MaxGPUs];
  long* dB[MaxGPUs];
  long* dC;
  hipModule_t Module;
  hipStream_t stream[MaxGPUs];

  uint32_t* init = new uint32_t[BufferSizeInDwords];
  for (uint32_t i = 0; i < BufferSizeInDwords; ++i) {
    init[i] = i;
  }

  int nGpu = 0;
  HIPCHECK(hipGetDeviceCount(&nGpu));
  size_t copySizeInDwords = BufferSizeInDwords / nGpu;
  hipDeviceProp_t deviceProp[MaxGPUs];

  for (int i = 0; i < nGpu; i++) {
    HIPCHECK(hipSetDevice(i));

    // Calculate the device occupancy to know how many blocks can be run concurrently
    hipGetDeviceProperties(&deviceProp[i], 0);
    if (!deviceProp[i].cooperativeMultiDeviceLaunch) {
      printf("Device doesn't support cooperative launch!");
      passed();
      return 0;
    }
    size_t SIZE = copySizeInDwords * sizeof(uint);

    HIPCHECK(hipMalloc((void**)&dA[i], SIZE));
    if (i == 0) {
      HIPCHECK(hipHostMalloc((void**)&dC, (nGpu + 1) * sizeof(long), hipHostMallocCoherent));
    }
    HIPCHECK(hipMemcpy(dA[i], &init[i * copySizeInDwords] , SIZE, hipMemcpyHostToDevice));
    HIPCHECK(hipStreamCreate(&stream[i]));
  }

  dim3 dimBlock;
  dim3 dimGrid;
  dimGrid.x = 1;
  dimGrid.y = 1;
  dimGrid.z = 1;
  dimBlock.x = 64;
  dimBlock.y = 1;
  dimBlock.z = 1;

  int numBlocks = 0;
  uint workgroups[3] = {64, 128, 256};

  hipLaunchParams* launchParamsList = new hipLaunchParams[nGpu];

  system_clock::time_point start = system_clock::now();

  for (uint set = 0; set < 3; ++set) {
    void* args[MaxGPUs * NumKernelArgs];
    std::cout << "---------- Test#" << set << "---------------\n";
    for (int i = 0; i < nGpu; i++) {
      HIPCHECK(hipSetDevice(i));
      dimBlock.x = workgroups[set];
      HIPCHECK(hipOccupancyMaxActiveBlocksPerMultiprocessor(reinterpret_cast<uint32_t*>(&numBlocks),
      (hipFunction_t)test_gws, dimBlock.x * dimBlock.y * dimBlock.z, dimBlock.x * sizeof(long)));

      std::cout << "GPU(" << i << ") Block size: " << dimBlock.x << " Num blocks per CU: " << numBlocks << "\n";

      dimGrid.x = deviceProp[i].multiProcessorCount * std::min(numBlocks, 32);
      HIPCHECK(hipMalloc((void**)&dB[i], dimGrid.x * sizeof(long)));

      args[i * NumKernelArgs]     = (void*)&dA[i];
      args[i * NumKernelArgs + 1] = (void*)&copySizeInDwords;
      args[i * NumKernelArgs + 2] = (void*)&dB[i];
      args[i * NumKernelArgs + 3] = (void*)&dC;

      launchParamsList[i].func = reinterpret_cast<void*>(test_gws);
      launchParamsList[i].gridDim = dimGrid;
      launchParamsList[i].blockDim = dimBlock;
      launchParamsList[i].sharedMem = dimBlock.x * sizeof(long);
      launchParamsList[i].stream = stream[i];
      launchParamsList[i].args = &args[i * NumKernelArgs];
    }

    hipLaunchCooperativeKernelMultiDevice(launchParamsList, nGpu, 0);

    HIPCHECK(hipMemcpy(init, dC, sizeof(long), hipMemcpyDeviceToHost));

    if (*dC != (((long)(BufferSizeInDwords) * (BufferSizeInDwords - 1)) / 2)) {
      std::cout << "Data validation failed for grid size = " << dimGrid.x << " and block size = " << dimBlock.x << "\n";
      std::cout << "Test failed! \n";
    }
    for (int i = 0; i < nGpu; i++) {
      hipFree(dB[i]);
    }
  }
  system_clock::time_point end = system_clock::now();

  delete [] launchParamsList;

  std::chrono::duration<double> elapsed_seconds = end - start;

  std::time_t end_time = std::chrono::system_clock::to_time_t(end);

  std::cout << "finished computation at " << std::ctime(&end_time) <<
    "elapsed time: " << elapsed_seconds.count() << "s\n";

  hipSetDevice(0);
  hipFree(dC);
  for (int i = 0; i < nGpu; i++) {
    hipFree(dA[i]);
    HIPCHECK(hipStreamDestroy(stream[i]));
  }
  delete [] init;
  passed();
  return 0;
}
<|endoftext|>


<commit_before>#ifndef STAN_IO_ARRAY_VAR_CONTEXT_HPP
#define STAN_IO_ARRAY_VAR_CONTEXT_HPP

#include <stan/io/var_context.hpp>
#include <boost/throw_exception.hpp>
#include <stan/math/prim/mat/fun/Eigen.hpp>
#include <unordered_map>
#include <algorithm>
#include <functional>
#include <numeric>
#include <sstream>
#include <string>
#include <type_traits>
#include <vector>
#include <utility>

namespace stan {

namespace io {

/**
 * An array_var_context object represents a named arrays
 * with dimensions constructed from an array, a vector
 * of names, and a vector of all dimensions for each element.
 */
class array_var_context : public var_context {
 private:
  // Pairs
  template <typename T>
  using pair_ = std::pair<std::vector<T>, std::vector<size_t>>;

  // Map holding reals
  using map_r_ = std::unordered_map<std::string, pair_<double>>;
  map_r_ vars_r_;
  using map_i_ = std::unordered_map<std::string, pair_<int>>;
  map_i_ vars_i_;
  // When search for variable name fails, return one these
  std::vector<double> const empty_vec_r_{0};
  std::vector<int> const empty_vec_i_{0};
  std::vector<size_t> const empty_vec_ui_{0};

  // Find method
  bool contains_r_only(const std::string& name) const {
    return vars_r_.find(name) != vars_r_.end();
  }

  /**
   * Check (1) if the vector size of dimensions is no smaller
   * than the name vector size; (2) if the size of the input
   * array is large enough for what is needed.
   *
   * @param names The names for each variable
   * @param array_size The total size of the vector holding the values we want
   * to access.
   * @param dims Vector holding the dimensions for each variable.
   * @return If the array size is equal to the number of dimensions,
   * a vector of the cumulative sum of the dimensions of each inner element of
   * dims. The return of this function is used in the add_* methods to get the
   * sequence of values For each variable.
   */

  template <typename T>
  std::vector<size_t> validate_dims(
      const std::vector<std::string>& names, const T array_size,
      const std::vector<std::vector<size_t>>& dims) {
    const size_t num_par = names.size();
    if (num_par > dims.size()) {
      std::stringstream msg;
      msg << "size of vector of dimensions (found " << dims.size() << ") "
          << "should be no smaller than number of parameters (found " << num_par
          << ").";
      BOOST_THROW_EXCEPTION(std::invalid_argument(msg.str()));
    }
    std::vector<size_t> elem_dims_total(dims.size() + 1);
    elem_dims_total[0] = 0;
    int i = 0;
    for (i = 0; i < dims.size(); i++) {
      elem_dims_total[i + 1] = std::accumulate(dims[i].begin(), dims[i].end(),
                                               1, std::multiplies<T>())
                                + elem_dims_total[i];;
    }
    if (elem_dims_total[i] > array_size) {
      std::stringstream msg;
      msg << "array is not long enough for all elements: " << array_size
          << " is found, but " << elem_dims_total[i] << " is needed.";
      BOOST_THROW_EXCEPTION(std::invalid_argument(msg.str()));
    }
    return elem_dims_total;
  }

  /**
   * Adds a set of floating point variables to the floating point map.
   * @param names Names of each variable.
   * @param values The real values of variable in a contiguous
   * column major order container.
   * @param dims the dimensions for each variable.
   */
  void add_r(const std::vector<std::string>& names,
             const std::vector<double>& values,
             const std::vector<std::vector<size_t>>& dims) {
    std::vector<size_t> dim_vec = validate_dims(names, values.size(), dims);
    for (size_t i = 0; i < names.size(); i++) {
      vars_r_.emplace(names[i], pair_<double>{{values.data() + dim_vec[i],
         values.data() + dim_vec[i + 1]}, dims[i]});
    }
  }

  void add_r(const std::vector<std::string>& names,
             const Eigen::VectorXd& values,
             const std::vector<std::vector<size_t>>& dims) {
    std::vector<size_t> dim_vec = validate_dims(names, values.size(), dims);
    const auto name_size = names.size();
    for (size_t i = 0; i < name_size; i++) {
      vars_r_.emplace(names[i], pair_<double>{{values.data() + dim_vec[i],
          values.data() + dim_vec[i + 1]}, dims[i]});
    }
  }

  /**
   * Adds a set of integer variables to the integer map.
   * @param names Names of each variable.
   * @param values The integer values of variable in a vector.
   * @param dims the dimensions for each variable.
   */
  void add_i(const std::vector<std::string>& names,
             const std::vector<int>& values,
             const std::vector<std::vector<size_t>>& dims) {
    std::vector<size_t> dim_vec = validate_dims(names, values.size(), dims);
    for (size_t i = 0; i < names.size(); i++) {
      vars_i_.emplace(names[i], pair_<int>{{values.data() + dim_vec[i],
        values.data() + dim_vec[i + 1]}, dims[i]});
    }
  }

 public:
  /**
   * Construct an array_var_context from only real value arrays.
   *
   * @param names_r  names for each element
   * @param values_r a vector of double values for all elements
   * @param dim_r   a vector of dimensions
   */
  array_var_context(const std::vector<std::string>& names_r,
                    const std::vector<double>& values_r,
                    const std::vector<std::vector<size_t>>& dim_r)
      : vars_r_(names_r.size()) {
    add_r(names_r, values_r, dim_r);
  }

  array_var_context(const std::vector<std::string>& names_r,
                    const Eigen::VectorXd& values_r,
                    const std::vector<std::vector<size_t>>& dim_r)
      : vars_r_(names_r.size()) {
    add_r(names_r, values_r, dim_r);
  }

  /**
   * Construct an array_var_context from only integer value arrays.
   *
   * @param names_i  names for each element
   * @param values_i a vector of integer values for all elements
   * @param dim_i   a vector of dimensions
   */
  array_var_context(const std::vector<std::string>& names_i,
                    const std::vector<int>& values_i,
                    const std::vector<std::vector<size_t>>& dim_i)
      : vars_i_(names_i.size()) {
    add_i(names_i, values_i, dim_i);
  }

  /**
   * Construct an array_var_context from arrays of both double
   * and integer separately
   *
   */
  array_var_context(const std::vector<std::string>& names_r,
                    const std::vector<double>& values_r,
                    const std::vector<std::vector<size_t>>& dim_r,
                    const std::vector<std::string>& names_i,
                    const std::vector<int>& values_i,
                    const std::vector<std::vector<size_t>>& dim_i)
      : vars_r_(names_r.size()), vars_i_(names_i.size()) {
    add_i(names_i, values_i, dim_i);
    add_r(names_r, values_r, dim_r);
  }

  array_var_context(const std::vector<std::string>& names_r,
                    const Eigen::VectorXd& values_r,
                    const std::vector<std::vector<size_t>>& dim_r,
                    const std::vector<std::string>& names_i,
                    const std::vector<int>& values_i,
                    const std::vector<std::vector<size_t>>& dim_i)
      : vars_r_(names_r.size()), vars_i_(names_i.size()) {
    add_i(names_i, values_i, dim_i);
    add_r(names_r, values_r, dim_r);
  }

  /**
   * Return true if this dump contains the specified
   * variable name is defined. This method returns true
   * even if the values are all integers.
   *
   * @param name Variable name to test.
   * @return true if the variable exists.
   */
  bool contains_r(const std::string& name) const {
    return contains_r_only(name) || contains_i(name);
  }

  /**
   * Return true if this dump contains an integer
   * valued array with the specified name.
   *
   * @param name Variable name to test.
   * @return true if the variable name has an integer
   * array value.
   */
  bool contains_i(const std::string& name) const {
    return vars_i_.find(name) != vars_i_.end();
  }

  /**
   * Return the double values for the variable with the specified
   * name or null.
   *
   * @param name Name of variable.
   * @return Values of variable.
   *
   */
  std::vector<double> vals_r(const std::string& name) const {
    const auto ret_val_r = vars_r_.find(name);
    if (ret_val_r != vars_r_.end()) {
      return ret_val_r->second.first;
    } else {
      const auto ret_val_i = vars_i_.find(name);
      if (ret_val_i != vars_i_.end()) {
        return {ret_val_i->second.first.begin(), ret_val_i->second.first.end()};
      }
    }
    return empty_vec_r_;
  }

  /**
   * Return the dimensions for the double variable with the specified
   * name.
   *
   * @param name Name of variable.
   * @return Dimensions of variable.
   */
  std::vector<size_t> dims_r(const std::string& name) const {
    const auto ret_val_r = vars_r_.find(name);
    if (ret_val_r != vars_r_.end()) {
      return ret_val_r->second.second;
    } else {
      const auto ret_val_i = vars_i_.find(name);
      if (ret_val_i != vars_i_.end()) {
        return ret_val_i->second.second;
      }
    }
    return empty_vec_ui_;
  }

  /**
   * Return the integer values for the variable with the specified
   * name.
   *
   * @param name Name of variable.
   * @return Values.
   */
  std::vector<int> vals_i(const std::string& name) const {
    auto ret_val_i = vars_i_.find(name);
    if (ret_val_i != vars_i_.end()) {
      return ret_val_i->second.first;
    }
    return empty_vec_i_;
  }

  /**
   * Return the dimensions for the integer variable with the specified
   * name.
   *
   * @param name Name of variable.
   * @return Dimensions of variable.
   */
  std::vector<size_t> dims_i(const std::string& name) const {
    auto ret_val_i = vars_i_.find(name);
    if (ret_val_i != vars_i_.end()) {
      return ret_val_i->second.second;
    }
    return empty_vec_ui_;
  }

  /**
   * Return a list of the names of the floating point variables in
   * the dump.
   *
   * @param names Vector to store the list of names in.
   */
  virtual void names_r(std::vector<std::string>& names) const {
    names.clear();
    names.reserve(vars_r_.size());
    for (const auto& vars_r_iter : vars_r_) {
      names.push_back(vars_r_iter.first);
    }
  }

  /**
   * Return a list of the names of the integer variables in
   * the dump.
   *
   * @param names Vector to store the list of names in.
   */
  virtual void names_i(std::vector<std::string>& names) const {
    names.clear();
    names.reserve(vars_i_.size());
    for (const auto& vars_i_iter : vars_r_) {
      names.push_back(vars_i_iter.first);
    }
  }

  /**
   * Remove variable from the object.
   *
   * @param name Name of the variable to remove.
   * @return If variable is removed returns true, else
   *   returns false.
   */
  bool remove(const std::string& name) {
    vars_i_.erase(name);
    vars_r_.erase(name);
    return true;
  }
};
}  // namespace io
}  // namespace stan
#endif
<commit_msg>Add back map<commit_after>#ifndef STAN_IO_ARRAY_VAR_CONTEXT_HPP
#define STAN_IO_ARRAY_VAR_CONTEXT_HPP

#include <stan/io/var_context.hpp>
#include <boost/throw_exception.hpp>
#include <stan/math/prim/mat/fun/Eigen.hpp>
#include <unordered_map>
#include <algorithm>
#include <functional>
#include <numeric>
#include <sstream>
#include <string>
#include <type_traits>
#include <vector>
#include <utility>

namespace stan {

namespace io {

/**
 * An array_var_context object represents a named arrays
 * with dimensions constructed from an array, a vector
 * of names, and a vector of all dimensions for each element.
 */
class array_var_context : public var_context {
 private:
  // Pairs
  template <typename T>
  using pair_ = std::pair<std::vector<T>, std::vector<size_t>>;

  // Map holding reals
  using map_r_ = std::map<std::string, pair_<double>>;
  map_r_ vars_r_;
  using map_i_ = std::map<std::string, pair_<int>>;
  map_i_ vars_i_;
  // When search for variable name fails, return one these
  std::vector<double> const empty_vec_r_{0};
  std::vector<int> const empty_vec_i_{0};
  std::vector<size_t> const empty_vec_ui_{0};

  // Find method
  bool contains_r_only(const std::string& name) const {
    return vars_r_.find(name) != vars_r_.end();
  }

  /**
   * Check (1) if the vector size of dimensions is no smaller
   * than the name vector size; (2) if the size of the input
   * array is large enough for what is needed.
   *
   * @param names The names for each variable
   * @param array_size The total size of the vector holding the values we want
   * to access.
   * @param dims Vector holding the dimensions for each variable.
   * @return If the array size is equal to the number of dimensions,
   * a vector of the cumulative sum of the dimensions of each inner element of
   * dims. The return of this function is used in the add_* methods to get the
   * sequence of values For each variable.
   */

  template <typename T>
  std::vector<size_t> validate_dims(
      const std::vector<std::string>& names, const T array_size,
      const std::vector<std::vector<size_t>>& dims) {
    const size_t num_par = names.size();
    if (num_par > dims.size()) {
      std::stringstream msg;
      msg << "size of vector of dimensions (found " << dims.size() << ") "
          << "should be no smaller than number of parameters (found " << num_par
          << ").";
      BOOST_THROW_EXCEPTION(std::invalid_argument(msg.str()));
    }
    std::vector<size_t> elem_dims_total(dims.size() + 1);
    elem_dims_total[0] = 0;
    int i = 0;
    for (i = 0; i < dims.size(); i++) {
      elem_dims_total[i + 1] = std::accumulate(dims[i].begin(), dims[i].end(),
                                               1, std::multiplies<T>())
                                + elem_dims_total[i];;
    }
    if (elem_dims_total[i] > array_size) {
      std::stringstream msg;
      msg << "array is not long enough for all elements: " << array_size
          << " is found, but " << elem_dims_total[i] << " is needed.";
      BOOST_THROW_EXCEPTION(std::invalid_argument(msg.str()));
    }
    return elem_dims_total;
  }

  /**
   * Adds a set of floating point variables to the floating point map.
   * @param names Names of each variable.
   * @param values The real values of variable in a contiguous
   * column major order container.
   * @param dims the dimensions for each variable.
   */
  void add_r(const std::vector<std::string>& names,
             const std::vector<double>& values,
             const std::vector<std::vector<size_t>>& dims) {
    std::vector<size_t> dim_vec = validate_dims(names, values.size(), dims);
    for (size_t i = 0; i < names.size(); i++) {
      vars_r_.emplace(names[i], pair_<double>{{values.data() + dim_vec[i],
         values.data() + dim_vec[i + 1]}, dims[i]});
    }
  }

  void add_r(const std::vector<std::string>& names,
             const Eigen::VectorXd& values,
             const std::vector<std::vector<size_t>>& dims) {
    std::vector<size_t> dim_vec = validate_dims(names, values.size(), dims);
    const auto name_size = names.size();
    for (size_t i = 0; i < name_size; i++) {
      vars_r_.emplace(names[i], pair_<double>{{values.data() + dim_vec[i],
          values.data() + dim_vec[i + 1]}, dims[i]});
    }
  }

  /**
   * Adds a set of integer variables to the integer map.
   * @param names Names of each variable.
   * @param values The integer values of variable in a vector.
   * @param dims the dimensions for each variable.
   */
  void add_i(const std::vector<std::string>& names,
             const std::vector<int>& values,
             const std::vector<std::vector<size_t>>& dims) {
    std::vector<size_t> dim_vec = validate_dims(names, values.size(), dims);
    for (size_t i = 0; i < names.size(); i++) {
      vars_i_.emplace(names[i], pair_<int>{{values.data() + dim_vec[i],
        values.data() + dim_vec[i + 1]}, dims[i]});
    }
  }

 public:
  /**
   * Construct an array_var_context from only real value arrays.
   *
   * @param names_r  names for each element
   * @param values_r a vector of double values for all elements
   * @param dim_r   a vector of dimensions
   */
  array_var_context(const std::vector<std::string>& names_r,
                    const std::vector<double>& values_r,
                    const std::vector<std::vector<size_t>>& dim_r) {
    add_r(names_r, values_r, dim_r);
  }

  array_var_context(const std::vector<std::string>& names_r,
                    const Eigen::VectorXd& values_r,
                    const std::vector<std::vector<size_t>>& dim_r) {
    add_r(names_r, values_r, dim_r);
  }

  /**
   * Construct an array_var_context from only integer value arrays.
   *
   * @param names_i  names for each element
   * @param values_i a vector of integer values for all elements
   * @param dim_i   a vector of dimensions
   */
  array_var_context(const std::vector<std::string>& names_i,
                    const std::vector<int>& values_i,
                    const std::vector<std::vector<size_t>>& dim_i) {
    add_i(names_i, values_i, dim_i);
  }

  /**
   * Construct an array_var_context from arrays of both double
   * and integer separately
   *
   */
  array_var_context(const std::vector<std::string>& names_r,
                    const std::vector<double>& values_r,
                    const std::vector<std::vector<size_t>>& dim_r,
                    const std::vector<std::string>& names_i,
                    const std::vector<int>& values_i,
                    const std::vector<std::vector<size_t>>& dim_i) {
    add_i(names_i, values_i, dim_i);
    add_r(names_r, values_r, dim_r);
  }

  array_var_context(const std::vector<std::string>& names_r,
                    const Eigen::VectorXd& values_r,
                    const std::vector<std::vector<size_t>>& dim_r,
                    const std::vector<std::string>& names_i,
                    const std::vector<int>& values_i,
                    const std::vector<std::vector<size_t>>& dim_i) {
    add_i(names_i, values_i, dim_i);
    add_r(names_r, values_r, dim_r);
  }

  /**
   * Return true if this dump contains the specified
   * variable name is defined. This method returns true
   * even if the values are all integers.
   *
   * @param name Variable name to test.
   * @return true if the variable exists.
   */
  bool contains_r(const std::string& name) const {
    return contains_r_only(name) || contains_i(name);
  }

  /**
   * Return true if this dump contains an integer
   * valued array with the specified name.
   *
   * @param name Variable name to test.
   * @return true if the variable name has an integer
   * array value.
   */
  bool contains_i(const std::string& name) const {
    return vars_i_.find(name) != vars_i_.end();
  }

  /**
   * Return the double values for the variable with the specified
   * name or null.
   *
   * @param name Name of variable.
   * @return Values of variable.
   *
   */
  std::vector<double> vals_r(const std::string& name) const {
    const auto ret_val_r = vars_r_.find(name);
    if (ret_val_r != vars_r_.end()) {
      return ret_val_r->second.first;
    } else {
      const auto ret_val_i = vars_i_.find(name);
      if (ret_val_i != vars_i_.end()) {
        return {ret_val_i->second.first.begin(), ret_val_i->second.first.end()};
      }
    }
    return empty_vec_r_;
  }

  /**
   * Return the dimensions for the double variable with the specified
   * name.
   *
   * @param name Name of variable.
   * @return Dimensions of variable.
   */
  std::vector<size_t> dims_r(const std::string& name) const {
    const auto ret_val_r = vars_r_.find(name);
    if (ret_val_r != vars_r_.end()) {
      return ret_val_r->second.second;
    } else {
      const auto ret_val_i = vars_i_.find(name);
      if (ret_val_i != vars_i_.end()) {
        return ret_val_i->second.second;
      }
    }
    return empty_vec_ui_;
  }

  /**
   * Return the integer values for the variable with the specified
   * name.
   *
   * @param name Name of variable.
   * @return Values.
   */
  std::vector<int> vals_i(const std::string& name) const {
    auto ret_val_i = vars_i_.find(name);
    if (ret_val_i != vars_i_.end()) {
      return ret_val_i->second.first;
    }
    return empty_vec_i_;
  }

  /**
   * Return the dimensions for the integer variable with the specified
   * name.
   *
   * @param name Name of variable.
   * @return Dimensions of variable.
   */
  std::vector<size_t> dims_i(const std::string& name) const {
    auto ret_val_i = vars_i_.find(name);
    if (ret_val_i != vars_i_.end()) {
      return ret_val_i->second.second;
    }
    return empty_vec_ui_;
  }

  /**
   * Return a list of the names of the floating point variables in
   * the dump.
   *
   * @param names Vector to store the list of names in.
   */
  virtual void names_r(std::vector<std::string>& names) const {
    names.clear();
    names.reserve(vars_r_.size());
    for (const auto& vars_r_iter : vars_r_) {
      names.push_back(vars_r_iter.first);
    }
  }

  /**
   * Return a list of the names of the integer variables in
   * the dump.
   *
   * @param names Vector to store the list of names in.
   */
  virtual void names_i(std::vector<std::string>& names) const {
    names.clear();
    names.reserve(vars_i_.size());
    for (const auto& vars_i_iter : vars_r_) {
      names.push_back(vars_i_iter.first);
    }
  }

  /**
   * Remove variable from the object.
   *
   * @param name Name of the variable to remove.
   * @return If variable is removed returns true, else
   *   returns false.
   */
  bool remove(const std::string& name) {
    vars_i_.erase(name);
    vars_r_.erase(name);
    return true;
  }
};
}  // namespace io
}  // namespace stan
#endif
<|endoftext|>


<commit_before>/*
    Copyright (C) 2012  David Edmundson <kde@davidedmundson.co.uk>

    This library is free software; you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published
    by the Free Software Foundation; either version 2.1 of the License, or
    (at your option) any later version.

    This program 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 General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
#include "streamtubechannelapprover.h"

#include <KNotification>
#include <KStatusNotifierItem>
#include <KLocale>
#include <KDebug>
#include <KAboutData>
#include <KActionCollection>
#include <KMenu>
#include <KIcon>

#include <TelepathyQt/AvatarData>
#include <TelepathyQt/Contact>

StreamTubeChannelApprover::StreamTubeChannelApprover(
        const Tp::StreamTubeChannelPtr & channel,
        QObject *parent)
    : ChannelApprover(0),  //set parent to 0. I.e don't delete when the dispatch operation finishes. Instead we delete when the channel becomes invalidated.

      m_channel(channel)
{
    kDebug();

    connect(m_channel.data(), SIGNAL(invalidated(Tp::DBusProxy*,QString,QString)), SLOT(onChannelInvalidated()));

    if (m_channel->service() == QLatin1String("x-ssh-contact")) {
        m_serviceName = i18n("SSH");
    } else {
        m_serviceName = m_channel->service();
    }

    //notification
    m_notification = new KNotification("incoming_file_transfer");
    KAboutData aboutData("ktelepathy",0,KLocalizedString(),0);
    m_notification.data()->setComponentData(KComponentData(aboutData));
    m_notification.data()->setTitle(i18n("Incoming %1 share request", m_serviceName));

    Tp::ContactPtr sender = channel->initiatorContact();
    m_notification.data()->setText(i18n("
%1 wants to start a %2 sharing session with you
",
                                        sender->alias(),
                                        m_serviceName));

    QPixmap pixmap;
    if (pixmap.load(sender->avatarData().fileName)) {
        m_notification.data()->setPixmap(pixmap);
    }

    m_notification.data()->setActions(QStringList() << i18n("Accept") << i18n("Reject"));
    connect(m_notification.data(), SIGNAL(action1Activated()), SIGNAL(channelAccepted()));
    connect(m_notification.data(), SIGNAL(action2Activated()), SIGNAL(channelRejected()));

    m_notification.data()->sendEvent();

    //tray icon
    m_notifierItem = new KStatusNotifierItem;
    m_notifierItem->setCategory(KStatusNotifierItem::Communications);
    m_notifierItem->setStatus(KStatusNotifierItem::NeedsAttention);
    m_notifierItem->setIconByName(QLatin1String("utilities-terminal"));
    m_notifierItem->setStandardActionsEnabled(false);
    m_notifierItem->setTitle(i18n("Incoming file transfer"));
    m_notifierItem->setToolTip(QLatin1String("document-save"),
                               i18n("Incoming share request from %1", sender->alias()),
                               QString());
    m_notifierItem->contextMenu()->addAction(i18n("Accept"), this, SIGNAL(channelAccepted()));
    m_notifierItem->contextMenu()->addAction(i18n("Reject"), this, SIGNAL(channelRejected()));
//    connect(m_notifierItem, SIGNAL(activateRequested(bool,QPoint)), SIGNAL(channelAccepted())); //do we want clicking the approver to be auto-accept? I think not.
    connect(this, SIGNAL(channelAccepted()), SLOT(onChannelAccepted()));
}

StreamTubeChannelApprover::~StreamTubeChannelApprover()
{
    kDebug();

    //destroy the notification
    if (m_notification) {
        m_notification.data()->close();
    }

    //destroy the tray icon
    m_notifierItem->deleteLater();
}

void StreamTubeChannelApprover::onChannelAccepted()
{
    //destroy the notification
    if (m_notification) {
        m_notification.data()->close();
    }

    //set new menu to an entry to close the channel
    m_notifierItem->contextMenu()->clear();
    m_notifierItem->contextMenu()->addAction(KIcon("dialog-close"), i18n("Stop %1 Sharing", m_serviceName), this, SLOT(onChannelCloseRequested()));
}

void StreamTubeChannelApprover::onChannelCloseRequested()
{
    m_channel->requestClose();
}

void StreamTubeChannelApprover::onChannelInvalidated()
{
    deleteLater();
}

#include "streamtubechannelapprover.moc"
<commit_msg>Approve SSH Stream tubes.<commit_after>/*
    Copyright (C) 2012  David Edmundson <kde@davidedmundson.co.uk>

    This library is free software; you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published
    by the Free Software Foundation; either version 2.1 of the License, or
    (at your option) any later version.

    This program 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 General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
#include "streamtubechannelapprover.h"

#include <KNotification>
#include <KStatusNotifierItem>
#include <KLocale>
#include <KDebug>
#include <KAboutData>
#include <KActionCollection>
#include <KMenu>
#include <KIcon>

#include <TelepathyQt/AvatarData>
#include <TelepathyQt/Contact>

StreamTubeChannelApprover::StreamTubeChannelApprover(
        const Tp::StreamTubeChannelPtr & channel,
        QObject *parent)
    : ChannelApprover(0),  //set parent to 0. I.e don't delete when the dispatch operation finishes. Instead we delete when the channel becomes invalidated.

      m_channel(channel)
{
    kDebug();

    connect(m_channel.data(), SIGNAL(invalidated(Tp::DBusProxy*,QString,QString)), SLOT(onChannelInvalidated()));

    if (m_channel->service() == QLatin1String("x-ssh-contact")) {
        m_serviceName = i18nc("Acronym for the secure shell service","SSH");
    } else {
        m_serviceName = m_channel->service();
    }

    //notification
    m_notification = new KNotification("incoming_file_transfer");
    KAboutData aboutData("ktelepathy",0,KLocalizedString(),0);
    m_notification.data()->setComponentData(KComponentData(aboutData));
    m_notification.data()->setTitle(i18n("Incoming %1 share request", m_serviceName));

    Tp::ContactPtr sender = channel->initiatorContact();
    m_notification.data()->setText(i18n("
%1 wants to start a %2 sharing session with you
",
                                        sender->alias(),
                                        m_serviceName));

    QPixmap pixmap;
    if (pixmap.load(sender->avatarData().fileName)) {
        m_notification.data()->setPixmap(pixmap);
    }

    m_notification.data()->setActions(QStringList() << i18n("Accept") << i18n("Reject"));
    connect(m_notification.data(), SIGNAL(action1Activated()), SIGNAL(channelAccepted()));
    connect(m_notification.data(), SIGNAL(action2Activated()), SIGNAL(channelRejected()));

    m_notification.data()->sendEvent();

    //tray icon
    m_notifierItem = new KStatusNotifierItem;
    m_notifierItem->setCategory(KStatusNotifierItem::Communications);
    m_notifierItem->setStatus(KStatusNotifierItem::NeedsAttention);
    m_notifierItem->setIconByName(QLatin1String("utilities-terminal"));
    m_notifierItem->setStandardActionsEnabled(false);
    m_notifierItem->setTitle(i18n("Incoming share request"));
    m_notifierItem->setToolTip(QLatin1String("document-save"),
                               i18n("Incoming share request from %1", sender->alias()),
                               QString());
    m_notifierItem->contextMenu()->addAction(i18n("Accept"), this, SIGNAL(channelAccepted()));
    m_notifierItem->contextMenu()->addAction(i18n("Reject"), this, SIGNAL(channelRejected()));
//    connect(m_notifierItem, SIGNAL(activateRequested(bool,QPoint)), SIGNAL(channelAccepted())); //do we want clicking the approver to be auto-accept? I think not.
    connect(this, SIGNAL(channelAccepted()), SLOT(onChannelAccepted()));
}

StreamTubeChannelApprover::~StreamTubeChannelApprover()
{
    kDebug();

    //destroy the notification
    if (m_notification) {
        m_notification.data()->close();
    }

    //destroy the tray icon
    m_notifierItem->deleteLater();
}

void StreamTubeChannelApprover::onChannelAccepted()
{
    //destroy the notification
    if (m_notification) {
        m_notification.data()->close();
    }

    m_notifierItem->setTitle(i18n("%1 share with %2", m_serviceName, m_channel->initiatorContact()->alias()));
    //set new menu to an entry to close the channel
    m_notifierItem->contextMenu()->clear();
    m_notifierItem->contextMenu()->addAction(KIcon("dialog-close"), i18n("Stop %1 Sharing", m_serviceName), this, SLOT(onChannelCloseRequested()));
}

void StreamTubeChannelApprover::onChannelCloseRequested()
{
    m_channel->requestClose();
}

void StreamTubeChannelApprover::onChannelInvalidated()
{
    deleteLater();
}

#include "streamtubechannelapprover.moc"
<|endoftext|>


<commit_before>// ******************************************************************************************
// * This project is licensed under the GNU Affero GPL v3. Copyright © 2014 A3Wasteland.com *
// ******************************************************************************************
#include "player_sys.sqf"

class playerSettings {

	idd = playersys_DIALOG;
	movingEnable = true;
	enableSimulation = true;
	onLoad = "[] execVM 'client\systems\playerMenu\item_list.sqf'";

	class controlsBackground {

		class MainBG : IGUIBack {
			idc = -1;
			colorText[] = {1, 1, 1, 1};
			colorBackground[] = {0,0,0,0.6};

			moving = true;
			x = 0.0; y = 0.1;
			w = .745; h = 0.65;
		};

		class TopBar: IGUIBack
		{
			idc = -1;
			colorText[] = {1, 1, 1, 1};
			colorBackground[] = {A3W_UICOLOR_R, A3W_UICOLOR_G, A3W_UICOLOR_B, 0.8};

			x = 0;
			y = 0.1;
			w = 0.745;
			h = 0.05;
		};

		class MainTitle : w_RscText {
			idc = -1;
			text = "Player Inventory";
			sizeEx = 0.04;
			shadow = 2;
			x = 0.260; y = 0.1;
			w = 0.3; h = 0.05;
		};

		class waterIcon : w_RscPicture {
			idc = -1;
			text = "client\icons\water.paa";
			x = 0.022; y = 0.2;
			w = 0.04 / (4/3); h = 0.04;
		};

		class foodIcon : w_RscPicture {
			idc = -1;
			text = "client\icons\food.paa";
			x = 0.022; y = 0.26;
			w = 0.04 / (4/3); h = 0.04;
		};

		class moneyIcon : w_RscPicture {
			idc = -1;
			text = "client\icons\money.paa";
			x = 0.022; y = 0.32;
			w = 0.04 / (4/3); h = 0.04;
		};

		class waterText : w_RscText {
			idc = water_text;
			text = "";
			sizeEx = 0.03;
			x = 0.06; y = 0.193;
			w = 0.3; h = 0.05;
		};

		class foodText : w_RscText {
			idc = food_text;
			sizeEx = 0.03;
			text = "";
			x = 0.06; y = 0.254;
			w = 0.3; h = 0.05;
		};

		class moneyText : w_RscText {
			idc = money_text;
			text = "";
			sizeEx = 0.03;
			x = 0.06; y = 0.313;
			w = 0.3; h = 0.05;
		};

		/*class distanceText : w_RscText {
			idc = view_range_text;
			text = "View range:";
			sizeEx = 0.025;
			x = 0.03; y = 0.40;
			w = 0.3; h = 0.02;
		};*/

		class uptimeText : w_RscText {
			idc = uptime_text;
			text = "";
			sizeEx = 0.030;
			x = 0.52; y = 0.69;
			w = 0.225; h = 0.03;
		};
	};

	class controls {

		class itemList : w_Rsclist {
			idc = item_list;
			x = 0.49; y = 0.185;
			w = 0.235; h = 0.325;
		};

		class DropButton : w_RscButton {
			idc = -1;
			text = "Drop";
			onButtonClick = "[1] execVM 'client\systems\playerMenu\itemfnc.sqf'";
			x = 0.610; y = 0.525;
			w = 0.116; h = 0.033 * safezoneH;
		};

		class UseButton : w_RscButton {
			idc = -1;
			text = "Use";
			onButtonClick = "[0] execVM 'client\systems\playerMenu\itemfnc.sqf'";
			x = 0.489; y = 0.525;
			w = 0.116; h = 0.033 * safezoneH;
		};

		class moneyInput: w_RscCombo {
			idc = money_value;
			x = 0.610; y = 0.618;
			w = .116; h = .030;
		};

		class DropcButton : w_RscButton {
			idc = -1;
			text = "Drop";
			onButtonClick = "[] execVM 'client\systems\playerMenu\dropMoney.sqf'";
			x = 0.489; y = 0.60;
			w = 0.116; h = 0.033 * safezoneH;
		};

		class CloseButton : w_RscButton {
			idc = close_button;
			text = "Close";
			onButtonClick = "[] execVM 'client\systems\playerMenu\closePlayerMenu.sqf'";
			x = 0.02; y = 0.66;
			w = 0.125; h = 0.033 * safezoneH;
		};

		class GroupsButton : w_RscButton {
			idc = groupButton;
			text = "Group Management";
			onButtonClick = "[] execVM 'client\systems\groups\loadGroupManagement.sqf'";
			x = 0.158; y = 0.66;
			w = 0.225; h = 0.033 * safezoneH;
		};

		/*class btnDistanceNear : w_RscButton {
			idc = -1;
			text = "Near";
			onButtonClick = "setViewDistance 1100;";
			x = 0.02; y = 0.43;
			w = 0.125; h = 0.033 * safezoneH;
		};

		class btnDistanceMedium : w_RscButton {
			idc = -1;
			text = "Medium";
			onButtonClick = "setViewDistance 2200;";
			x = 0.02; y = 0.5;
			w = 0.125; h = 0.033 * safezoneH;
		};

		class btnDistanceFar : w_RscButton {
			idc = -1;
			text = "Far";
			onButtonClick = "setViewDistance 3300;";
			x = 0.02; y = 0.57;
			w = 0.125; h = 0.033 * safezoneH;
		};

		class btnDistanceInsane : w_RscButton {
			text = "Insane";
			onButtonClick = "setViewDistance 5000;";
			x = 0.02; y = 0.60;
			w = 0.125; h = 0.033 * safezoneH;
		};

		class btnDistanceCHVD : w_RscButton {
			idc = -1;
			text = "Viewdist.";
			onButtonClick = "call CHVD_fnc_openDialog";
			x = 0.02; y = 0.57;
			w = 0.125; h = 0.033 * safezoneH;
		};*/
		class TOParmaInfoButton : w_RscButton {
			idc = 1;
			text = "TOParma.com Info";
			onButtonClick = "[] execVM 'addons\TOParmaInfo\loadToparmaInfo.sqf'";
			x = 0.228; y = 0.254;
			w = 0.225; h = 0.033 * safezoneH;
		};
	};
};
<commit_msg>updated button name<commit_after>// ******************************************************************************************
// * This project is licensed under the GNU Affero GPL v3. Copyright © 2014 A3Wasteland.com *
// ******************************************************************************************
#include "player_sys.sqf"

class playerSettings {

	idd = playersys_DIALOG;
	movingEnable = true;
	enableSimulation = true;
	onLoad = "[] execVM 'client\systems\playerMenu\item_list.sqf'";

	class controlsBackground {

		class MainBG : IGUIBack {
			idc = -1;
			colorText[] = {1, 1, 1, 1};
			colorBackground[] = {0,0,0,0.6};

			moving = true;
			x = 0.0; y = 0.1;
			w = .745; h = 0.65;
		};

		class TopBar: IGUIBack
		{
			idc = -1;
			colorText[] = {1, 1, 1, 1};
			colorBackground[] = {A3W_UICOLOR_R, A3W_UICOLOR_G, A3W_UICOLOR_B, 0.8};

			x = 0;
			y = 0.1;
			w = 0.745;
			h = 0.05;
		};

		class MainTitle : w_RscText {
			idc = -1;
			text = "Player Inventory";
			sizeEx = 0.04;
			shadow = 2;
			x = 0.260; y = 0.1;
			w = 0.3; h = 0.05;
		};

		class waterIcon : w_RscPicture {
			idc = -1;
			text = "client\icons\water.paa";
			x = 0.022; y = 0.2;
			w = 0.04 / (4/3); h = 0.04;
		};

		class foodIcon : w_RscPicture {
			idc = -1;
			text = "client\icons\food.paa";
			x = 0.022; y = 0.26;
			w = 0.04 / (4/3); h = 0.04;
		};

		class moneyIcon : w_RscPicture {
			idc = -1;
			text = "client\icons\money.paa";
			x = 0.022; y = 0.32;
			w = 0.04 / (4/3); h = 0.04;
		};

		class waterText : w_RscText {
			idc = water_text;
			text = "";
			sizeEx = 0.03;
			x = 0.06; y = 0.193;
			w = 0.3; h = 0.05;
		};

		class foodText : w_RscText {
			idc = food_text;
			sizeEx = 0.03;
			text = "";
			x = 0.06; y = 0.254;
			w = 0.3; h = 0.05;
		};

		class moneyText : w_RscText {
			idc = money_text;
			text = "";
			sizeEx = 0.03;
			x = 0.06; y = 0.313;
			w = 0.3; h = 0.05;
		};

		/*class distanceText : w_RscText {
			idc = view_range_text;
			text = "View range:";
			sizeEx = 0.025;
			x = 0.03; y = 0.40;
			w = 0.3; h = 0.02;
		};*/

		class uptimeText : w_RscText {
			idc = uptime_text;
			text = "";
			sizeEx = 0.030;
			x = 0.52; y = 0.69;
			w = 0.225; h = 0.03;
		};
	};

	class controls {

		class itemList : w_Rsclist {
			idc = item_list;
			x = 0.49; y = 0.185;
			w = 0.235; h = 0.325;
		};

		class DropButton : w_RscButton {
			idc = -1;
			text = "Drop";
			onButtonClick = "[1] execVM 'client\systems\playerMenu\itemfnc.sqf'";
			x = 0.610; y = 0.525;
			w = 0.116; h = 0.033 * safezoneH;
		};

		class UseButton : w_RscButton {
			idc = -1;
			text = "Use";
			onButtonClick = "[0] execVM 'client\systems\playerMenu\itemfnc.sqf'";
			x = 0.489; y = 0.525;
			w = 0.116; h = 0.033 * safezoneH;
		};

		class moneyInput: w_RscCombo {
			idc = money_value;
			x = 0.610; y = 0.618;
			w = .116; h = .030;
		};

		class DropcButton : w_RscButton {
			idc = -1;
			text = "Drop";
			onButtonClick = "[] execVM 'client\systems\playerMenu\dropMoney.sqf'";
			x = 0.489; y = 0.60;
			w = 0.116; h = 0.033 * safezoneH;
		};

		class CloseButton : w_RscButton {
			idc = close_button;
			text = "Close";
			onButtonClick = "[] execVM 'client\systems\playerMenu\closePlayerMenu.sqf'";
			x = 0.02; y = 0.66;
			w = 0.125; h = 0.033 * safezoneH;
		};

		class GroupsButton : w_RscButton {
			idc = groupButton;
			text = "Group Management";
			onButtonClick = "[] execVM 'client\systems\groups\loadGroupManagement.sqf'";
			x = 0.158; y = 0.66;
			w = 0.225; h = 0.033 * safezoneH;
		};

		/*class btnDistanceNear : w_RscButton {
			idc = -1;
			text = "Near";
			onButtonClick = "setViewDistance 1100;";
			x = 0.02; y = 0.43;
			w = 0.125; h = 0.033 * safezoneH;
		};

		class btnDistanceMedium : w_RscButton {
			idc = -1;
			text = "Medium";
			onButtonClick = "setViewDistance 2200;";
			x = 0.02; y = 0.5;
			w = 0.125; h = 0.033 * safezoneH;
		};

		class btnDistanceFar : w_RscButton {
			idc = -1;
			text = "Far";
			onButtonClick = "setViewDistance 3300;";
			x = 0.02; y = 0.57;
			w = 0.125; h = 0.033 * safezoneH;
		};

		class btnDistanceInsane : w_RscButton {
			text = "Insane";
			onButtonClick = "setViewDistance 5000;";
			x = 0.02; y = 0.60;
			w = 0.125; h = 0.033 * safezoneH;
		};

		class btnDistanceCHVD : w_RscButton {
			idc = -1;
			text = "Viewdist.";
			onButtonClick = "call CHVD_fnc_openDialog";
			x = 0.02; y = 0.57;
			w = 0.125; h = 0.033 * safezoneH;
		};*/
		class TOParmaInfoButton : w_RscButton {
			idc = 1;
			text = "Fractured";
			onButtonClick = "[] execVM 'addons\TOParmaInfo\loadToparmaInfo.sqf'";
			x = 0.228; y = 0.254;
			w = 0.225; h = 0.033 * safezoneH;
		};
	};
};
<|endoftext|>