<commit_before>/*M///////////////////////////////////////////////////////////////////////////////////////
//
//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
//  By downloading, copying, installing or using the software you agree to this license.
//  If you do not agree to this license, do not download, install,
//  copy or use the software.
//
//
//                           License Agreement
//                For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistribution's of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//
//   * Redistribution's 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.
//
//   * The name of the copyright holders may not be used to endorse or promote products
//     derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/

#include "test_precomp.hpp"

#ifdef HAVE_CUDA

using namespace cvtest;

//////////////////////////////////////////////////////////////////////////
// StereoBM

struct StereoBM : testing::TestWithParam<cv::gpu::DeviceInfo>
{
    cv::gpu::DeviceInfo devInfo;

    virtual void SetUp()
    {
        devInfo = GetParam();

        cv::gpu::setDevice(devInfo.deviceID());
    }
};

GPU_TEST_P(StereoBM, Regression)
{
    cv::Mat left_image  = readImage("stereobm/aloe-L.png", cv::IMREAD_GRAYSCALE);
    cv::Mat right_image = readImage("stereobm/aloe-R.png", cv::IMREAD_GRAYSCALE);
    cv::Mat disp_gold   = readImage("stereobm/aloe-disp.png", cv::IMREAD_GRAYSCALE);

    ASSERT_FALSE(left_image.empty());
    ASSERT_FALSE(right_image.empty());
    ASSERT_FALSE(disp_gold.empty());

    cv::gpu::StereoBM_GPU bm(0, 128, 19);
    cv::gpu::GpuMat disp;

    bm(loadMat(left_image), loadMat(right_image), disp);

    EXPECT_MAT_NEAR(disp_gold, disp, 0.0);
}

INSTANTIATE_TEST_CASE_P(GPU_Calib3D, StereoBM, ALL_DEVICES);

//////////////////////////////////////////////////////////////////////////
// StereoBeliefPropagation

struct StereoBeliefPropagation : testing::TestWithParam<cv::gpu::DeviceInfo>
{
    cv::gpu::DeviceInfo devInfo;

    virtual void SetUp()
    {
        devInfo = GetParam();

        cv::gpu::setDevice(devInfo.deviceID());
    }
};

GPU_TEST_P(StereoBeliefPropagation, Regression)
{
    cv::Mat left_image  = readImage("stereobp/aloe-L.png");
    cv::Mat right_image = readImage("stereobp/aloe-R.png");
    cv::Mat disp_gold   = readImage("stereobp/aloe-disp.png", cv::IMREAD_GRAYSCALE);

    ASSERT_FALSE(left_image.empty());
    ASSERT_FALSE(right_image.empty());
    ASSERT_FALSE(disp_gold.empty());

    cv::gpu::StereoBeliefPropagation bp(64, 8, 2, 25, 0.1f, 15, 1, CV_16S);
    cv::gpu::GpuMat disp;

    bp(loadMat(left_image), loadMat(right_image), disp);

    cv::Mat h_disp(disp);
    h_disp.convertTo(h_disp, disp_gold.depth());

    EXPECT_MAT_NEAR(disp_gold, h_disp, 0.0);
}

INSTANTIATE_TEST_CASE_P(GPU_Calib3D, StereoBeliefPropagation, ALL_DEVICES);

//////////////////////////////////////////////////////////////////////////
// StereoConstantSpaceBP

struct StereoConstantSpaceBP : testing::TestWithParam<cv::gpu::DeviceInfo>
{
    cv::gpu::DeviceInfo devInfo;

    virtual void SetUp()
    {
        devInfo = GetParam();

        cv::gpu::setDevice(devInfo.deviceID());
    }
};

GPU_TEST_P(StereoConstantSpaceBP, Regression)
{
    cv::Mat left_image  = readImage("csstereobp/aloe-L.png");
    cv::Mat right_image = readImage("csstereobp/aloe-R.png");

    cv::Mat disp_gold;

    if (supportFeature(devInfo, cv::gpu::FEATURE_SET_COMPUTE_20))
        disp_gold = readImage("csstereobp/aloe-disp.png", cv::IMREAD_GRAYSCALE);
    else
        disp_gold = readImage("csstereobp/aloe-disp_CC1X.png", cv::IMREAD_GRAYSCALE);

    ASSERT_FALSE(left_image.empty());
    ASSERT_FALSE(right_image.empty());
    ASSERT_FALSE(disp_gold.empty());

    cv::gpu::StereoConstantSpaceBP csbp(128, 16, 4, 4);
    cv::gpu::GpuMat disp;

    csbp(loadMat(left_image), loadMat(right_image), disp);

    cv::Mat h_disp(disp);
    h_disp.convertTo(h_disp, disp_gold.depth());

    EXPECT_MAT_SIMILAR(disp_gold, h_disp, 1e-4);
}

INSTANTIATE_TEST_CASE_P(GPU_Calib3D, StereoConstantSpaceBP, ALL_DEVICES);

///////////////////////////////////////////////////////////////////////////////////////////////////////
// transformPoints

struct TransformPoints : testing::TestWithParam<cv::gpu::DeviceInfo>
{
    cv::gpu::DeviceInfo devInfo;

    virtual void SetUp()
    {
        devInfo = GetParam();

        cv::gpu::setDevice(devInfo.deviceID());
    }
};

GPU_TEST_P(TransformPoints, Accuracy)
{
    cv::Mat src = randomMat(cv::Size(1000, 1), CV_32FC3, 0, 10);
    cv::Mat rvec = randomMat(cv::Size(3, 1), CV_32F, 0, 1);
    cv::Mat tvec = randomMat(cv::Size(3, 1), CV_32F, 0, 1);

    cv::gpu::GpuMat dst;
    cv::gpu::transformPoints(loadMat(src), rvec, tvec, dst);

    ASSERT_EQ(src.size(), dst.size());
    ASSERT_EQ(src.type(), dst.type());

    cv::Mat h_dst(dst);

    cv::Mat rot;
    cv::Rodrigues(rvec, rot);

    for (int i = 0; i < h_dst.cols; ++i)
    {
        cv::Point3f res = h_dst.at<cv::Point3f>(0, i);

        cv::Point3f p = src.at<cv::Point3f>(0, i);
        cv::Point3f res_gold(
                rot.at<float>(0, 0) * p.x + rot.at<float>(0, 1) * p.y + rot.at<float>(0, 2) * p.z + tvec.at<float>(0, 0),
                rot.at<float>(1, 0) * p.x + rot.at<float>(1, 1) * p.y + rot.at<float>(1, 2) * p.z + tvec.at<float>(0, 1),
                rot.at<float>(2, 0) * p.x + rot.at<float>(2, 1) * p.y + rot.at<float>(2, 2) * p.z + tvec.at<float>(0, 2));

        ASSERT_POINT3_NEAR(res_gold, res, 1e-5);
    }
}

INSTANTIATE_TEST_CASE_P(GPU_Calib3D, TransformPoints, ALL_DEVICES);

///////////////////////////////////////////////////////////////////////////////////////////////////////
// ProjectPoints

struct ProjectPoints : testing::TestWithParam<cv::gpu::DeviceInfo>
{
    cv::gpu::DeviceInfo devInfo;

    virtual void SetUp()
    {
        devInfo = GetParam();

        cv::gpu::setDevice(devInfo.deviceID());
    }
};

GPU_TEST_P(ProjectPoints, Accuracy)
{
    cv::Mat src = randomMat(cv::Size(1000, 1), CV_32FC3, 0, 10);
    cv::Mat rvec = randomMat(cv::Size(3, 1), CV_32F, 0, 1);
    cv::Mat tvec = randomMat(cv::Size(3, 1), CV_32F, 0, 1);
    cv::Mat camera_mat = randomMat(cv::Size(3, 3), CV_32F, 0.5, 1);
    camera_mat.at<float>(0, 1) = 0.f;
    camera_mat.at<float>(1, 0) = 0.f;
    camera_mat.at<float>(2, 0) = 0.f;
    camera_mat.at<float>(2, 1) = 0.f;

    cv::gpu::GpuMat dst;
    cv::gpu::projectPoints(loadMat(src), rvec, tvec, camera_mat, cv::Mat(), dst);

    ASSERT_EQ(1, dst.rows);
    ASSERT_EQ(MatType(CV_32FC2), MatType(dst.type()));

    std::vector<cv::Point2f> dst_gold;
    cv::projectPoints(src, rvec, tvec, camera_mat, cv::Mat(1, 8, CV_32F, cv::Scalar::all(0)), dst_gold);

    ASSERT_EQ(dst_gold.size(), static_cast<size_t>(dst.cols));

    cv::Mat h_dst(dst);

    for (size_t i = 0; i < dst_gold.size(); ++i)
    {
        cv::Point2f res = h_dst.at<cv::Point2f>(0, (int)i);
        cv::Point2f res_gold = dst_gold[i];

        ASSERT_LE(cv::norm(res_gold - res) / cv::norm(res_gold), 1e-3f);
    }
}

INSTANTIATE_TEST_CASE_P(GPU_Calib3D, ProjectPoints, ALL_DEVICES);

///////////////////////////////////////////////////////////////////////////////////////////////////////
// SolvePnPRansac

struct SolvePnPRansac : testing::TestWithParam<cv::gpu::DeviceInfo>
{
    cv::gpu::DeviceInfo devInfo;

    virtual void SetUp()
    {
        devInfo = GetParam();

        cv::gpu::setDevice(devInfo.deviceID());
    }
};

GPU_TEST_P(SolvePnPRansac, Accuracy)
{
    cv::Mat object = randomMat(cv::Size(5000, 1), CV_32FC3, 0, 100);
    cv::Mat camera_mat = randomMat(cv::Size(3, 3), CV_32F, 0.5, 1);
    camera_mat.at<float>(0, 1) = 0.f;
    camera_mat.at<float>(1, 0) = 0.f;
    camera_mat.at<float>(2, 0) = 0.f;
    camera_mat.at<float>(2, 1) = 0.f;

    std::vector<cv::Point2f> image_vec;
    cv::Mat rvec_gold;
    cv::Mat tvec_gold;
    rvec_gold = randomMat(cv::Size(3, 1), CV_32F, 0, 1);
    tvec_gold = randomMat(cv::Size(3, 1), CV_32F, 0, 1);
    cv::projectPoints(object, rvec_gold, tvec_gold, camera_mat, cv::Mat(1, 8, CV_32F, cv::Scalar::all(0)), image_vec);

    cv::Mat rvec, tvec;
    std::vector<int> inliers;
    cv::gpu::solvePnPRansac(object, cv::Mat(1, (int)image_vec.size(), CV_32FC2, &image_vec[0]),
                            camera_mat, cv::Mat(1, 8, CV_32F, cv::Scalar::all(0)),
                            rvec, tvec, false, 200, 2.f, 100, &inliers);

    ASSERT_LE(cv::norm(rvec - rvec_gold), 2e-3);
    ASSERT_LE(cv::norm(tvec - tvec_gold), 2e-3);
}

INSTANTIATE_TEST_CASE_P(GPU_Calib3D, SolvePnPRansac, ALL_DEVICES);

////////////////////////////////////////////////////////////////////////////////
// reprojectImageTo3D

PARAM_TEST_CASE(ReprojectImageTo3D, cv::gpu::DeviceInfo, cv::Size, MatDepth, UseRoi)
{
    cv::gpu::DeviceInfo devInfo;
    cv::Size size;
    int depth;
    bool useRoi;

    virtual void SetUp()
    {
        devInfo = GET_PARAM(0);
        size = GET_PARAM(1);
        depth = GET_PARAM(2);
        useRoi = GET_PARAM(3);

        cv::gpu::setDevice(devInfo.deviceID());
    }
};

GPU_TEST_P(ReprojectImageTo3D, Accuracy)
{
    cv::Mat disp = randomMat(size, depth, 5.0, 30.0);
    cv::Mat Q = randomMat(cv::Size(4, 4), CV_32FC1, 0.1, 1.0);

    cv::gpu::GpuMat dst;
    cv::gpu::reprojectImageTo3D(loadMat(disp, useRoi), dst, Q, 3);

    cv::Mat dst_gold;
    cv::reprojectImageTo3D(disp, dst_gold, Q, false);

    EXPECT_MAT_NEAR(dst_gold, dst, 1e-5);
}

INSTANTIATE_TEST_CASE_P(GPU_Calib3D, ReprojectImageTo3D, testing::Combine(
    ALL_DEVICES,
    DIFFERENT_SIZES,
    testing::Values(MatDepth(CV_8U), MatDepth(CV_16S)),
    WHOLE_SUBMAT));

#endif // HAVE_CUDA
<commit_msg>use fixed seed for RNG in gpu SolvePnPRansac test (cherry picked from commit 95eed59f2dcc0fc4a3b46892d60deb9e26d22872)<commit_after>/*M///////////////////////////////////////////////////////////////////////////////////////
//
//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
//  By downloading, copying, installing or using the software you agree to this license.
//  If you do not agree to this license, do not download, install,
//  copy or use the software.
//
//
//                           License Agreement
//                For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistribution's of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//
//   * Redistribution's 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.
//
//   * The name of the copyright holders may not be used to endorse or promote products
//     derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/

#include "test_precomp.hpp"

#ifdef HAVE_CUDA

using namespace cvtest;

//////////////////////////////////////////////////////////////////////////
// StereoBM

struct StereoBM : testing::TestWithParam<cv::gpu::DeviceInfo>
{
    cv::gpu::DeviceInfo devInfo;

    virtual void SetUp()
    {
        devInfo = GetParam();

        cv::gpu::setDevice(devInfo.deviceID());
    }
};

GPU_TEST_P(StereoBM, Regression)
{
    cv::Mat left_image  = readImage("stereobm/aloe-L.png", cv::IMREAD_GRAYSCALE);
    cv::Mat right_image = readImage("stereobm/aloe-R.png", cv::IMREAD_GRAYSCALE);
    cv::Mat disp_gold   = readImage("stereobm/aloe-disp.png", cv::IMREAD_GRAYSCALE);

    ASSERT_FALSE(left_image.empty());
    ASSERT_FALSE(right_image.empty());
    ASSERT_FALSE(disp_gold.empty());

    cv::gpu::StereoBM_GPU bm(0, 128, 19);
    cv::gpu::GpuMat disp;

    bm(loadMat(left_image), loadMat(right_image), disp);

    EXPECT_MAT_NEAR(disp_gold, disp, 0.0);
}

INSTANTIATE_TEST_CASE_P(GPU_Calib3D, StereoBM, ALL_DEVICES);

//////////////////////////////////////////////////////////////////////////
// StereoBeliefPropagation

struct StereoBeliefPropagation : testing::TestWithParam<cv::gpu::DeviceInfo>
{
    cv::gpu::DeviceInfo devInfo;

    virtual void SetUp()
    {
        devInfo = GetParam();

        cv::gpu::setDevice(devInfo.deviceID());
    }
};

GPU_TEST_P(StereoBeliefPropagation, Regression)
{
    cv::Mat left_image  = readImage("stereobp/aloe-L.png");
    cv::Mat right_image = readImage("stereobp/aloe-R.png");
    cv::Mat disp_gold   = readImage("stereobp/aloe-disp.png", cv::IMREAD_GRAYSCALE);

    ASSERT_FALSE(left_image.empty());
    ASSERT_FALSE(right_image.empty());
    ASSERT_FALSE(disp_gold.empty());

    cv::gpu::StereoBeliefPropagation bp(64, 8, 2, 25, 0.1f, 15, 1, CV_16S);
    cv::gpu::GpuMat disp;

    bp(loadMat(left_image), loadMat(right_image), disp);

    cv::Mat h_disp(disp);
    h_disp.convertTo(h_disp, disp_gold.depth());

    EXPECT_MAT_NEAR(disp_gold, h_disp, 0.0);
}

INSTANTIATE_TEST_CASE_P(GPU_Calib3D, StereoBeliefPropagation, ALL_DEVICES);

//////////////////////////////////////////////////////////////////////////
// StereoConstantSpaceBP

struct StereoConstantSpaceBP : testing::TestWithParam<cv::gpu::DeviceInfo>
{
    cv::gpu::DeviceInfo devInfo;

    virtual void SetUp()
    {
        devInfo = GetParam();

        cv::gpu::setDevice(devInfo.deviceID());
    }
};

GPU_TEST_P(StereoConstantSpaceBP, Regression)
{
    cv::Mat left_image  = readImage("csstereobp/aloe-L.png");
    cv::Mat right_image = readImage("csstereobp/aloe-R.png");

    cv::Mat disp_gold;

    if (supportFeature(devInfo, cv::gpu::FEATURE_SET_COMPUTE_20))
        disp_gold = readImage("csstereobp/aloe-disp.png", cv::IMREAD_GRAYSCALE);
    else
        disp_gold = readImage("csstereobp/aloe-disp_CC1X.png", cv::IMREAD_GRAYSCALE);

    ASSERT_FALSE(left_image.empty());
    ASSERT_FALSE(right_image.empty());
    ASSERT_FALSE(disp_gold.empty());

    cv::gpu::StereoConstantSpaceBP csbp(128, 16, 4, 4);
    cv::gpu::GpuMat disp;

    csbp(loadMat(left_image), loadMat(right_image), disp);

    cv::Mat h_disp(disp);
    h_disp.convertTo(h_disp, disp_gold.depth());

    EXPECT_MAT_SIMILAR(disp_gold, h_disp, 1e-4);
}

INSTANTIATE_TEST_CASE_P(GPU_Calib3D, StereoConstantSpaceBP, ALL_DEVICES);

///////////////////////////////////////////////////////////////////////////////////////////////////////
// transformPoints

struct TransformPoints : testing::TestWithParam<cv::gpu::DeviceInfo>
{
    cv::gpu::DeviceInfo devInfo;

    virtual void SetUp()
    {
        devInfo = GetParam();

        cv::gpu::setDevice(devInfo.deviceID());
    }
};

GPU_TEST_P(TransformPoints, Accuracy)
{
    cv::Mat src = randomMat(cv::Size(1000, 1), CV_32FC3, 0, 10);
    cv::Mat rvec = randomMat(cv::Size(3, 1), CV_32F, 0, 1);
    cv::Mat tvec = randomMat(cv::Size(3, 1), CV_32F, 0, 1);

    cv::gpu::GpuMat dst;
    cv::gpu::transformPoints(loadMat(src), rvec, tvec, dst);

    ASSERT_EQ(src.size(), dst.size());
    ASSERT_EQ(src.type(), dst.type());

    cv::Mat h_dst(dst);

    cv::Mat rot;
    cv::Rodrigues(rvec, rot);

    for (int i = 0; i < h_dst.cols; ++i)
    {
        cv::Point3f res = h_dst.at<cv::Point3f>(0, i);

        cv::Point3f p = src.at<cv::Point3f>(0, i);
        cv::Point3f res_gold(
                rot.at<float>(0, 0) * p.x + rot.at<float>(0, 1) * p.y + rot.at<float>(0, 2) * p.z + tvec.at<float>(0, 0),
                rot.at<float>(1, 0) * p.x + rot.at<float>(1, 1) * p.y + rot.at<float>(1, 2) * p.z + tvec.at<float>(0, 1),
                rot.at<float>(2, 0) * p.x + rot.at<float>(2, 1) * p.y + rot.at<float>(2, 2) * p.z + tvec.at<float>(0, 2));

        ASSERT_POINT3_NEAR(res_gold, res, 1e-5);
    }
}

INSTANTIATE_TEST_CASE_P(GPU_Calib3D, TransformPoints, ALL_DEVICES);

///////////////////////////////////////////////////////////////////////////////////////////////////////
// ProjectPoints

struct ProjectPoints : testing::TestWithParam<cv::gpu::DeviceInfo>
{
    cv::gpu::DeviceInfo devInfo;

    virtual void SetUp()
    {
        devInfo = GetParam();

        cv::gpu::setDevice(devInfo.deviceID());
    }
};

GPU_TEST_P(ProjectPoints, Accuracy)
{
    cv::Mat src = randomMat(cv::Size(1000, 1), CV_32FC3, 0, 10);
    cv::Mat rvec = randomMat(cv::Size(3, 1), CV_32F, 0, 1);
    cv::Mat tvec = randomMat(cv::Size(3, 1), CV_32F, 0, 1);
    cv::Mat camera_mat = randomMat(cv::Size(3, 3), CV_32F, 0.5, 1);
    camera_mat.at<float>(0, 1) = 0.f;
    camera_mat.at<float>(1, 0) = 0.f;
    camera_mat.at<float>(2, 0) = 0.f;
    camera_mat.at<float>(2, 1) = 0.f;

    cv::gpu::GpuMat dst;
    cv::gpu::projectPoints(loadMat(src), rvec, tvec, camera_mat, cv::Mat(), dst);

    ASSERT_EQ(1, dst.rows);
    ASSERT_EQ(MatType(CV_32FC2), MatType(dst.type()));

    std::vector<cv::Point2f> dst_gold;
    cv::projectPoints(src, rvec, tvec, camera_mat, cv::Mat(1, 8, CV_32F, cv::Scalar::all(0)), dst_gold);

    ASSERT_EQ(dst_gold.size(), static_cast<size_t>(dst.cols));

    cv::Mat h_dst(dst);

    for (size_t i = 0; i < dst_gold.size(); ++i)
    {
        cv::Point2f res = h_dst.at<cv::Point2f>(0, (int)i);
        cv::Point2f res_gold = dst_gold[i];

        ASSERT_LE(cv::norm(res_gold - res) / cv::norm(res_gold), 1e-3f);
    }
}

INSTANTIATE_TEST_CASE_P(GPU_Calib3D, ProjectPoints, ALL_DEVICES);

///////////////////////////////////////////////////////////////////////////////////////////////////////
// SolvePnPRansac

struct SolvePnPRansac : testing::TestWithParam<cv::gpu::DeviceInfo>
{
    cv::gpu::DeviceInfo devInfo;

    virtual void SetUp()
    {
        devInfo = GetParam();

        cv::gpu::setDevice(devInfo.deviceID());
    }
};

GPU_TEST_P(SolvePnPRansac, Accuracy)
{
    // Use RNG with fixed seed to be reproducable
    cv::RNG rng(123456789);
    cv::theRNG() = rng;

    cv::Mat object = cvtest::randomMat(rng, cv::Size(5000, 1), CV_32FC3, 0, 100, false);
    cv::Mat camera_mat = cvtest::randomMat(rng, cv::Size(3, 3), CV_32FC1, 0.5, 1, false);
    camera_mat.at<float>(0, 1) = 0.f;
    camera_mat.at<float>(1, 0) = 0.f;
    camera_mat.at<float>(2, 0) = 0.f;
    camera_mat.at<float>(2, 1) = 0.f;

    std::vector<cv::Point2f> image_vec;
    cv::Mat rvec_gold = cvtest::randomMat(rng, cv::Size(3, 1), CV_32F, 0, 1, false);
    cv::Mat tvec_gold = cvtest::randomMat(rng, cv::Size(3, 1), CV_32F, 0, 1, false);
    cv::projectPoints(object, rvec_gold, tvec_gold, camera_mat, cv::Mat(1, 8, CV_32F, cv::Scalar::all(0)), image_vec);

    cv::Mat rvec, tvec;
    std::vector<int> inliers;
    cv::gpu::solvePnPRansac(object, cv::Mat(1, (int)image_vec.size(), CV_32FC2, &image_vec[0]),
                            camera_mat, cv::Mat(1, 8, CV_32F, cv::Scalar::all(0)),
                            rvec, tvec, false, 200, 2.f, 100, &inliers);

    ASSERT_LE(cv::norm(rvec - rvec_gold), 2e-3);
    ASSERT_LE(cv::norm(tvec - tvec_gold), 2e-3);
}

INSTANTIATE_TEST_CASE_P(GPU_Calib3D, SolvePnPRansac, ALL_DEVICES);

////////////////////////////////////////////////////////////////////////////////
// reprojectImageTo3D

PARAM_TEST_CASE(ReprojectImageTo3D, cv::gpu::DeviceInfo, cv::Size, MatDepth, UseRoi)
{
    cv::gpu::DeviceInfo devInfo;
    cv::Size size;
    int depth;
    bool useRoi;

    virtual void SetUp()
    {
        devInfo = GET_PARAM(0);
        size = GET_PARAM(1);
        depth = GET_PARAM(2);
        useRoi = GET_PARAM(3);

        cv::gpu::setDevice(devInfo.deviceID());
    }
};

GPU_TEST_P(ReprojectImageTo3D, Accuracy)
{
    cv::Mat disp = randomMat(size, depth, 5.0, 30.0);
    cv::Mat Q = randomMat(cv::Size(4, 4), CV_32FC1, 0.1, 1.0);

    cv::gpu::GpuMat dst;
    cv::gpu::reprojectImageTo3D(loadMat(disp, useRoi), dst, Q, 3);

    cv::Mat dst_gold;
    cv::reprojectImageTo3D(disp, dst_gold, Q, false);

    EXPECT_MAT_NEAR(dst_gold, dst, 1e-5);
}

INSTANTIATE_TEST_CASE_P(GPU_Calib3D, ReprojectImageTo3D, testing::Combine(
    ALL_DEVICES,
    DIFFERENT_SIZES,
    testing::Values(MatDepth(CV_8U), MatDepth(CV_16S)),
    WHOLE_SUBMAT));

#endif // HAVE_CUDA
<|endoftext|>


<commit_before>/*****************************************************************************
 * registry.cpp: Windows Registry Manipulation
 ****************************************************************************
 * Copyright (C) 2008 the VideoLAN team
 * $Id$
 *
 * Authors: Andre Weber <WeberAndre # gmx - de>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 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 General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

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

#ifdef WIN32

#include <stdlib.h>
#include "registry.hpp"

QVLCRegistry::QVLCRegistry( HKEY rootKey )
{
    m_RootKey = rootKey;
}

QVLCRegistry::~QVLCRegistry( void )
{
}

bool QVLCRegistry::RegistryKeyExists( const char *path )
{
    HKEY keyHandle;
    if(  RegOpenKeyEx( m_RootKey, path, 0, KEY_READ, &keyHandle ) == ERROR_SUCCESS )
    {
        RegCloseKey( keyHandle );
        return true;
    }
    return false;
}

bool QVLCRegistry::RegistryValueExists( const char *path, const char *valueName )
{
    HKEY keyHandle;
    bool temp = false;
    DWORD size1;
    DWORD valueType;

    if(  RegOpenKeyEx( m_RootKey, path, 0, KEY_READ, &keyHandle ) == ERROR_SUCCESS )
    {
        if( RegQueryValueEx( keyHandle, valueName, NULL,
                             &valueType, NULL, &size1 ) == ERROR_SUCCESS )
        {
           temp = true;
        }
        RegCloseKey( keyHandle );
    }
    return temp;
}

void QVLCRegistry::WriteRegistryInt( const char *path, const char *valueName, int value )
{
    HKEY keyHandle;

    if(  RegCreateKeyEx( m_RootKey, path, 0, NULL, REG_OPTION_NON_VOLATILE,
                         KEY_WRITE, NULL, &keyHandle, NULL )  == ERROR_SUCCESS )
    {
        RegSetValueEx( keyHandle, valueName, 0, REG_DWORD,
                (LPBYTE)&value, sizeof( int ) );
        RegCloseKey( keyHandle );
    }
}

void QVLCRegistry::WriteRegistryString( const char *path, const char *valueName, const char *value )
{
    HKEY keyHandle;

    if(  RegCreateKeyEx( m_RootKey, path, 0, NULL, REG_OPTION_NON_VOLATILE,
                         KEY_WRITE, NULL, &keyHandle, NULL )  == ERROR_SUCCESS )
    {
        RegSetValueEx( keyHandle, valueName, 0, REG_SZ, (LPBYTE)value,
                (DWORD)( strlen( value ) + 1 ) );
        RegCloseKey( keyHandle );
    }
}

void QVLCRegistry::WriteRegistryDouble( const char *path, const char *valueName, double value )
{
    HKEY keyHandle;
    if( RegCreateKeyEx( m_RootKey, path, 0, NULL, REG_OPTION_NON_VOLATILE,
                       KEY_WRITE, NULL, &keyHandle, NULL ) == ERROR_SUCCESS )
    {
        RegSetValueEx( keyHandle, valueName, 0, REG_BINARY, (LPBYTE)&value, sizeof( double ) );
        RegCloseKey( keyHandle );
    }
}

int QVLCRegistry::ReadRegistryInt( const char *path, const char *valueName, int default_value ) {
    HKEY keyHandle;
    int tempValue;
    DWORD size1;
    DWORD valueType;

    if(  RegOpenKeyEx( m_RootKey, path, 0, KEY_READ, &keyHandle ) == ERROR_SUCCESS )
    {
        if( RegQueryValueEx(  keyHandle, valueName, NULL, &valueType, NULL, &size1 ) == ERROR_SUCCESS )
        {
           if( valueType == REG_DWORD )
           {
               if( RegQueryValueEx(  keyHandle, valueName, NULL, &valueType, (LPBYTE)&tempValue, &size1 ) == ERROR_SUCCESS )
               {
                  default_value = tempValue;
               };
           }
        }
        RegCloseKey( keyHandle );
    }
    return default_value;
}

char * QVLCRegistry::ReadRegistryString( const char *path, const char *valueName, const char *default_value )
{
    HKEY keyHandle;
    char *tempValue = NULL;
    char *tempValue2 = NULL;

    DWORD size1;
    DWORD valueType;

    if( RegOpenKeyEx( m_RootKey, path, 0, KEY_READ, &keyHandle ) == ERROR_SUCCESS )
    {
        if( RegQueryValueEx(  keyHandle, valueName, NULL, &valueType, NULL, &size1 ) == ERROR_SUCCESS )
        {
           if( valueType == REG_SZ )
           {
               // free
               tempValue = ( char * )malloc( size1+1 ); // +1 für NullByte`?
               if( RegQueryValueEx(  keyHandle, valueName, NULL, &valueType, (LPBYTE)tempValue, &size1 ) == ERROR_SUCCESS )
               {
                  tempValue2 = tempValue;
               };
           }
        }
        RegCloseKey( keyHandle );
    }

    return tempValue == NULL ? strdup( default_value ) : tempValue2;
}

double QVLCRegistry::ReadRegistryDouble( const char *path, const char *valueName, double default_value )
{
    HKEY keyHandle;
    double tempValue;
    DWORD size1;
    DWORD valueType;

    if( RegOpenKeyEx( m_RootKey, path, 0, KEY_READ, &keyHandle ) == ERROR_SUCCESS )
    {
        if( RegQueryValueEx( keyHandle, valueName, NULL, &valueType,
                             NULL, &size1 ) == ERROR_SUCCESS )
        {
           if( ( valueType == REG_BINARY ) && ( size1 == sizeof( double ) ) )
           {
               if( RegQueryValueEx(  keyHandle, valueName, NULL, &valueType,
                           (LPBYTE)&tempValue, &size1 ) == ERROR_SUCCESS )
               {
                  default_value = tempValue;
               };
           }
        }
        RegCloseKey( keyHandle );
    }
    return default_value;
}

int QVLCRegistry::DeleteValue( const char *path, const char *valueName )
{
    HKEY keyHandle;
    long result;
    if( (result = RegOpenKeyEx(m_RootKey, path, 0, KEY_WRITE, &keyHandle)) == ERROR_SUCCESS)
    {
        result = RegDeleteValue(keyHandle, valueName);
        RegCloseKey(keyHandle);
    }
    //ERROR_SUCCESS = ok everything else you have a problem*g*,
    return result;
}

long QVLCRegistry::DeleteKey( const char *path, const char *keyName )
{
    HKEY keyHandle;
    long result;
    if( (result = RegOpenKeyEx(m_RootKey, path, 0, KEY_WRITE, &keyHandle)) == ERROR_SUCCESS)
    {
         // be warned the key "keyName" will not be deleted if there are subkeys below him, values
        // I think are ok and will be recusively deleted, but not keys...
        // for this case we have to do a little bit more work!
        result = RegDeleteKey(keyHandle, keyName);
        RegCloseKey(keyHandle);
    }
    //ERROR_SUCCESS = ok everything else you have a problem*g*,
    return result;
}

#endif /* WIN32 */
<commit_msg>Qt: fix indentation<commit_after>/*****************************************************************************
 * registry.cpp: Windows Registry Manipulation
 ****************************************************************************
 * Copyright (C) 2008 the VideoLAN team
 * $Id$
 *
 * Authors: Andre Weber <WeberAndre # gmx - de>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 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 General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

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

#ifdef WIN32

#include <stdlib.h>
#include "registry.hpp"

QVLCRegistry::QVLCRegistry( HKEY rootKey )
{
    m_RootKey = rootKey;
}

QVLCRegistry::~QVLCRegistry( void )
{
}

bool QVLCRegistry::RegistryKeyExists( const char *path )
{
    HKEY keyHandle;
    if( RegOpenKeyEx( m_RootKey, path, 0, KEY_READ, &keyHandle ) == ERROR_SUCCESS )
    {
        RegCloseKey( keyHandle );
        return true;
    }
    return false;
}

bool QVLCRegistry::RegistryValueExists( const char *path, const char *valueName )
{
    HKEY keyHandle;
    bool temp = false;
    DWORD size1;
    DWORD valueType;

    if( RegOpenKeyEx( m_RootKey, path, 0, KEY_READ, &keyHandle ) == ERROR_SUCCESS )
    {
        if( RegQueryValueEx( keyHandle, valueName, NULL,
                             &valueType, NULL, &size1 ) == ERROR_SUCCESS )
        {
           temp = true;
        }
        RegCloseKey( keyHandle );
    }
    return temp;
}

void QVLCRegistry::WriteRegistryInt( const char *path, const char *valueName, int value )
{
    HKEY keyHandle;

    if( RegCreateKeyEx( m_RootKey, path, 0, NULL, REG_OPTION_NON_VOLATILE,
                         KEY_WRITE, NULL, &keyHandle, NULL )  == ERROR_SUCCESS )
    {
        RegSetValueEx( keyHandle, valueName, 0, REG_DWORD,
                (LPBYTE)&value, sizeof( int ) );
        RegCloseKey( keyHandle );
    }
}

void QVLCRegistry::WriteRegistryString( const char *path, const char *valueName, const char *value )
{
    HKEY keyHandle;

    if( RegCreateKeyEx( m_RootKey, path, 0, NULL, REG_OPTION_NON_VOLATILE,
                         KEY_WRITE, NULL, &keyHandle, NULL )  == ERROR_SUCCESS )
    {
        RegSetValueEx( keyHandle, valueName, 0, REG_SZ, (LPBYTE)value,
                (DWORD)( strlen( value ) + 1 ) );
        RegCloseKey( keyHandle );
    }
}

void QVLCRegistry::WriteRegistryDouble( const char *path, const char *valueName, double value )
{
    HKEY keyHandle;
    if( RegCreateKeyEx( m_RootKey, path, 0, NULL, REG_OPTION_NON_VOLATILE,
                       KEY_WRITE, NULL, &keyHandle, NULL ) == ERROR_SUCCESS )
    {
        RegSetValueEx( keyHandle, valueName, 0, REG_BINARY, (LPBYTE)&value, sizeof( double ) );
        RegCloseKey( keyHandle );
    }
}

int QVLCRegistry::ReadRegistryInt( const char *path, const char *valueName, int default_value ) {
    HKEY keyHandle;
    int tempValue;
    DWORD size1;
    DWORD valueType;

    if( RegOpenKeyEx( m_RootKey, path, 0, KEY_READ, &keyHandle ) == ERROR_SUCCESS )
    {
        if( RegQueryValueEx(  keyHandle, valueName, NULL, &valueType, NULL, &size1 ) == ERROR_SUCCESS )
        {
           if( valueType == REG_DWORD )
           {
               if( RegQueryValueEx(  keyHandle, valueName, NULL, &valueType, (LPBYTE)&tempValue, &size1 ) == ERROR_SUCCESS )
               {
                  default_value = tempValue;
               };
           }
        }
        RegCloseKey( keyHandle );
    }
    return default_value;
}

char * QVLCRegistry::ReadRegistryString( const char *path, const char *valueName, const char *default_value )
{
    HKEY keyHandle;
    char *tempValue = NULL;
    char *tempValue2 = NULL;

    DWORD size1;
    DWORD valueType;

    if( RegOpenKeyEx( m_RootKey, path, 0, KEY_READ, &keyHandle ) == ERROR_SUCCESS )
    {
        if( RegQueryValueEx(  keyHandle, valueName, NULL, &valueType, NULL, &size1 ) == ERROR_SUCCESS )
        {
           if( valueType == REG_SZ )
           {
               // free
               tempValue = ( char * )malloc( size1+1 ); // +1 für NullByte`?
               if( RegQueryValueEx(  keyHandle, valueName, NULL, &valueType, (LPBYTE)tempValue, &size1 ) == ERROR_SUCCESS )
               {
                  tempValue2 = tempValue;
               };
           }
        }
        RegCloseKey( keyHandle );
    }

    return tempValue == NULL ? strdup( default_value ) : tempValue2;
}

double QVLCRegistry::ReadRegistryDouble( const char *path, const char *valueName, double default_value )
{
    HKEY keyHandle;
    double tempValue;
    DWORD size1;
    DWORD valueType;

    if( RegOpenKeyEx( m_RootKey, path, 0, KEY_READ, &keyHandle ) == ERROR_SUCCESS )
    {
        if( RegQueryValueEx( keyHandle, valueName, NULL, &valueType,
                             NULL, &size1 ) == ERROR_SUCCESS )
        {
           if( ( valueType == REG_BINARY ) && ( size1 == sizeof( double ) ) )
           {
               if( RegQueryValueEx(  keyHandle, valueName, NULL, &valueType,
                           (LPBYTE)&tempValue, &size1 ) == ERROR_SUCCESS )
               {
                  default_value = tempValue;
               };
           }
        }
        RegCloseKey( keyHandle );
    }
    return default_value;
}

int QVLCRegistry::DeleteValue( const char *path, const char *valueName )
{
    HKEY keyHandle;
    long result;
    if( (result = RegOpenKeyEx(m_RootKey, path, 0, KEY_WRITE, &keyHandle)) == ERROR_SUCCESS)
    {
        result = RegDeleteValue(keyHandle, valueName);
        RegCloseKey(keyHandle);
    }
    //ERROR_SUCCESS = ok everything else you have a problem*g*,
    return result;
}

long QVLCRegistry::DeleteKey( const char *path, const char *keyName )
{
    HKEY keyHandle;
    long result;
    if( (result = RegOpenKeyEx(m_RootKey, path, 0, KEY_WRITE, &keyHandle)) == ERROR_SUCCESS)
    {
         // be warned the key "keyName" will not be deleted if there are subkeys below him, values
        // I think are ok and will be recusively deleted, but not keys...
        // for this case we have to do a little bit more work!
        result = RegDeleteKey(keyHandle, keyName);
        RegCloseKey(keyHandle);
    }
    //ERROR_SUCCESS = ok everything else you have a problem*g*,
    return result;
}

#endif /* WIN32 */
<|endoftext|>


<commit_before>#include <cppunit/extensions/HelperMacros.h>
#include "trickle_tests.h"
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <openssl/sha.h>
#include <assert.h>
#include <libcmm.h>
#include <libcmm_irob.h>

#include <pthread.h>
#include "../pthread_util.h"

CPPUNIT_TEST_SUITE_REGISTRATION(TrickleTests);

const size_t NUMINTS = 20;

struct thread_args {
    mc_socket_t sock;
    u_long send_label;
    struct timespec delay;
    int nums[NUMINTS];
};

static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

static void nowake_nanosleep(const struct timespec *duration)
{
    struct timespec time_left;
    struct timespec sleep_time = *duration;
    while (nanosleep(&sleep_time, &time_left) < 0) {
        if (errno != EINTR) {
            perror("nanosleep");
            exit(-1);
        }
        sleep_time = time_left;
    }
}

void *SenderThread(void *arg)
{
    struct thread_args *th_arg = (struct thread_args *)arg;

    int numdeps = 0;
    irob_id_t *deps = NULL;
    irob_id_t last_id = -1;
    size_t next = 0;
    while (next < NUMINTS) {
        nowake_nanosleep(&th_arg->delay);

        PthreadScopedLock lock(&mutex);
        fprintf(stderr, "Sending %s int...\n",
                th_arg->send_label == CMM_LABEL_ONDEMAND ? "FG" : "BG");

        irob_id_t id = begin_irob(th_arg->sock, numdeps, deps,
                                  th_arg->send_label, NULL, NULL);
        CPPUNIT_ASSERT_MESSAGE("begin_irob succeeds", id >= 0);
        last_id = id;
        deps = &last_id;
        numdeps = 1;

        int rc= irob_send(id, &th_arg->nums[next],
                          sizeof(int), 0);
        if (rc >= 0) {
            fprintf(stderr, "...sent, rc=%d\n", rc);
            CPPUNIT_ASSERT_EQUAL_MESSAGE("Integer sent",
                                         (int)sizeof(int), rc);
            rc = end_irob(id);
            CPPUNIT_ASSERT_EQUAL_MESSAGE("IROB completed",
                                         0, rc);
            next++;
        } else {
            fprintf(stderr, "failed! rc=%d, errno=%d\n", rc, errno);
            CPPUNIT_FAIL("Failed to send integer");
        }
    }

    delete th_arg;
    return NULL;
}

void
TrickleTests::testTrickle()
{
    int nums[NUMINTS * 2];
    for (size_t i = 0; i < NUMINTS; ++i) {
        nums[i] = i;
        nums[i + NUMINTS] = i + 1000;
    }

    if (isReceiver()) {
        receiverAssertIntsSorted(nums, NUMINTS*2);
    } else {
        struct thread_args *fg_args = new struct thread_args;
        fg_args->sock = send_sock;
        fg_args->send_label = CMM_LABEL_ONDEMAND;
        fg_args->delay.tv_sec = 0;
        fg_args->delay.tv_nsec = 700000000;

        struct thread_args *bg_args = new struct thread_args;
        bg_args->sock = send_sock;
        bg_args->send_label = CMM_LABEL_BACKGROUND;
        bg_args->delay.tv_sec = 2;
        bg_args->delay.tv_nsec = 0;

        for (size_t i = 0; i < NUMINTS; ++i) {
            fg_args->nums[i] = htonl(nums[i]);
            bg_args->nums[i] = htonl(nums[i + NUMINTS]);
        }

        pthread_t fg_thread, bg_thread;
        int rc = pthread_create(&fg_thread, NULL, SenderThread, fg_args);
        CPPUNIT_ASSERT_EQUAL_MESSAGE("Created FG thread", 0, rc);
        sleep(1);
        rc = pthread_create(&bg_thread, NULL, SenderThread, bg_args);
        CPPUNIT_ASSERT_EQUAL_MESSAGE("Created BG thread", 0, rc);

        pthread_join(fg_thread, NULL);
        pthread_join(bg_thread, NULL);
    }
}
<commit_msg>Trying the trickle test with shorter delays.<commit_after>#include <cppunit/extensions/HelperMacros.h>
#include "trickle_tests.h"
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <openssl/sha.h>
#include <assert.h>
#include <libcmm.h>
#include <libcmm_irob.h>

#include <pthread.h>
#include "../pthread_util.h"

CPPUNIT_TEST_SUITE_REGISTRATION(TrickleTests);

const size_t NUMINTS = 20;

struct thread_args {
    mc_socket_t sock;
    u_long send_label;
    struct timespec delay;
    int nums[NUMINTS];
};

static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

static void nowake_nanosleep(const struct timespec *duration)
{
    struct timespec time_left;
    struct timespec sleep_time = *duration;
    while (nanosleep(&sleep_time, &time_left) < 0) {
        if (errno != EINTR) {
            perror("nanosleep");
            exit(-1);
        }
        sleep_time = time_left;
    }
}

void *SenderThread(void *arg)
{
    struct thread_args *th_arg = (struct thread_args *)arg;

    int numdeps = 0;
    irob_id_t *deps = NULL;
    irob_id_t last_id = -1;
    size_t next = 0;
    while (next < NUMINTS) {
        nowake_nanosleep(&th_arg->delay);

        PthreadScopedLock lock(&mutex);
        fprintf(stderr, "Sending %s int...\n",
                th_arg->send_label == CMM_LABEL_ONDEMAND ? "FG" : "BG");

        irob_id_t id = begin_irob(th_arg->sock, numdeps, deps,
                                  th_arg->send_label, NULL, NULL);
        CPPUNIT_ASSERT_MESSAGE("begin_irob succeeds", id >= 0);
        last_id = id;
        deps = &last_id;
        numdeps = 1;

        int rc= irob_send(id, &th_arg->nums[next],
                          sizeof(int), 0);
        if (rc >= 0) {
            fprintf(stderr, "...sent, rc=%d\n", rc);
            CPPUNIT_ASSERT_EQUAL_MESSAGE("Integer sent",
                                         (int)sizeof(int), rc);
            rc = end_irob(id);
            CPPUNIT_ASSERT_EQUAL_MESSAGE("IROB completed",
                                         0, rc);
            next++;
        } else {
            fprintf(stderr, "failed! rc=%d, errno=%d\n", rc, errno);
            CPPUNIT_FAIL("Failed to send integer");
        }
    }

    delete th_arg;
    return NULL;
}

void
TrickleTests::testTrickle()
{
    int nums[NUMINTS * 2];
    for (size_t i = 0; i < NUMINTS; ++i) {
        nums[i] = i;
        nums[i + NUMINTS] = i + 1000;
    }

    if (isReceiver()) {
        receiverAssertIntsSorted(nums, NUMINTS*2);
    } else {
        struct thread_args *fg_args = new struct thread_args;
        fg_args->sock = send_sock;
        fg_args->send_label = CMM_LABEL_ONDEMAND;
        fg_args->delay.tv_sec = 0;
        fg_args->delay.tv_nsec = 500000000;

        struct thread_args *bg_args = new struct thread_args;
        bg_args->sock = send_sock;
        bg_args->send_label = CMM_LABEL_BACKGROUND;
        bg_args->delay.tv_sec = 0;
        bg_args->delay.tv_nsec = 600000000;

        for (size_t i = 0; i < NUMINTS; ++i) {
            fg_args->nums[i] = htonl(nums[i]);
            bg_args->nums[i] = htonl(nums[i + NUMINTS]);
        }

        pthread_t fg_thread, bg_thread;
        int rc = pthread_create(&fg_thread, NULL, SenderThread, fg_args);
        CPPUNIT_ASSERT_EQUAL_MESSAGE("Created FG thread", 0, rc);
        sleep(1);
        rc = pthread_create(&bg_thread, NULL, SenderThread, bg_args);
        CPPUNIT_ASSERT_EQUAL_MESSAGE("Created BG thread", 0, rc);

        pthread_join(fg_thread, NULL);
        pthread_join(bg_thread, NULL);
    }
}
<|endoftext|>


<commit_before>// -*- mode:c++;tab-width:2;indent-tabs-mode:t;show-trailing-whitespace:t;rm-trailing-spaces:t -*-
// vi: set ts=2 noet:
//
// Copyright (c) 2016 Sergey Lyskov <sergey.lyskov@jhu.edu>
//
// All rights reserved. Use of this source code is governed by a
// MIT license that can be found in the LICENSE file.

/// @file   binder/binder.cpp
/// @brief  Main
/// @author Sergey Lyskov

#include <binder.hpp>

// Declares clang::SyntaxOnlyAction.
#include "clang/Frontend/FrontendActions.h"
#include "clang/Tooling/CommonOptionsParser.h"
#include "clang/Tooling/Tooling.h"

#include <clang/AST/RecursiveASTVisitor.h>
#include <clang/Basic/SourceLocation.h>
#include <clang/Frontend/CompilerInstance.h>
#include <clang/AST/Comment.h>

// Declares llvm::cl::extrahelp.
#include "llvm/Support/CommandLine.h"

#include <context.hpp>
#include <enum.hpp>
#include <function.hpp>
#include <class.hpp>
#include <util.hpp>

#include <clang/Basic/Diagnostic.h>

using namespace clang::tooling;
using namespace llvm;

// Apply a custom category to all command-line options so that they are the
// only ones displayed.
static llvm::cl::OptionCategory BinderToolCategory("Binder options");

// CommonOptionsParser declares HelpMessage with a description of the common
// command-line options related to the compilation database and input files.
// It's nice to have this help message in all tools.
static cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage);

// A help message for this specific tool can be added afterwards.
static cl::extrahelp MoreHelp("\nMore help text...\n");

using binder::Config;

using namespace clang;

using std::string;

cl::opt<std::string> O_root_module("root-module", cl::desc("Name of root module"), /*cl::init("example"),*/ cl::cat(BinderToolCategory));

cl::opt<int> O_max_file_size("max-file-size", cl::desc("Specify maximum length of generated source files"), cl::init(1024*16), cl::cat(BinderToolCategory));

cl::opt<std::string> O_prefix("prefix", cl::desc("Output prefix for all generated files. Might contain directories."), cl::init(""), cl::cat(BinderToolCategory));

cl::list<std::string> O_bind("bind", cl::desc("Namespace to bind, could be specified more then once. Specify \"\" to bind all namespaces."), cl::cat(BinderToolCategory)); // , cl::OneOrMore
cl::list<std::string> O_skip("skip", cl::desc("Namespace to skip, could be specified more then once"), cl::cat(BinderToolCategory)); // , cl::OneOrMore

cl::opt<std::string> O_config("config", cl::desc("Specify config file from which bindings setting will be read"), cl::init(""), cl::cat(BinderToolCategory));

cl::opt<bool> O_annotate_includes("annotate-includes", cl::desc("Annotate each includes in generated code with type name that trigger it inclusion"), cl::init(false), cl::cat(BinderToolCategory));

cl::opt<bool> O_single_file("single-file", cl::desc("Concatenate all binder output into single file with name: root-module-name + '.cpp'. Use this for a small projects and for testing."), cl::init(false), cl::cat(BinderToolCategory));

cl::opt<bool> O_trace("trace", cl::desc("Add tracer output for each binded object (i.e. for debugging)"), cl::init(false), cl::cat(BinderToolCategory));

cl::opt<bool> O_verbose("v", cl::desc("Increase verbosity of output"), cl::init(false), cl::cat(BinderToolCategory));

cl::opt<bool> O_suppress_errors("suppress-errors", cl::desc("Suppres all the compilers errors. This option could be useful when you want to tell Binder to ignore non-critical errors (for example due to missing includes) and generate binding for part of code that Binder was able to parse"), cl::init(false), cl::cat(BinderToolCategory));

class ClassVisitor : public RecursiveASTVisitor<ClassVisitor>
{
public:
    explicit ClassVisitor(DeclContext *dc) /*: decl_context(dc)*/ {}

	virtual ~ClassVisitor() {}

	virtual bool VisitEnumDecl(EnumDecl *record) {
		errs() << "ClassVisitor EnumDecl: " << record->getQualifiedNameAsString() << "\n";
		record->dump();
        return true;
	}

private:
    //DeclContext *decl_context;
};

string wrap_CXXRecordDecl(CXXRecordDecl *R)
{
	ClassVisitor v{R};
	v.TraverseDecl( R );
	//R->dump();
	return "";
}

class BinderVisitor : public RecursiveASTVisitor<BinderVisitor>
{
public:
    explicit BinderVisitor(CompilerInstance *ci) : ast_context( &( ci->getASTContext() ) )
	{
		Config & config = Config::get();

		config.root_module = O_root_module;
		config.prefix = O_prefix;
		config.maximum_file_length = O_max_file_size;

		config.namespaces_to_bind = O_bind;
		config.namespaces_to_skip = O_skip;

		if( O_config.size() ) config.read(O_config);
		if( O_suppress_errors )	{
			clang::DiagnosticsEngine& di = ci->getDiagnostics();
			di.setSuppressAllDiagnostics();
		}
	}

	virtual ~BinderVisitor() {}

	bool shouldVisitTemplateInstantiations () const { return true; }

	virtual bool VisitFunctionDecl(FunctionDecl *F)
	{
		if( F->isCXXInstanceMember() or isa<CXXMethodDecl>(F) ) return true;

		if( binder::is_bindable(F) ) {
			binder::BinderOP b = std::make_shared<binder::FunctionBinder>(F);
			context.add(b);
		} else if( F->isOverloadedOperator()  and  F->getNameAsString() == "operator<<" ) {
			//outs() << "Adding insertion operator: " << binder::function_pointer_type(F) << "\n";
			context.add_insertion_operator(F);
		}

        return true;
    }

	virtual bool VisitCXXRecordDecl(CXXRecordDecl *C) {
		if( C->isCXXInstanceMember()  or  C->isCXXClassMember() ) return true;

		if( binder::is_bindable(C) ) {
			binder::BinderOP b = std::make_shared<binder::ClassBinder>(C);
			context.add(b);
		}

        return true;
    }

	// virtual bool VisitClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl *C) {
	// 	if( FullSourceLoc(C->getLocation(), ast_context->getSourceManager() ).isInSystemHeader() ) return true;
	// 	errs() << "Visit ClassTemplateSpecializationDecl:" << C->getQualifiedNameAsString() << binder::template_specialization(C) << "\n";
	// 	C->dump();
    //     return true;
	// }

	// virtual bool VisitTemplateDecl(TemplateDecl *record) {
	// 	//if( FullSourceLoc(record->getLocation(), ast_context->getSourceManager() ).isInSystemHeader() ) return true;
	// 	errs() << "Visit TemplateDecl: " << record->getQualifiedNameAsString() << "\n";
	// 	//record->dump();
    //     return true;
	// }

	// virtual bool VisitClassTemplateDecl(ClassTemplateDecl *record) {
	// 	//if( FullSourceLoc(record->getLocation(), ast_context->getSourceManager() ).isInSystemHeader() ) return true;
	// 	errs() << "Visit ClassTemplateDecl: " << record->getQualifiedNameAsString() << binder::template_specialization( record->getTemplatedDecl() ) << "\n";
	// 	//record->dump();
    //     return true;
	// }

	// virtual bool VisitTypedefDecl(TypedefDecl *T) {
	// 	if( FullSourceLoc(T->getLocation(), ast_context->getSourceManager() ).isInSystemHeader() ) return true;
	// 	//errs() << "Visit TypedefDecl: " << T->getQualifiedNameAsString() << "  Type: " << T->getUnderlyingType()->getCanonicalTypeInternal()/*getCanonicalType()*/.getAsString() << "\n";
	// 	// record->dump();
    //     return true;
	// }

	// virtual bool VisitNamedDecl(NamedDecl *record) {
	// 	errs() << "Visit NamedRecord: " << record->getQualifiedNameAsString() << "\n";
    //     return true;
	// }

	// virtual bool VisitFieldDecl(FieldDecl *record) {
	// 	errs() << "Visit FieldDecl: " << record->getQualifiedNameAsString() << "\n";
	// 	record->dump();
    //     return true;
	// }

	virtual bool VisitEnumDecl(EnumDecl *E) {
		if( E->isCXXInstanceMember()  or  E->isCXXClassMember() ) return true;

		binder::BinderOP b = std::make_shared<binder::EnumBinder>( E/*->getCanonicalDecl()*/ );
		context.add(b);

        return true;
	}

	void generate(void) {
		context.generate( Config::get() );
	}

private:
    ASTContext *ast_context;

	binder::Context context;
};

class BinderASTConsumer : public ASTConsumer
{
private:
    std::unique_ptr<BinderVisitor> visitor;

public:
    // override the constructor in order to pass CI
    explicit BinderASTConsumer(CompilerInstance *ci) : visitor(new BinderVisitor(ci)) {}

    // override this to call our ExampleVisitor on the entire source file
    virtual void HandleTranslationUnit(ASTContext &context)
	{
        visitor->TraverseDecl( context.getTranslationUnitDecl() );
		visitor->generate();
    }
};

class BinderFrontendAction : public ASTFrontendAction {
public:
    virtual std::unique_ptr<clang::ASTConsumer> CreateASTConsumer(CompilerInstance &ci, StringRef file) {
        return std::unique_ptr<ASTConsumer>( new BinderASTConsumer(&ci) );
    }
};

int main(int argc, const char **argv)
{
	CommonOptionsParser op(argc, argv, BinderToolCategory);

	ClangTool tool(op.getCompilations(), op.getSourcePathList());
	//outs() << "Root module: " << O_root_module << "\n";
	//for(auto &s : O_bind) outs() << "Binding: '" << s << "'\n";

	return tool.run(newFrontendActionFactory<BinderFrontendAction>().get());
}
<commit_msg>Update binder.cpp<commit_after>// -*- mode:c++;tab-width:2;indent-tabs-mode:t;show-trailing-whitespace:t;rm-trailing-spaces:t -*-
// vi: set ts=2 noet:
//
// Copyright (c) 2016 Sergey Lyskov <sergey.lyskov@jhu.edu>
//
// All rights reserved. Use of this source code is governed by a
// MIT license that can be found in the LICENSE file.

/// @file   binder/binder.cpp
/// @brief  Main
/// @author Sergey Lyskov

#include <binder.hpp>

// Declares clang::SyntaxOnlyAction.
#include "clang/Frontend/FrontendActions.h"
#include "clang/Tooling/CommonOptionsParser.h"
#include "clang/Tooling/Tooling.h"

#include <clang/AST/RecursiveASTVisitor.h>
#include <clang/Basic/SourceLocation.h>
#include <clang/Frontend/CompilerInstance.h>
#include <clang/AST/Comment.h>
#include <clang/Basic/Diagnostic.h>

#include <llvm/Support/CommandLine.h> // Declares llvm::cl::extrahelp

#include <context.hpp>
#include <enum.hpp>
#include <function.hpp>
#include <class.hpp>
#include <util.hpp>

using namespace clang::tooling;
using namespace llvm;

// Apply a custom category to all command-line options so that they are the
// only ones displayed.
static llvm::cl::OptionCategory BinderToolCategory("Binder options");

// CommonOptionsParser declares HelpMessage with a description of the common
// command-line options related to the compilation database and input files.
// It's nice to have this help message in all tools.
static cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage);

// A help message for this specific tool can be added afterwards.
static cl::extrahelp MoreHelp("\nMore help text...\n");

using binder::Config;

using namespace clang;

using std::string;

cl::opt<std::string> O_root_module("root-module", cl::desc("Name of root module"), /*cl::init("example"),*/ cl::cat(BinderToolCategory));

cl::opt<int> O_max_file_size("max-file-size", cl::desc("Specify maximum length of generated source files"), cl::init(1024*16), cl::cat(BinderToolCategory));

cl::opt<std::string> O_prefix("prefix", cl::desc("Output prefix for all generated files. Might contain directories."), cl::init(""), cl::cat(BinderToolCategory));

cl::list<std::string> O_bind("bind", cl::desc("Namespace to bind, could be specified more then once. Specify \"\" to bind all namespaces."), cl::cat(BinderToolCategory)); // , cl::OneOrMore
cl::list<std::string> O_skip("skip", cl::desc("Namespace to skip, could be specified more then once"), cl::cat(BinderToolCategory)); // , cl::OneOrMore

cl::opt<std::string> O_config("config", cl::desc("Specify config file from which bindings setting will be read"), cl::init(""), cl::cat(BinderToolCategory));

cl::opt<bool> O_annotate_includes("annotate-includes", cl::desc("Annotate each includes in generated code with type name that trigger it inclusion"), cl::init(false), cl::cat(BinderToolCategory));

cl::opt<bool> O_single_file("single-file", cl::desc("Concatenate all binder output into single file with name: root-module-name + '.cpp'. Use this for a small projects and for testing."), cl::init(false), cl::cat(BinderToolCategory));

cl::opt<bool> O_trace("trace", cl::desc("Add tracer output for each binded object (i.e. for debugging)"), cl::init(false), cl::cat(BinderToolCategory));

cl::opt<bool> O_verbose("v", cl::desc("Increase verbosity of output"), cl::init(false), cl::cat(BinderToolCategory));

cl::opt<bool> O_suppress_errors("suppress-errors", cl::desc("Suppres all the compilers errors. This option could be useful when you want to tell Binder to ignore non-critical errors (for example due to missing includes) and generate binding for part of code that Binder was able to parse"), cl::init(false), cl::cat(BinderToolCategory));

class ClassVisitor : public RecursiveASTVisitor<ClassVisitor>
{
public:
    explicit ClassVisitor(DeclContext *dc) /*: decl_context(dc)*/ {}

	virtual ~ClassVisitor() {}

	virtual bool VisitEnumDecl(EnumDecl *record) {
		errs() << "ClassVisitor EnumDecl: " << record->getQualifiedNameAsString() << "\n";
		record->dump();
        return true;
	}

private:
    //DeclContext *decl_context;
};

string wrap_CXXRecordDecl(CXXRecordDecl *R)
{
	ClassVisitor v{R};
	v.TraverseDecl( R );
	//R->dump();
	return "";
}

class BinderVisitor : public RecursiveASTVisitor<BinderVisitor>
{
public:
    explicit BinderVisitor(CompilerInstance *ci) : ast_context( &( ci->getASTContext() ) )
	{
		Config & config = Config::get();

		config.root_module = O_root_module;
		config.prefix = O_prefix;
		config.maximum_file_length = O_max_file_size;

		config.namespaces_to_bind = O_bind;
		config.namespaces_to_skip = O_skip;

		if( O_config.size() ) config.read(O_config);
		if( O_suppress_errors )	{
			clang::DiagnosticsEngine& di = ci->getDiagnostics();
			di.setSuppressAllDiagnostics();
		}
	}

	virtual ~BinderVisitor() {}

	bool shouldVisitTemplateInstantiations () const { return true; }

	virtual bool VisitFunctionDecl(FunctionDecl *F)
	{
		if( F->isCXXInstanceMember() or isa<CXXMethodDecl>(F) ) return true;

		if( binder::is_bindable(F) ) {
			binder::BinderOP b = std::make_shared<binder::FunctionBinder>(F);
			context.add(b);
		} else if( F->isOverloadedOperator()  and  F->getNameAsString() == "operator<<" ) {
			//outs() << "Adding insertion operator: " << binder::function_pointer_type(F) << "\n";
			context.add_insertion_operator(F);
		}

        return true;
    }

	virtual bool VisitCXXRecordDecl(CXXRecordDecl *C) {
		if( C->isCXXInstanceMember()  or  C->isCXXClassMember() ) return true;

		if( binder::is_bindable(C) ) {
			binder::BinderOP b = std::make_shared<binder::ClassBinder>(C);
			context.add(b);
		}

        return true;
    }

	// virtual bool VisitClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl *C) {
	// 	if( FullSourceLoc(C->getLocation(), ast_context->getSourceManager() ).isInSystemHeader() ) return true;
	// 	errs() << "Visit ClassTemplateSpecializationDecl:" << C->getQualifiedNameAsString() << binder::template_specialization(C) << "\n";
	// 	C->dump();
    //     return true;
	// }

	// virtual bool VisitTemplateDecl(TemplateDecl *record) {
	// 	//if( FullSourceLoc(record->getLocation(), ast_context->getSourceManager() ).isInSystemHeader() ) return true;
	// 	errs() << "Visit TemplateDecl: " << record->getQualifiedNameAsString() << "\n";
	// 	//record->dump();
    //     return true;
	// }

	// virtual bool VisitClassTemplateDecl(ClassTemplateDecl *record) {
	// 	//if( FullSourceLoc(record->getLocation(), ast_context->getSourceManager() ).isInSystemHeader() ) return true;
	// 	errs() << "Visit ClassTemplateDecl: " << record->getQualifiedNameAsString() << binder::template_specialization( record->getTemplatedDecl() ) << "\n";
	// 	//record->dump();
    //     return true;
	// }

	// virtual bool VisitTypedefDecl(TypedefDecl *T) {
	// 	if( FullSourceLoc(T->getLocation(), ast_context->getSourceManager() ).isInSystemHeader() ) return true;
	// 	//errs() << "Visit TypedefDecl: " << T->getQualifiedNameAsString() << "  Type: " << T->getUnderlyingType()->getCanonicalTypeInternal()/*getCanonicalType()*/.getAsString() << "\n";
	// 	// record->dump();
    //     return true;
	// }

	// virtual bool VisitNamedDecl(NamedDecl *record) {
	// 	errs() << "Visit NamedRecord: " << record->getQualifiedNameAsString() << "\n";
    //     return true;
	// }

	// virtual bool VisitFieldDecl(FieldDecl *record) {
	// 	errs() << "Visit FieldDecl: " << record->getQualifiedNameAsString() << "\n";
	// 	record->dump();
    //     return true;
	// }

	virtual bool VisitEnumDecl(EnumDecl *E) {
		if( E->isCXXInstanceMember()  or  E->isCXXClassMember() ) return true;

		binder::BinderOP b = std::make_shared<binder::EnumBinder>( E/*->getCanonicalDecl()*/ );
		context.add(b);

        return true;
	}

	void generate(void) {
		context.generate( Config::get() );
	}

private:
    ASTContext *ast_context;

	binder::Context context;
};

class BinderASTConsumer : public ASTConsumer
{
private:
    std::unique_ptr<BinderVisitor> visitor;

public:
    // override the constructor in order to pass CI
    explicit BinderASTConsumer(CompilerInstance *ci) : visitor(new BinderVisitor(ci)) {}

    // override this to call our ExampleVisitor on the entire source file
    virtual void HandleTranslationUnit(ASTContext &context)
	{
        visitor->TraverseDecl( context.getTranslationUnitDecl() );
		visitor->generate();
    }
};

class BinderFrontendAction : public ASTFrontendAction {
public:
    virtual std::unique_ptr<clang::ASTConsumer> CreateASTConsumer(CompilerInstance &ci, StringRef file) {
        return std::unique_ptr<ASTConsumer>( new BinderASTConsumer(&ci) );
    }
};

int main(int argc, const char **argv)
{
	CommonOptionsParser op(argc, argv, BinderToolCategory);

	ClangTool tool(op.getCompilations(), op.getSourcePathList());
	//outs() << "Root module: " << O_root_module << "\n";
	//for(auto &s : O_bind) outs() << "Binding: '" << s << "'\n";

	return tool.run(newFrontendActionFactory<BinderFrontendAction>().get());
}
<|endoftext|>


<commit_before>//
// Created by redwards on 10/3/18.
//
// Normalize the rapsearch hits. This just sums the counts and then prints the numbers
#include <iostream>
#include <fstream>
#include <string>
#include <cstring>
#include <sstream>
using namespace std;

int main (int argc, char* argv[]) {

    if ( argc < 3) {
        cerr << "Usage: " << argv[0] << " <file to normalize> <directory to write to>\n";
        return 1;
    }

    ifstream counts;
    counts.open(argv[1]);
    if (!counts) {
        cerr << "Unable to open the input file" << argv[1];
        return 1;
    }

    string line;
    ostringstream p;
    p << argv[2] << '/' << argv[1] << endl;
    ofstream outs(p.str());
    if (!outs) {
        cerr << "Unable to open the output file " << p.str();
        argv[1];
        return 2;
    }

    int c=0;

    while (counts >> line)
    {
        // note this makes a stream from the string
        istringstream iss(line);
        cout << " read: " << line;
        int c;
        string peg;
        iss >> c;
        iss >> peg;
        cout << " peg : " << peg << " count: " << c;

    }

    return 0;
}

<commit_msg>normalizing counts<commit_after>//
// Created by redwards on 10/3/18.
//
// Normalize the rapsearch hits. This just sums the counts and then prints the numbers
#include <iostream>
#include <fstream>
#include <string>
#include <cstring>
#include <sstream>
#include <map>
using namespace std;

int main (int argc, char* argv[]) {

    if ( argc < 3) {
        cerr << "Usage: " << argv[0] << " <file to normalize> <directory to write to>\n";
        return 1;
    }

    ifstream counts;
    counts.open(argv[1]);
    if (!counts) {
        cerr << "Unable to open the input file" << argv[1];
        return 1;
    }

    int total=0;
    map<string, int> pegcounts;
    int c; string peg;
    // read each line and split into two tokens
    while (counts >> c >> peg)
    {
        pegcounts[peg] = c;
        total += c;
    }
    counts.close();

    ostringstream p;
    p << argv[2] << '/' << argv[1];
    ofstream outs(p.str());
    if (!outs) {
        cerr << "Unable to open the output file " << p.str() << endl;
        argv[1];
        return 2;
    }

    for( auto const& [key, val] : pegcounts )
    {
        outs << key << " " << (float) val/ (float) total << endl;
    }
    outs.close();

    return 0;
}

<|endoftext|>


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

#ifndef CADSCENE_H__
#define CADSCENE_H__

#include <nv_math/nv_math.h>
#include <vector>

class CadScene {

public:

  struct BBox {
    nv_math::vec4f    min;
    nv_math::vec4f    max;

    BBox() : min(FLT_MAX), max(FLT_MIN) {}

    inline void merge( const nv_math::vec4f& point )
    {
      min = nv_math::nv_min(min, point);
      max = nv_math::nv_max(max, point);
    }

    inline void merge( const BBox& bbox )
    {
     min = nv_math::nv_min(min, bbox.min);
     max = nv_math::nv_max(max, bbox.max);
    }

    inline BBox transformed ( const nv_math::mat4f &matrix, int dim=3)
    {
      int i;
      nv_math::vec4f box[16];
      // create box corners
      box[0] = nv_math::vec4f(min.x,min.y,min.z,min.w);
      box[1] = nv_math::vec4f(max.x,min.y,min.z,min.w);
      box[2] = nv_math::vec4f(min.x,max.y,min.z,min.w);
      box[3] = nv_math::vec4f(max.x,max.y,min.z,min.w);
      box[4] = nv_math::vec4f(min.x,min.y,max.z,min.w);
      box[5] = nv_math::vec4f(max.x,min.y,max.z,min.w);
      box[6] = nv_math::vec4f(min.x,max.y,max.z,min.w);
      box[7] = nv_math::vec4f(max.x,max.y,max.z,min.w);

      box[8] = nv_math::vec4f(min.x,min.y,min.z,max.w);
      box[9] = nv_math::vec4f(max.x,min.y,min.z,max.w);
      box[10] = nv_math::vec4f(min.x,max.y,min.z,max.w);
      box[11] = nv_math::vec4f(max.x,max.y,min.z,max.w);
      box[12] = nv_math::vec4f(min.x,min.y,max.z,max.w);
      box[13] = nv_math::vec4f(max.x,min.y,max.z,max.w);
      box[14] = nv_math::vec4f(min.x,max.y,max.z,max.w);
      box[15] = nv_math::vec4f(max.x,max.y,max.z,max.w);

      // transform box corners
      // and find new mins,maxs
      BBox bbox;

      for (i = 0; i < (1<<dim) ; i++){
        nv_math::vec4f point = matrix * box[i];
        bbox.merge(point);
      }

      return bbox;
    }
  };

  struct MaterialSide {
    nv_math::vec4f ambient;
    nv_math::vec4f diffuse;
    nv_math::vec4f specular;
    nv_math::vec4f emissive;
  };

  // need to keep this 256 byte aligned (UBO range)
  struct Material {
    MaterialSide        sides[2];
    unsigned int        _pad[32];

    Material() {
      memset(this,0,sizeof(Material));
    }
  };

  // need to keep this 256 byte aligned (UBO range)
  struct MatrixNode {
    nv_math::mat4f  worldMatrix;
    nv_math::mat4f  worldMatrixIT;
    nv_math::mat4f  objectMatrix;
    nv_math::mat4f  objectMatrixIT;
  };

  struct Vertex {
    nv_math::vec4f position;
    nv_math::vec4f normal;
  };

  struct DrawRange {
    size_t        offset;
    int           count;

    DrawRange() : offset(0) , count(0) {}
  };

  struct DrawStateInfo {
    int           materialIndex;
    int           matrixIndex;

    friend bool operator != ( const DrawStateInfo &lhs,  const DrawStateInfo &rhs){
      return lhs.materialIndex != rhs.materialIndex || lhs.matrixIndex != rhs.matrixIndex;
    }

    friend bool operator == ( const DrawStateInfo &lhs,  const DrawStateInfo &rhs){
      return lhs.materialIndex == rhs.materialIndex && lhs.matrixIndex == rhs.matrixIndex;
    }
  };

  struct DrawRangeCache {
    std::vector<DrawStateInfo>    state;
    std::vector<int>          stateCount;

    std::vector<size_t>       offsets;
    std::vector<int>          counts;
  };

  struct GeometryPart {
    DrawRange     indexSolid;
    DrawRange     indexWire;
  };

  struct Geometry {
    int       cloneIdx;
    size_t    vboSize;
    size_t    iboSize;

    Vertex*       vertices;
    unsigned int* indices;

    std::vector<GeometryPart> parts;

    int       numVertices;
    int       numIndexSolid;
    int       numIndexWire;
  };

  struct ObjectPart {
    int   active;
    int   materialIndex;
    int   matrixIndex;
  };

  struct Object {
    int             matrixIndex;
    int             geometryIndex;

    std::vector<ObjectPart> parts;

    DrawRangeCache  cacheSolid;
    DrawRangeCache  cacheWire;
  };

  std::vector<Material>       m_materials;
  std::vector<BBox>           m_geometryBboxes;
  std::vector<Geometry>       m_geometry;
  std::vector<MatrixNode>     m_matrices;
  std::vector<Object>         m_objects;
  std::vector<nv_math::vec2i> m_objectAssigns;

  BBox      m_bbox;

  void  updateObjectDrawCache(Object& object);

  bool  loadCSF(const char* filename, int clones = 0, int cloneaxis = 3);
  void  unload();

};

#endif

<commit_msg>bbox init bug<commit_after>/*-----------------------------------------------------------------------
  Copyright (c) 2014-2016, NVIDIA. All rights reserved.
  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions
  are met:
   * Redistributions of source code must retain the above copyright
     notice, this list of conditions and the following disclaimer.
   * Neither the name of its contributors may be used to endorse
     or promote products derived from this software without specific
     prior written permission.
  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-----------------------------------------------------------------------*/
/* Contact ckubisch@nvidia.com (Christoph Kubisch) for feedback */

#ifndef CADSCENE_H__
#define CADSCENE_H__

#include <nv_math/nv_math.h>
#include <vector>

class CadScene {

public:

  struct BBox {
    nv_math::vec4f    min;
    nv_math::vec4f    max;

    BBox() : min(FLT_MAX), max(-FLT_MAX) {}

    inline void merge( const nv_math::vec4f& point )
    {
      min = nv_math::nv_min(min, point);
      max = nv_math::nv_max(max, point);
    }

    inline void merge( const BBox& bbox )
    {
     min = nv_math::nv_min(min, bbox.min);
     max = nv_math::nv_max(max, bbox.max);
    }

    inline BBox transformed ( const nv_math::mat4f &matrix, int dim=3)
    {
      int i;
      nv_math::vec4f box[16];
      // create box corners
      box[0] = nv_math::vec4f(min.x,min.y,min.z,min.w);
      box[1] = nv_math::vec4f(max.x,min.y,min.z,min.w);
      box[2] = nv_math::vec4f(min.x,max.y,min.z,min.w);
      box[3] = nv_math::vec4f(max.x,max.y,min.z,min.w);
      box[4] = nv_math::vec4f(min.x,min.y,max.z,min.w);
      box[5] = nv_math::vec4f(max.x,min.y,max.z,min.w);
      box[6] = nv_math::vec4f(min.x,max.y,max.z,min.w);
      box[7] = nv_math::vec4f(max.x,max.y,max.z,min.w);

      box[8] = nv_math::vec4f(min.x,min.y,min.z,max.w);
      box[9] = nv_math::vec4f(max.x,min.y,min.z,max.w);
      box[10] = nv_math::vec4f(min.x,max.y,min.z,max.w);
      box[11] = nv_math::vec4f(max.x,max.y,min.z,max.w);
      box[12] = nv_math::vec4f(min.x,min.y,max.z,max.w);
      box[13] = nv_math::vec4f(max.x,min.y,max.z,max.w);
      box[14] = nv_math::vec4f(min.x,max.y,max.z,max.w);
      box[15] = nv_math::vec4f(max.x,max.y,max.z,max.w);

      // transform box corners
      // and find new mins,maxs
      BBox bbox;

      for (i = 0; i < (1<<dim) ; i++){
        nv_math::vec4f point = matrix * box[i];
        bbox.merge(point);
      }

      return bbox;
    }
  };

  struct MaterialSide {
    nv_math::vec4f ambient;
    nv_math::vec4f diffuse;
    nv_math::vec4f specular;
    nv_math::vec4f emissive;
  };

  // need to keep this 256 byte aligned (UBO range)
  struct Material {
    MaterialSide        sides[2];
    unsigned int        _pad[32];

    Material() {
      memset(this,0,sizeof(Material));
    }
  };

  // need to keep this 256 byte aligned (UBO range)
  struct MatrixNode {
    nv_math::mat4f  worldMatrix;
    nv_math::mat4f  worldMatrixIT;
    nv_math::mat4f  objectMatrix;
    nv_math::mat4f  objectMatrixIT;
  };

  struct Vertex {
    nv_math::vec4f position;
    nv_math::vec4f normal;
  };

  struct DrawRange {
    size_t        offset;
    int           count;

    DrawRange() : offset(0) , count(0) {}
  };

  struct DrawStateInfo {
    int           materialIndex;
    int           matrixIndex;

    friend bool operator != ( const DrawStateInfo &lhs,  const DrawStateInfo &rhs){
      return lhs.materialIndex != rhs.materialIndex || lhs.matrixIndex != rhs.matrixIndex;
    }

    friend bool operator == ( const DrawStateInfo &lhs,  const DrawStateInfo &rhs){
      return lhs.materialIndex == rhs.materialIndex && lhs.matrixIndex == rhs.matrixIndex;
    }
  };

  struct DrawRangeCache {
    std::vector<DrawStateInfo>    state;
    std::vector<int>          stateCount;

    std::vector<size_t>       offsets;
    std::vector<int>          counts;
  };

  struct GeometryPart {
    DrawRange     indexSolid;
    DrawRange     indexWire;
  };

  struct Geometry {
    int       cloneIdx;
    size_t    vboSize;
    size_t    iboSize;

    Vertex*       vertices;
    unsigned int* indices;

    std::vector<GeometryPart> parts;

    int       numVertices;
    int       numIndexSolid;
    int       numIndexWire;
  };

  struct ObjectPart {
    int   active;
    int   materialIndex;
    int   matrixIndex;
  };

  struct Object {
    int             matrixIndex;
    int             geometryIndex;

    std::vector<ObjectPart> parts;

    DrawRangeCache  cacheSolid;
    DrawRangeCache  cacheWire;
  };

  std::vector<Material>       m_materials;
  std::vector<BBox>           m_geometryBboxes;
  std::vector<Geometry>       m_geometry;
  std::vector<MatrixNode>     m_matrices;
  std::vector<Object>         m_objects;
  std::vector<nv_math::vec2i> m_objectAssigns;

  BBox      m_bbox;

  void  updateObjectDrawCache(Object& object);

  bool  loadCSF(const char* filename, int clones = 0, int cloneaxis = 3);
  void  unload();

};

#endif

<|endoftext|>


<commit_before>#pragma once

#include "acmacs-base/fmt.hh"

// ----------------------------------------------------------------------

namespace injson
{
    inline namespace v1
    {
        class error : public std::runtime_error
        {
          public:
            template <typename S> error(size_t line_no, ssize_t column_no, S&& message) : std::runtime_error(fmt::format("injson error at {}:{}: {}", line_no, column_no, message)) {}
        };

        namespace detail
        {
            template <typename Iter> Iter read_string(Iter first, Iter last, Iter& line_start, size_t& line_no)
            {
                bool esc = false;
                for (; first != last; ++first) {
                    switch (*first) {
                      case '"':
                          if (!esc)
                              return first;
                          esc = false;
                          break;
                      case '\\':
                          esc = !esc;
                          break;
                      case '\n':
                          esc = false;
                          ++line_no;
                          line_start = first + 1;
                          break;
                      default:
                          esc = false;
                          break;
                    }
                }
                throw error(line_no, first - line_start, "unexpected EOF");
            }

            enum class number_is { integer, real };
            template <typename Iter> std::pair<Iter, number_is> read_number(Iter first, Iter last)
            {
                number_is nis = number_is::integer;
                for (; first != last; ++first) {
                    switch (*first) {
                        case '0':
                        case '1':
                        case '2':
                        case '3':
                        case '4':
                        case '5':
                        case '6':
                        case '7':
                        case '8':
                        case '9':
                            break;
                        case '.':
                        case '-':
                        case 'e':
                        case 'E':
                            nis = number_is::real;
                            break;
                        default:
                            return {first, nis};
                    }
                }
                throw error(0, 0, "read_number internal");
            }
        } // namespace detail

        template <typename Sink, typename Iter> void parse(Sink& sink, Iter first, Iter last)
        {
            using namespace fmt::literals;

            // const auto start = fist;
            auto line_start = first;
            size_t line_no = 1;
            while (first != last) {
                switch (*first) {
                    case ' ':
                    case ',':
                    case ':':
                        break;
                    case '\n':
                        line_start = first + 1;
                        ++line_no;
                        break;
                    case '{':
                        sink.injson_object_start();
                        break;
                    case '}':
                        sink.injson_object_end();
                        break;
                    case '[':
                        sink.injson_array_start();
                        break;
                    case ']':
                        sink.injson_array_end();
                        break;
                    case '"': {
                        const auto end = detail::read_string(first + 1, last, line_start, line_no); // may throw error on EOF
                        sink.injson_string(first + 1, end);
                        first = end; // end points to terminating double-quotes
                    } break;
                    case '+':
                    case '-':
                    case '0':
                    case '1':
                    case '2':
                    case '3':
                    case '4':
                    case '5':
                    case '6':
                    case '7':
                    case '8':
                    case '9': {
                        const auto [end, nis] = detail::read_number(first + 1, last);
                        switch (nis) {
                            case detail::number_is::integer:
                                sink.injson_integer(first, end);
                                break;
                            case detail::number_is::real:
                                sink.injson_real(first, end);
                                break;
                        }
                        first = end - 1; // incremented after switch
                    } break;
                    default:
                        throw error(line_no, first - line_start, "unexpected '{}'"_format(*first));
                }
                ++first;
            }
        }
    } // namespace v1
}

// ----------------------------------------------------------------------
/// Local Variables:
/// eval: (if (fboundp 'eu-rename-buffer) (eu-rename-buffer))
/// End:
<commit_msg>injson<commit_after>#pragma once

#include "acmacs-base/fmt.hh"

// ----------------------------------------------------------------------

namespace injson
{
    inline namespace v1
    {
        class error : public std::runtime_error
        {
          public:
            template <typename S> error(size_t line_no, ssize_t column_no, S&& message) : std::runtime_error(fmt::format("injson error at {}:{}: {}", line_no, column_no, message)) {}
        };

        namespace detail
        {
            template <typename Iter> Iter read_string(Iter first, Iter last, Iter& line_start, size_t& line_no)
            {
                bool esc = false;
                for (; first != last; ++first) {
                    switch (*first) {
                      case '"':
                          if (!esc)
                              return first;
                          esc = false;
                          break;
                      case '\\':
                          esc = !esc;
                          break;
                      case '\n':
                          esc = false;
                          ++line_no;
                          line_start = first + 1;
                          break;
                      default:
                          esc = false;
                          break;
                    }
                }
                throw error(line_no, first - line_start, "unexpected EOF");
            }

            enum class number_is { integer, real };
            template <typename Iter> std::pair<Iter, number_is> read_number(Iter first, Iter last)
            {
                number_is nis = number_is::integer;
                for (; first != last; ++first) {
                    switch (*first) {
                        case '0':
                        case '1':
                        case '2':
                        case '3':
                        case '4':
                        case '5':
                        case '6':
                        case '7':
                        case '8':
                        case '9':
                            break;
                        case '.':
                        case '-':
                        case 'e':
                        case 'E':
                            nis = number_is::real;
                            break;
                        default:
                            return {first, nis};
                    }
                }
                throw error(0, 0, "read_number internal");
            }
        } // namespace detail

        template <typename Sink, typename Iter> void parse(Sink& sink, Iter first, Iter last)
        {
            using namespace fmt::literals;

            auto line_start = first;
            size_t line_no = 1;
            while (first != last) {
                switch (*first) {
                    case ' ':
                    case ',':
                    case ':':
                        break;
                    case '\n':
                        line_start = first + 1;
                        ++line_no;
                        break;
                    case '{':
                        sink.injson_object_start();
                        break;
                    case '}':
                        sink.injson_object_end();
                        break;
                    case '[':
                        sink.injson_array_start();
                        break;
                    case ']':
                        sink.injson_array_end();
                        break;
                    case '"': {
                        const auto end = detail::read_string(first + 1, last, line_start, line_no); // may throw error on EOF
                        sink.injson_string(first + 1, end);
                        first = end; // end points to terminating double-quotes
                    } break;
                    case '+':
                    case '-':
                    case '0':
                    case '1':
                    case '2':
                    case '3':
                    case '4':
                    case '5':
                    case '6':
                    case '7':
                    case '8':
                    case '9': {
                        const auto [end, nis] = detail::read_number(first + 1, last);
                        switch (nis) {
                            case detail::number_is::integer:
                                sink.injson_integer(first, end);
                                break;
                            case detail::number_is::real:
                                sink.injson_real(first, end);
                                break;
                        }
                        first = end - 1; // incremented after switch
                    } break;
                    default:
                        throw error(line_no, first - line_start, "unexpected '{}'"_format(*first));
                }
                ++first;
            }
        }
    } // namespace v1
}

// ----------------------------------------------------------------------
/// Local Variables:
/// eval: (if (fboundp 'eu-rename-buffer) (eu-rename-buffer))
/// End:
<|endoftext|>


<commit_before>#pragma once

#include <chrono>

#include "acmacs-base/log.hh"

// ----------------------------------------------------------------------

namespace acmacs
{
    using clock_t = std::chrono::high_resolution_clock;
    using timestamp_t = decltype(clock_t::now());
    using duration_t = std::chrono::nanoseconds;

    inline timestamp_t timestamp() { return clock_t::now(); }
    inline duration_t elapsed(timestamp_t start) { return std::chrono::duration_cast<duration_t>(timestamp() - start); }
    std::string format_duration(duration_t duration);
    inline double elapsed_seconds(timestamp_t start) { return std::chrono::duration<double>{timestamp() - start}.count(); }

} // namespace acmacs

// ----------------------------------------------------------------------

enum class report_time { no, yes };

constexpr report_time do_report_time(bool do_report) { return do_report ? report_time::yes : report_time::no; }

// ----------------------------------------------------------------------

class Timeit
{
  public:
    Timeit(std::string_view msg, report_time aReport = report_time::yes, const acmacs::log::source_location& sl = acmacs::log::source_location{})
        : message_{msg}, report_(aReport), start_{acmacs::timestamp()}, sl_{sl}
    {
    }
    ~Timeit() { report(); }

    void report() const
    {
        acmacs::log::print(sl_, report_ == report_time::yes, acmacs::log::prefix::info, "{}: {}", message_, acmacs::format_duration(acmacs::elapsed(start_)));
        report_ = report_time::no;
    }

    void message_append(const std::string& to_append) { message_ += to_append; }

  private:
    std::string message_;
    mutable report_time report_;
    acmacs::timestamp_t start_;
    const acmacs::log::source_location sl_;
};

// ----------------------------------------------------------------------
/// Local Variables:
/// eval: (if (fboundp 'eu-rename-buffer) (eu-rename-buffer))
/// End:
<commit_msg>timeit(msg, func)<commit_after>#pragma once

#include <chrono>

#include "acmacs-base/log.hh"

// ----------------------------------------------------------------------

namespace acmacs
{
    using clock_t = std::chrono::high_resolution_clock;
    using timestamp_t = decltype(clock_t::now());
    using duration_t = std::chrono::nanoseconds;

    inline timestamp_t timestamp() { return clock_t::now(); }
    inline duration_t elapsed(timestamp_t start) { return std::chrono::duration_cast<duration_t>(timestamp() - start); }
    std::string format_duration(duration_t duration);
    inline double elapsed_seconds(timestamp_t start) { return std::chrono::duration<double>{timestamp() - start}.count(); }

} // namespace acmacs

// ----------------------------------------------------------------------

enum class report_time { no, yes };

constexpr report_time do_report_time(bool do_report) { return do_report ? report_time::yes : report_time::no; }

// ----------------------------------------------------------------------

class Timeit
{
  public:
    Timeit(std::string_view msg, report_time aReport = report_time::yes, const acmacs::log::source_location& sl = acmacs::log::source_location{})
        : message_{msg}, report_(aReport), start_{acmacs::timestamp()}, sl_{sl}
    {
    }
    ~Timeit() { report(); }

    void report() const
    {
        acmacs::log::print(sl_, report_ == report_time::yes, acmacs::log::prefix::info, "{}: {}", message_, acmacs::format_duration(acmacs::elapsed(start_)));
        report_ = report_time::no;
    }

    void message_append(const std::string& to_append) { message_ += to_append; }

  private:
    std::string message_;
    mutable report_time report_;
    acmacs::timestamp_t start_;
    const acmacs::log::source_location sl_;
};

// ----------------------------------------------------------------------

template <typename Func> auto timeit(std::string_view msg, Func&& func, const acmacs::log::source_location& sl = acmacs::log::source_location{})
    requires std::is_invocable_v<Func>
{
    const auto start{acmacs::timestamp()};
    const auto print = [&sl, msg, start]() { acmacs::log::print(sl, true, acmacs::log::prefix::info, "{}: {}", msg, acmacs::format_duration(acmacs::elapsed(start))); };

    if constexpr (std::is_same_v<std::invoke_result_t<Func>, void>) {
        func();
        print();
    }
    else {
        const std::invoke_result_t<Func> result = func();
        print();
        return result;
    }
}

// ----------------------------------------------------------------------

template <typename Func> auto timeit(std::string_view pre, std::string_view after, Func&& func, const acmacs::log::source_location& sl = acmacs::log::source_location{})
    requires std::is_invocable_v<Func>
{
    acmacs::log::print(sl, true, acmacs::log::prefix::info, "{}", pre);
    return timeit(after, std::forward<Func>(func), sl);
}

// ----------------------------------------------------------------------
/// Local Variables:
/// eval: (if (fboundp 'eu-rename-buffer) (eu-rename-buffer))
/// End:
<|endoftext|>