text:
//
// GTest.cpp - GTESTs
//
// GTESTs
//
// Created by Sandesh Kumar Sodhi, December 2017
// Copyright (c) [2017] Juniper Networks, Inc. All rights reserved.
//
// All rights reserved.
//
// Notice and Disclaimer: This code is licensed to you under the Apache
// License 2.0 (the "License"). You may not use this code except in compliance
// with the License. This code is not an official Juniper product. You can
// obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
//
// Third-Party Code: This code may depend on other components under separate
// copyright notice and license terms. Your use of the source code for those
// components is subject to the terms and conditions of the respective license
// as noted in the Third-Party source code file.
//

#include <time.h>

#include <boost/filesystem.hpp>
#include <fstream>
#include <future>
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>

#include "gtest/gtest.h"
#include "Controller.h"
#include "TapIf.h"
#include "TestPacket.h"
#include "TestUtils.h"

using namespace std::chrono_literals;

//
// Test setup
//
// Junos RE CLI Sandbox configuration
// ==================================
//
// root# show forwarding-options
// forwarding-sandbox jp4agent {
//     port p1 {
//         interface xe-0/0/0:1;
//     }
//     port p2 {
//         interface xe-0/0/0:2;
//     }
// }
//
//
//  +--------------------------------------------------------------------------+
//  | +----------------------------------------------------------------------+ |
//  | |                                         Docker container             | |
//  | |                                                 ##        .          | |
//  | |   +---------------------+                 ## ## ##       ==          | |
//  | |   |        VCP          |              ## ## ## ##      ===          | |
//  | |   |                     |          /""""""""""""""""___/ ===         | |
//  | |   +---------------------+     ~~~ {~~ ~~~~ ~~~ ~~~~ ~~ ~ /  ===- ~~~ | |
//  | |                                    \______ o          __/            | |
//  | |   +---------------------+           \    \        __/                | |
//  | |   |        VFP          |             \____\______/                  | |
//  | |   |                     |                                            | |
//  | |   |                     |                                            | |
//  | |   |                     |                                            | |
//  | |   |                     |                Controller/GTEST            | |
//  | |   |                     |                    ^                       | |
//  | |   |                     |         P4 Runtime |                       | |
//  | |   |                     |                    |                       | |
//  | |   |                     |                    V                       | |
//  | |   |     afi-server <-------grpc/tcp-----> JP4Agent                   | |
//  | |   |                     |                                            | |
//  | |   |                     |                                            | |
//  | |   |                     |                                            | |
//  | |   |       riot          |                                            | |
//  | |   |                     |                                            | |
//  | |   |   p1            p2  |                                            | |
//  | |   |ge-0/0/2     ge-0/0/3|                                            | |
//  | |   +---------------------+                                            | |
//  | |       |             |                                                | |
//  | |       |             |        ,-----.                                 | |
//  | |       |             |        |     |                                 | |
//  | |       |             `--------o     |                                 | |
//  | |       |                      |_____|                                 | |
//  | |       |                     vmx_link2                                | |
//  | |       |                                                              | |
//  | |       |                                                              | |
//  | |       |                                                              | |
//  | |       |                      ,-----.                                 | |
//  | |       |                      |     |                                 | |
//  | |       `----------------------o     |                                 | |
//  | |                              |_____|                                 | |
//  | |                             vmx_link1                                | |
//  | |                                                                      | |
//  | +----------------------------------------------------------------------+ |
//  |                                                                          |
//  | mx86 server                                                              |
//  +--------------------------------------------------------------------------+
//
// root@de5cf35cd169:~# ifconfig | grep vmx_link
// vmx_link0 Link encap:Ethernet  HWaddr 32:26:0a:2e:bb:f0
// vmx_link1 Link encap:Ethernet  HWaddr 32:26:0a:2e:bb:f1
// vmx_link2 Link encap:Ethernet  HWaddr 32:26:0a:2e:bb:f2
// vmx_link3 Link encap:Ethernet  HWaddr 32:26:0a:2e:bb:f3
// vmx_link4 Link encap:Ethernet  HWaddr 32:26:0a:2e:bb:f4
// vmx_link5 Link encap:Ethernet  HWaddr 32:26:0a:2e:bb:f5
// vmx_link6 Link encap:Ethernet  HWaddr 32:26:0a:2e:bb:f6
// vmx_link7 Link encap:Ethernet  HWaddr 32:26:0a:2e:bb:f7
// root@de5cf35cd169:~#
//

//
//              |
//   ,-----.    |
//   |     |    |
//   |     o----o----------
//   |_____|    |pX / ge-0/0/X
//  vmx_linkX   |
//              |
//

struct intf {
    const char *if_name;
    const char *mac_str;
    const char *ip_addr;
};

static constexpr intf ge_intfs[] = {
    {"ge-0.0.0-vmx1", "fe:26:0a:2e:aa:f0", "103.30.100.1"},
    {"ge-0.0.1-vmx1", "fe:26:0a:2e:aa:f1", "103.30.110.1"},
    {"ge-0.0.2-vmx1", "fe:26:0a:2e:aa:f2", "103.30.120.1"},
    {"ge-0.0.3-vmx1", "fe:26:0a:2e:aa:f3", "103.30.130.1"},
    {"ge-0.0.4-vmx1", "fe:26:0a:2e:aa:f4", "103.30.140.1"},
    {"ge-0.0.5-vmx1", "fe:26:0a:2e:aa:f5", "103.30.150.1"},
    {"ge-0.0.6-vmx1", "fe:26:0a:2e:aa:f6", "103.30.160.1"},
    {"ge-0.0.7-vmx1", "fe:26:0a:2e:aa:f7", "103.30.170.1"}};

static constexpr intf vmx_links[] = {
    {"vmx_link10", "32:26:0a:2e:bb:f0", "103.30.100.2"},
    {"vmx_link11", "32:26:0a:2e:bb:f1", "103.30.110.2"},
    {"vmx_link12", "32:26:0a:2e:bb:f2", "103.30.120.2"},
    {"vmx_link13", "32:26:0a:2e:bb:f3", "103.30.130.2"},
    {"vmx_link14", "32:26:0a:2e:bb:f4", "103.30.140.2"},
    {"vmx_link15", "32:26:0a:2e:bb:f5", "103.30.150.2"},
    {"vmx_link16", "32:26:0a:2e:bb:f6", "103.30.160.2"},
    {"vmx_link17", "32:26:0a:2e:bb:f7", "103.30.170.2"}};

/*
 * IPv4 Router
 *                                                         Expected Packet
 *                                                               /\
 *               ,----------------------------------------.      ||
 *               |                                        |      ||
 *               |              .                         |      ||
 *    ,-----.    |             / \                        |    ,-----.
 *    |     |    |            /   \                       |    |     |
 *    |     o----o---------->/  R1-\--->[Eth Encap]------>o----o     |
 *    |_____|    |p2        /_______\                   p3|    |_____|
 *   vmx_link2   |ge-0/0/2                        ge-0/0/3|    vmx_link3
 *      /\       |                                        |
 *      ||       |                                        |
 *      ||       |            Sandbox: jp4agent           |
 *      ||       `----------------------------------------'
 * Input Packet
 */

// Global context for all tests.
class TestEnv : public testing::Environment
{
 public:
    std::string result_dir;

    void SetUp() override
    {
        // Create the result directory and store its name.
        time_t    rawtime;
        struct tm timeinfo;

        time(&rawtime);
        localtime_r(&rawtime, &timeinfo);

        char time_str[80];
        strftime(time_str, 80, "%d%m%Y_%I%M%S", &timeinfo);

        result_dir = "GTEST_RESULT_" + std::string(time_str);

        ASSERT_TRUE(boost::filesystem::create_directories(result_dir))
            << "Failed to create GTest result directory.";
    }
};

static const ::testing::Environment *genv;

// Common setup for all tests in this test fixture. We setup the forwarding
// pipeline config here.
class P4 : public ::testing::Test
{
 protected:
    std::string test_out_dir;
    std::string test_exp_dir;

    static void SetUpTestCase()
    {
        ControllerSetConfig();
        sleep_thread_log(15s);
    }

    void SetUp() override
    {
        // Populate expected and output directory names for this test.
        const auto *tenv = dynamic_cast<const TestEnv *>(genv);
        ASSERT_NE(tenv, nullptr);

        const ::testing::TestInfo *const tInfo =
            ::testing::UnitTest::GetInstance()->current_test_info();
        const std::string tDir = std::string(tInfo->test_case_name()) + "/" +
                                 std::string(tInfo->name());

        test_out_dir = tenv->result_dir + "/" + tDir;
        test_exp_dir = "GTEST_EXPECTED/" + tDir;

        // Create output directory.
        ASSERT_TRUE(boost::filesystem::create_directories(test_out_dir))
            << "Failed to create test output directory " << test_out_dir;
    }
};

// Test1: Inject L2 pkt with port ID of vmx_link2 at controller and verify
// receipt at vmx_link2.
TEST_F(P4, injectL2Pkt)
{
    constexpr uint16_t egress_port      = 0;
    constexpr int      num_pkts         = 1;
    constexpr int      pcap_timeout_sec = 10;

    // Start listening for pkts.
    const std::vector<std::string> capture_ifs{ge_intfs[2].if_name};
    std::vector<pid_t>             pcap_pids =
        start_pktcap(test_out_dir, capture_ifs, num_pkts, pcap_timeout_sec);
    ASSERT_EQ(capture_ifs.size(), pcap_pids.size())
        << "Failed to listen on all the specified interfaces";
    sleep_thread_log(3s);

    std::cout << "Injecting L2 packet on egress port " << egress_port << "...";
    TestPacket *testPkt = testPacketLibrary.getTestPacket(
        TestPacketLibrary::TEST_PKT_ID_IPV4_ECHO_REQ_TO_TAP2);
    char   pktbuf[ETHER_PAYLOAD_BUF_SIZE];
    size_t pktlen = testPkt->getEtherPacket(pktbuf, ETHER_PAYLOAD_BUF_SIZE);
    std::string l2_pkt(pktbuf, pktlen);

    // Call controller to inject the L2 pkt on the JP4Agent connection.
    EXPECT_TRUE(ControllerInjectL2Pkt(l2_pkt, egress_port))
        << "Failed to inject L2 pkt.";
    std::cout << "Done." << std::endl;

    // Print injected pkt
    std::cout << "Injected pkt:" << std::hex << std::uppercase;
    for (size_t i = 0; i < pktlen; i++) {
        if (i % 16 == 0) std::cout << "\n";
        std::cout << " " << std::setfill('0') << std::setw(2)
                  << +(uint8_t)l2_pkt[i];
    }
    std::cout << std::endl << std::dec << std::nouppercase;

    // Wait for pcap child processes
    ASSERT_TRUE(stop_pktcap(capture_ifs, pcap_pids))
        << "Packet capture failed or timed out";

    // Verify packets
    tVerifyPackets(test_out_dir, test_exp_dir, capture_ifs);
}

// Test2: Punt path: Inject L2 pkt in vmx_link2 and verify receipt at
// controller.
TEST_F(P4, puntL2Pkt)
{
    constexpr uint16_t expected_ingress_port = 0;

    // Start Controller and listen.
    uint16_t    ingress_port = 0;
    std::string recvd_pkt;
    auto        fut = std::async(std::launch::async, ControllerPuntPkt,
                          std::ref(recvd_pkt), std::ref(ingress_port), 15s);

    constexpr int                  num_pkts         = 1;
    constexpr int                  pcap_timeout_sec = 10;
    const std::vector<std::string> capture_ifs{ge_intfs[2].if_name};
    std::vector<pid_t>             pcap_pids =
        start_pktcap(test_out_dir, capture_ifs, num_pkts, pcap_timeout_sec);
    ASSERT_EQ(capture_ifs.size(), pcap_pids.size())
        << "Failed to listen on all the specified interfaces";
    sleep_thread_log(3s);

    // Send RawEth pkt on vmx_link2
    int ret = SendRawEth(
        vmx_links[2].if_name,
        TestPacketLibrary::VMXZT_TEST_PKT_ID_IPV4_ROUTER_ICMP_ECHO_TO_TAP3);
    EXPECT_EQ(0, ret) << "Failed to send pkt to VMX_LINK2";

    // Wait for pcap child processes
    ASSERT_TRUE(stop_pktcap(capture_ifs, pcap_pids))
        << "Packet capture failed or timed out";

    // Verify packets
    tVerifyPackets(test_out_dir, test_exp_dir, capture_ifs);

    // Wait for controller thread
    ASSERT_TRUE(fut.get()) << "Timed out waiting for packet";
    ASSERT_FALSE(recvd_pkt.empty()) << "Failed to read packet";
    EXPECT_EQ(expected_ingress_port, ingress_port)
        << "Packet didn't arrive on the expected ingress port";

    // Compare and verify
    TestPacket *testPkt = testPacketLibrary.getTestPacket(
        TestPacketLibrary::VMXZT_TEST_PKT_ID_IPV4_ROUTER_ICMP_ECHO_TO_TAP3);
    char   pktbuf[ETHER_PAYLOAD_BUF_SIZE];
    size_t pktlen = testPkt->getEtherPacket(pktbuf, ETHER_PAYLOAD_BUF_SIZE);

    EXPECT_EQ(0, memcmp(pktbuf, recvd_pkt.data(), pktlen))
        << "Sent and received pkts differ";
}

// Test3: ICMP echo request/reply
TEST_F(P4, hostPing)
{
    // Start Controller to handle ping.
    auto fut = std::async(std::launch::async, ControllerICMPEcho, 15s);

    constexpr int                  num_pkts         = 2;
    constexpr int                  pcap_timeout_sec = 10;
    const std::vector<std::string> capture_ifs{ge_intfs[2].if_name};
    std::vector<pid_t>             pcap_pids =
        start_pktcap(test_out_dir, capture_ifs, num_pkts, pcap_timeout_sec);
    ASSERT_EQ(capture_ifs.size(), pcap_pids.size())
        << "Failed to listen on all the specified interfaces";
    sleep_thread_log(3s);

    // Send ICMP Echo request.
    int ret = SendRawEth(
        vmx_links[2].if_name,
        TestPacketLibrary::VMXZT_TEST_PKT_ID_IPV4_ROUTER_ICMP_ECHO_TO_TAP3);
    EXPECT_EQ(0, ret) << "Failed to send pkt to VMX_LINK2";

    // Wait for pcap child processes
    ASSERT_TRUE(stop_pktcap(capture_ifs, pcap_pids))
        << "Packet capture failed or timed out";

    // Verify packets
    tVerifyPackets(test_out_dir, test_exp_dir, capture_ifs);

    // Wait for controller thread
    ASSERT_TRUE(fut.get()) << "Timed out waiting for pkt";
}

// Test4: Send ARP request to Controller and verify ARP reply.
TEST_F(P4, sendArpReq)
{
    // Start Controller to handle arp req.
    std::string recvd_pkt;
    auto fut = std::async(std::launch::async, ControllerHandleArpReq, 15s);

    constexpr int                  num_pkts = 2;  // ARP request and reply.
    constexpr int                  pcap_timeout_sec = 10;
    const std::vector<std::string> capture_ifs{ge_intfs[2].if_name};
    std::vector<pid_t>             pcap_pids =
        start_pktcap(test_out_dir, capture_ifs, num_pkts, pcap_timeout_sec);
    ASSERT_EQ(capture_ifs.size(), pcap_pids.size())
        << "Failed to listen on all the specified interfaces";
    sleep_thread_log(3s);

    // Construct and send ARP request
    EXPECT_NO_FATAL_FAILURE(
        send_arp_req(vmx_links[2].if_name, ge_intfs[2].ip_addr));

    // Wait for pcap child processes
    ASSERT_TRUE(stop_pktcap(capture_ifs, pcap_pids))
        << "Packet capture failed or timed out";

    // Verify packets
    tVerifyPackets(test_out_dir, test_exp_dir, capture_ifs);

    // Wait for controller thread
    ASSERT_TRUE(fut.get()) << "Timed out waiting for ARP request packet.";
}

// Test5: Transit packet.
TEST_F(P4, ipv4Router)
{
    // Launch controller to add route entry.
    ControllerAddRouteEntry(0x671e1e03, 16, 0x0a000001, 0x88a25e9175ff, 1);
    sleep_thread_log(5s);

    const int num_pkts_to_send = 1;
    const int pcap_timeout_sec = 10;

    // Start packet capture on ingress and egress interfaces.
    const std::vector<std::string> capture_ifs{ge_intfs[2].if_name,
                                               ge_intfs[3].if_name};
    std::vector<pid_t>             pcap_pids = start_pktcap(
        test_out_dir, capture_ifs, num_pkts_to_send, pcap_timeout_sec);
    ASSERT_EQ(capture_ifs.size(), pcap_pids.size())
        << "Failed to listen on all the specified interfaces";
    sleep_thread_log(3s);

    // Send L2 packet.
    for (int i = 0; i < num_pkts_to_send; i++) {
        int ret = SendRawEth(
            vmx_links[2].if_name,
            TestPacketLibrary::VMXZT_TEST_PKT_ID_IPV4_ROUTER_ICMP_ECHO_TO_TAP3);
        EXPECT_EQ(0, ret);
        std::this_thread::sleep_for(1s);
    }

    // Wait for pcap child processes
    ASSERT_TRUE(stop_pktcap(capture_ifs, pcap_pids))
        << "Packet capture failed or timed out";

    // Verify packets
    tVerifyPackets(test_out_dir, test_exp_dir, capture_ifs);
}

// Test6: Null Target Test.
TEST_F(P4, nullTest)
{
    // Launch controller to add route entry.
    ControllerAddRouteEntry(0x0a000001, 16, 0x0a000001, 0x88a25e9175ff, 1);
    sleep_thread_log(1s);

    const std::string expectedString =
        "key_field: packet.ip4.daddr\ntree.ByteSize(): 69\nentry_name: "
        "entry1\nparent_name: ipv4_lpm\ntarget_afi_object: etherencap1\n";
    std::ifstream gtestFile{"/root/JP4Agent/src/targets/null/NullTest.txt"};
    std::string line, log;
    while (getline(gtestFile, line)) {
        log += line + "\n";
    }

    EXPECT_EQ(log, expectedString);
}

//
// gtest main
//
int
main(int argc, char **argv)
{
    ::testing::InitGoogleTest(&argc, argv);

    // Init global environment.
    genv = ::testing::AddGlobalTestEnvironment(new TestEnv);

    if (argc == 1) {
        ::testing::GTEST_FLAG(filter) = "P4.*-P4.nullTest";
    } else if (strcmp(argv[1], "brcm")  == 0) {
            ::testing::GTEST_FLAG(filter) = "P4BRCM.*";
    } else if (strcmp(argv[1], "brcmspine")  == 0) {
            ::testing::GTEST_FLAG(filter) = "P4BRCMSPINE.*";
            //::testing::GTEST_FLAG(filter) = "P4BRCMSPINE.Punt";
    } else if (strcmp(argv[1], "brcmspine.init")  == 0) {
            ::testing::GTEST_FLAG(filter) = "P4BRCMSPINE.Foo";
    } else if (strcmp(argv[1], "brcmspine.vrf")  == 0) {
            ::testing::GTEST_FLAG(filter) = "P4BRCMSPINE.VrfClassifier";
    } else if (strcmp(argv[1], "brcmspine.classid")  == 0) {
            ::testing::GTEST_FLAG(filter) = "P4BRCMSPINE.ClassId";
    } else if (strcmp(argv[1], "brcmspine.mymac")  == 0) {
            ::testing::GTEST_FLAG(filter) = "P4BRCMSPINE.MyMac";
    } else if (strcmp(argv[1], "brcmspine.rtt")  == 0) {
            ::testing::GTEST_FLAG(filter) = "P4BRCMSPINE.RTT";
    } else if (strcmp(argv[1], "brcmspine.punt")  == 0) {
            ::testing::GTEST_FLAG(filter) = "P4BRCMSPINE.Punt";
    } else if (strcmp(argv[1], "brcmspine.VrfTraffic")  == 0) {
            ::testing::GTEST_FLAG(filter) = "P4BRCMSPINE.VrfTraffic";
    } else if (strcmp(argv[1], "brcmspine.OverrideTraffic")  == 0) {
            ::testing::GTEST_FLAG(filter) = "P4BRCMSPINE.OverrideTraffic";
    } else if (strcmp(argv[1], "brcmspine.FallbackTraffic")  == 0) {
            ::testing::GTEST_FLAG(filter) = "P4BRCMSPINE.FallbackTraffic";
    } else if (strcmp(argv[1], "brcmspine.PuntTableTraffic")  == 0) {
            ::testing::GTEST_FLAG(filter) = "P4BRCMSPINE.PuntTableTraffic";
    } else if (strcmp(argv[1], "brcmvrf")  == 0) {
            ::testing::GTEST_FLAG(filter) = "P4BRCMVRF.*";
    } else {
        ::testing::GTEST_FLAG(filter) = "*nullTest*";
    }
    // ::testing::GTEST_FLAG(filter) = "*ipv4Router*";
    // ::testing::GTEST_FLAG(filter) = "*injectL2Pkt*:*puntL2Pkt*:*hostPing*";

    return RUN_ALL_TESTS();
}


text:
//
// Copyright (C) 2004-2006, Maciej Sobczak
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//

#include "cpptkbase.h"
#include <tcl.h>
#include <tk.h>
#include <map>
#include <ostream>
#include <iostream>
#include <sstream>
#include <boost/scoped_ptr.hpp>

using namespace Tk;
using namespace Tk::details;
using namespace boost;
using namespace std;

namespace { // anonymous

class Interp
{
public:
     Interp()
     {
          interp_ = Tcl_CreateInterp();

          int cc = Tcl_Init(interp_);
          if (cc != TCL_OK)
          {
               throw TkError(interp_->result);
          }

          cc = Tk_Init(interp_);
          if (cc != TCL_OK)
          {
               throw TkError(interp_->result);
          }

          cc = Tcl_Eval(interp_, "namespace eval CppTk {}");
          if (cc != TCL_OK)
          {
               throw TkError(interp_->result);
          }
     }

     ~Interp()
     {
          // GUI programs are supposed to exit by calling "exit"
          // then - explicit delete here is harmful
          //Tcl_DeleteInterp(interp_);
     }

     Tcl_Interp * get() const { return interp_; }

private:
     Tcl_Interp * interp_;
};

// lazy-initialization of Tcl interpreter
Tcl_Interp * getInterp()
{
     static Interp interp;
     return interp.get();
}

// output stream for dumping Tk commands
// (useful for automated testing)
ostream *dumpstream = &cerr;

void do_eval(string const &str)
{
#ifdef CPPTK_DUMP_COMMANDS
     *dumpstream << str << '\n';
#endif // CPPTK_DUMP_COMMANDS

#ifndef CPPTK_DONT_EVALUATE
     int cc = Tcl_Eval(getInterp(), str.c_str());
     if (cc != TCL_OK)
     {
          throw TkError(getInterp()->result);
     }
#endif
}

// map for callbacks
typedef map<int, boost::shared_ptr<CallbackBase> > CallbacksMap;
CallbacksMap callbacks;

// callback id
int callbackId = 0;

char const *callbackPrefix = "CppTk::callback";

typedef map<int *,    string> IntLinks;
typedef map<double *, string> DoubleLinks;
typedef map<string *, string> StringLinks;

IntLinks intLinks;
DoubleLinks doubleLinks;
StringLinks stringLinks;

typedef map<string *, char *> StringLinkBuffers;
StringLinkBuffers stringLinkBuffers;

int linkId = 0;

char const *linkVarPrefix = "CppTk::variable";

// this function refreshes Tcl variables from C++ variables
void linkCpptoTcl()
{
     // synchronize C++ variables with Tcl variables
     // it is enough to refresh string buffers and update links

     // refresh string buffers
     for (StringLinks::iterator it = stringLinks.begin();
          it != stringLinks.end(); ++it)
     {
          string *ps = it->first; // pointer to C++ string (original value)

          StringLinkBuffers::iterator itb = stringLinkBuffers.find(ps);
          char *&pb = itb->second; // pointer to Tcl buffer (destination)

          if (pb != NULL)
          {
               Tcl_Free(pb);
          }
          pb = Tcl_Alloc(static_cast<unsigned int>(ps->size()) + 1);
          copy(ps->begin(), ps->end(), pb);
          pb[ps->size()] = '\0';

          Tcl_UpdateLinkedVar(getInterp(), it->second.c_str());
     }

     // update other (int and double) Tcl links
     for (IntLinks::iterator it = intLinks.begin();
          it != intLinks.end(); ++it)
     {
          Tcl_UpdateLinkedVar(getInterp(), it->second.c_str());
     }
     for (DoubleLinks::iterator it = doubleLinks.begin();
          it != doubleLinks.end(); ++it)
     {
          Tcl_UpdateLinkedVar(getInterp(), it->second.c_str());
     }
}

// this function refreshes C++ variables from Tcl variables
void linkTcltoCpp()
{
     // it is enough to refresh strings from their buffers
     for (StringLinks::iterator it = stringLinks.begin();
          it != stringLinks.end(); ++it)
     {
          string *ps = it->first; // pointer to C++ string (destination)

          StringLinkBuffers::iterator itb = stringLinkBuffers.find(ps);
          char *pb = itb->second; // pointer to Tcl buffer (original value)

          if (pb != NULL)
          {
               ps->assign(pb);
          }
          else
          {
               ps->clear();
          }
     }
}

} // namespace // anonymous

// global flag for avoiding multiple-error problem
bool Tk::TkError::inTkError = false;

// generic callback handler

extern "C"
int callbackHandler(ClientData cd, Tcl_Interp *interp,
     int objc, Tcl_Obj *CONST objv[])
{
     int slot = static_cast<int>(reinterpret_cast<size_t>(cd));

     CallbacksMap::iterator it = callbacks.find(slot);
     if (it == callbacks.end())
     {
          Tcl_SetResult(interp,
               "Trying to invoke non-existent callback", TCL_STATIC);
          return TCL_ERROR;
     }

     try
     {
          // refresh C++ variables
          linkTcltoCpp();

          Params p(objc, reinterpret_cast<void*>(
               const_cast<Tcl_Obj **>(objv)));
          it->second->invoke(p);

          // refresh Tcl variables
          linkCpptoTcl();
     }
     catch (std::exception const &e)
     {
          Tcl_SetResult(interp, const_cast<char*>(e.what()), TCL_VOLATILE);
          return TCL_ERROR;
     }
     return TCL_OK;
}

// generic callback deleter

extern "C"
void callbackDeleter(ClientData cd)
{
     int slot = static_cast<int>(reinterpret_cast<size_t>(cd));
     callbacks.erase(slot);
}

string Tk::details::addCallback(boost::shared_ptr<CallbackBase> cb)
{
     int newSlot = callbackId++;
     callbacks[newSlot] = cb;

     string newCmd(callbackPrefix);
     newCmd += lexical_cast<string>(newSlot);

     Tcl_CreateObjCommand(getInterp(), newCmd.c_str(),
          callbackHandler, reinterpret_cast<ClientData>(
			static_cast<size_t>(newSlot)),
          callbackDeleter);

     return newCmd;
}

string Tk::details::addLinkVar(int &i)
{
     int newLink = linkId++;
     string newLinkVar(linkVarPrefix);
     newLinkVar += lexical_cast<string>(newLink);

     int cc = Tcl_LinkVar(getInterp(), newLinkVar.c_str(),
          reinterpret_cast<char*>(&i), TCL_LINK_INT);
     if (cc != TCL_OK)
     {
          throw TkError(getInterp()->result);
     }

     intLinks[&i] = newLinkVar;
     return newLinkVar;
}

string Tk::details::addLinkVar(double &d)
{
     int newLink = linkId++;
     string newLinkVar(linkVarPrefix);
     newLinkVar += lexical_cast<string>(newLink);

     int cc = Tcl_LinkVar(getInterp(), newLinkVar.c_str(),
          reinterpret_cast<char*>(&d), TCL_LINK_DOUBLE);
     if (cc != TCL_OK)
     {
          throw TkError(getInterp()->result);
     }

     doubleLinks[&d] = newLinkVar;
     return newLinkVar;
}

string Tk::details::addLinkVar(string &s)
{
     int newLink = linkId++;
     string newLinkVar(linkVarPrefix);
     newLinkVar += lexical_cast<string>(newLink);

     pair<map<string *, char *>::iterator, bool> it =
          stringLinkBuffers.insert(make_pair(&s, static_cast<char*>(NULL)));

     char *&pb = it.first->second;
     pb = Tcl_Alloc(static_cast<unsigned int>(s.size()) + 1);
     copy(s.begin(), s.end(), pb);
     pb[s.size()] = '\0';

     int cc = Tcl_LinkVar(getInterp(), newLinkVar.c_str(),
          reinterpret_cast<char*>(&it.first->second), TCL_LINK_STRING);
     if (cc != TCL_OK)
     {
          throw TkError(getInterp()->result);
     }

     stringLinks[&s] = newLinkVar;
     return newLinkVar;
}

void Tk::details::deleteLinkVar(int &i)
{
     IntLinks::iterator it = intLinks.find(&i);
     if (it == intLinks.end())
     {
          return;
     }

     Tcl_UnlinkVar(getInterp(), it->second.c_str());
     intLinks.erase(it);
}

void Tk::details::deleteLinkVar(double &d)
{
     DoubleLinks::iterator it = doubleLinks.find(&d);
     if (it == doubleLinks.end())
     {
          return;
     }

     Tcl_UnlinkVar(getInterp(), it->second.c_str());
     doubleLinks.erase(it);
}

void Tk::details::deleteLinkVar(string &s)
{
     StringLinks::iterator it = stringLinks.find(&s);
     if (it == stringLinks.end())
     {
          return;
     }

     Tcl_UnlinkVar(getInterp(), it->second.c_str());
     stringLinks.erase(it);

     StringLinkBuffers::iterator itb = stringLinkBuffers.find(&s);
     char *pb = itb->second;
     if (pb != NULL)
     {
          Tcl_Free(pb);
     }

     stringLinkBuffers.erase(itb);
}

void details::setResult(bool b)
{
     Tcl_SetObjResult(getInterp(), Tcl_NewBooleanObj(b));
}

void details::setResult(long i)
{
     Tcl_SetObjResult(getInterp(), Tcl_NewLongObj(i));
}

void details::setResult(double d)
{
     Tcl_SetObjResult(getInterp(), Tcl_NewDoubleObj(d));
}

void details::setResult(string const &s)
{
     Tcl_SetObjResult(getInterp(),
          Tcl_NewStringObj(s.data(), static_cast<int>(s.size())));
}

int details::getResultLen()
{
     Tcl_Interp *interp = getInterp();

     Tcl_Obj *list = Tcl_GetObjResult(interp);
     int len, cc;

     cc = Tcl_ListObjLength(interp, list, &len);
     if (cc != TCL_OK)
     {
          throw TkError(interp->result);
     }

     return len;
}

template <>
int details::getResultElem<int>(int indx)
{
     Tcl_Interp *interp = getInterp();

     Tcl_Obj *list = Tcl_GetObjResult(interp);
     Tcl_Obj *obj;

     int cc = Tcl_ListObjIndex(interp, list, indx, &obj);
     if (cc != TCL_OK)
     {
          throw TkError(interp->result);
     }

     int val;
     cc = Tcl_GetIntFromObj(interp, obj, &val);
     if (cc != TCL_OK)
     {
          throw TkError(interp->result);
     }

     return val;
}

template <>
double details::getResultElem<double>(int indx)
{
     Tcl_Interp *interp = getInterp();

     Tcl_Obj *list = Tcl_GetObjResult(interp);
     Tcl_Obj *obj;

     int cc = Tcl_ListObjIndex(interp, list, indx, &obj);
     if (cc != TCL_OK)
     {
          throw TkError(interp->result);
     }

     double val;
     cc = Tcl_GetDoubleFromObj(interp, obj, &val);
     if (cc != TCL_OK)
     {
          throw TkError(interp->result);
     }

     return val;
}

template <>
string details::getResultElem<string>(int indx)
{
     Tcl_Interp *interp = getInterp();

     Tcl_Obj *list = Tcl_GetObjResult(interp);
     Tcl_Obj *obj;

     int cc = Tcl_ListObjIndex(interp, list, indx, &obj);
     if (cc != TCL_OK)
     {
          throw TkError(interp->result);
     }

     return Tcl_GetString(obj);
}

details::Command::Command(std::string const &str, std::string const &postfix)
     : invoked_(false), str_(str), postfix_(postfix)
{
}

details::Command::~Command()
{
     if (!TkError::inTkError)
     {
          invokeOnce();
     }
}

string details::Command::invoke() const
{
     invokeOnce();
     return getInterp()->result;
}

void details::Command::invokeOnce() const
{
     if (invoked_ == false)
     {
          invoked_ = true;

          string cmd(str_);
          cmd += postfix_;

          do_eval(cmd);
     }
}

details::Expr::Expr(string const &str, bool starter)
{
     if (starter)
     {
          cmd_.reset(new Command(str));
     }
     else
     {
          str_ = str;
     }
}

details::Expr::Expr(string const &str, string const &postfix)
{
     cmd_.reset(new Command(str, postfix));
}

string details::Expr::getValue() const
{
     if (!str_.empty())
     {
          return str_;
     }
     else
     {
          return cmd_->getValue();
     }
}

details::Expr::operator string() const
{
     return cmd_->invoke();
}

details::Expr::operator int() const
{
     cmd_->invokeOnce();

     Tcl_Interp *interp = getInterp();
     Tcl_Obj *obj = Tcl_GetObjResult(interp);

     int val, cc;
     cc = Tcl_GetIntFromObj(interp, obj, &val);
     if (cc != TCL_OK)
     {
          throw TkError(interp->result);
     }

     return val;
}

details::Expr::operator double() const
{
     cmd_->invokeOnce();

     Tcl_Interp *interp = getInterp();
     Tcl_Obj *obj = Tcl_GetObjResult(interp);

     double val;
     int cc = Tcl_GetDoubleFromObj(interp, obj, &val);
     if (cc != TCL_OK)
     {
          throw TkError(interp->result);
     }

     return val;
}

details::Expr::operator Tk::Point() const
{
     string ret(cmd_->invoke());
     if (ret.empty())
     {
          return Tk::Point(0, 0);
     }

     int len = getResultLen();
     if (len < 2)
     {
          throw TkError("Cannot convert the result list to Point\n");
     }

     int x = getResultElem<int>(0);
     int y = getResultElem<int>(1);

     return Point(x, y);
}

details::Expr::operator Tk::Box() const
{
     string ret(cmd_->invoke());
     if (ret.empty())
     {
          return Tk::Box(0, 0, 0, 0);
     }

     int len = getResultLen();
     if (len < 4)
     {
          throw TkError("Cannot convert the result list to Box\n");
     }

     int x1 = getResultElem<int>(0);
     int y1 = getResultElem<int>(1);
     int x2 = getResultElem<int>(2);
     int y2 = getResultElem<int>(3);

     return Box(x1, y1, x2, y2);
}

// these two specializations are used to extract parameter
// with the requested type

template <>
int details::Params::get<int>(int argno) const
{
     if (argno < 1 || argno >= argc_)
     {
          throw TkError("Parameter number out of valid range");
     }

     Tcl_Obj *CONST *objv = reinterpret_cast<Tcl_Obj *CONST *>(objv_);

     int res, cc;
     cc = Tcl_GetIntFromObj(getInterp(), objv[argno], &res);
     if (cc != TCL_OK)
     {
          throw TkError(getInterp()->result);
     }

     return res;
}

template <>
string details::Params::get<string>(int argno) const
{
     if (argno < 1 || argno >= argc_)
     {
          throw TkError("Parameter number out of valid range");
     }

     Tcl_Obj *CONST *objv = reinterpret_cast<Tcl_Obj *CONST *>(objv_);

     string res = Tcl_GetString(objv[argno]);
     return res;
}

ostream & details::operator<<(ostream &os, BasicToken const &token)
{
     return os << static_cast<string>(token);
}

namespace { // anonymous

void doSingleQuote(string &s, char c)
{
     string::size_type pos = 0;
     while ((pos = s.find(c, pos)) != string::npos)
     {
          s.insert(pos, "\\");
          pos += 2;
     }
}

} // namespace anonymous

// this function is used to quote quotation marks in string values'
// in later version, it will not be needed
string details::quote(string const &s)
{
     string ret(s);
     doSingleQuote(ret, '\\');
     doSingleQuote(ret, '\"');
     doSingleQuote(ret, '$');
     doSingleQuote(ret, '[');
     doSingleQuote(ret, ']');

     return ret;
}

// basic Tk expression operations

Expr Tk::operator-(Expr const &lhs, Expr const &rhs)
{
     boost::shared_ptr<Command> cmd(lhs.getCmd());
     cmd->append(rhs.getValue());

     return Expr(cmd);
}

Expr Tk::operator<<(string const &w, Expr const &rhs)
{
     boost::shared_ptr<Command> cmd(rhs.getCmd());
     cmd->prepend(" ");
     cmd->prepend(w);

     return Expr(cmd);
}

// helper functions

void Tk::deleteCallback(string const &name)
{
     string::size_type pos = name.find_first_not_of(callbackPrefix);
     if (pos == string::npos) return;

     int slot = lexical_cast<int>(name.substr(pos, name.size()));
     callbacks.erase(slot);

     int cc = Tcl_DeleteCommand(getInterp(), name.c_str());
     if (cc != TCL_OK)
     {
          throw TkError(getInterp()->result);
     }
}

Tk::CallbackHandle::CallbackHandle(string const &name) : name_(name) {}

Tk::CallbackHandle::~CallbackHandle() { deleteCallback(name_); }

Expr Tk::eval(string const &str)
{
     return Expr(str);
}

void Tk::init(char *argv0)
{
	Tcl_FindExecutable(argv0);
}

void Tk::runEventLoop()
{
     // refresh Tcl variables
     linkCpptoTcl();

     Tk_MainLoop();
}

void Tk::setDumpStream(ostream &os)
{
	dumpstream = &os;
}

ext: cc

max_stars_repo_name: NeLy-EPFL/SeptaCam

max_issues_repo_name: NeLy-EPFL/SeptaCam

max_forks_repo_name: NeLy-EPFL/SeptaCam


text:
#include <string>
#include <exception>

// boost
#include <boost/filesystem.hpp>
#include <boost/format.hpp>
#include <boost/program_options.hpp>

// pcl to deal with point clouds
#include <pcl/point_types.h>
#include <pcl/search/organized.h>
#include <pcl/search/octree.h>
//#include <pcl/io/ply_io.h>
#include "pcl/io/ply_io.h"
#include <pcl/filters/voxel_grid.h>

// Namespaces
namespace po = boost::program_options;

// Prototypes
pcl::PointCloud<pcl::PointXYZ>::Ptr down_sample(const pcl::PointCloud<pcl::PointXYZ>::Ptr& input_points);
void save_ply(const pcl::PointCloud<pcl::PointXYZ>::Ptr& points, std::string output_file);
pcl::PointCloud<pcl::PointXYZ>::Ptr readPointCloud(std::string points_file, const std::string& input_type);

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

    try {
        std::string input_file;
        std::string input_type;
        std::string output_file;

        po::options_description desc("Allowed options");
        desc.add_options()
                ("help", "produce help message")
                ("input_file", po::value<std::string>(), "Input file (.bin or ply)")
                ("input_type", po::value<std::string>(), "Input type (bin or ply)")
                ("output_file", po::value<std::string>(), "Output file (.ply)");

        po::variables_map vm;
        po::store(po::parse_command_line(argc, argv, desc), vm);
        po::notify(vm);

        if (vm.count("help")) {
            std::cout << desc << "\n";
            return 0;
        }

        if (vm.count("input_file")) {
            input_file = vm["input_file"].as<std::string>();
        } else {
            std::cerr << "Argument required.\n";
            return 1;
        }

        if (vm.count("input_type")) {
            input_type = vm["input_type"].as<std::string>();
        } else {
            std::cerr << "Argument required.\n";
            return 1;
        }

        if (vm.count("output_file")) {
            output_file = vm["output_file"].as<std::string>();
        } else {
            std::cerr << "Argument required.\n";
            return 1;
        }

        std::cout << "Input file: " << input_file << std::endl
                << "Output file: " << output_file << std::endl
                << "Downsampling the pointcloud ..." << std::endl;

        pcl::PointCloud<pcl::PointXYZ>::Ptr points = readPointCloud(input_file, input_type);
        pcl::PointCloud<pcl::PointXYZ>::Ptr points_ds = down_sample(points);
        save_ply(points_ds, output_file);

        std::cout << "Done !" << std::endl;

    }
    catch(std::exception& e) {
        std::cerr << "error: " << e.what() << "\n";
        return 1;
    }
    catch(...) {
        std::cerr << "Exception of unknown type!\n";
        return 1;
    }
    return 0;
}

void save_ply(const pcl::PointCloud<pcl::PointXYZ>::Ptr& points, std::string output_file){
    boost::filesystem::create_directories(boost::filesystem::path(output_file).parent_path());
    pcl::io::savePLYFileBinary(output_file, *points);
}

pcl::PointCloud<pcl::PointXYZ>::Ptr down_sample(const pcl::PointCloud<pcl::PointXYZ>::Ptr& input_points){
    float leaf_size = 0.1f;
    pcl::PointCloud<pcl::PointXYZ>::Ptr output_points(new pcl::PointCloud<pcl::PointXYZ>);
    pcl::VoxelGrid<pcl::PointXYZ> sor;
    sor.setInputCloud (input_points);
    sor.setLeafSize (leaf_size, leaf_size, leaf_size);
    sor.filter (*output_points);
    return(output_points);
}

pcl::PointCloud<pcl::PointXYZ>::Ptr readPointCloud(std::string points_file, const std::string& input_type){

    pcl::PointCloud<pcl::PointXYZ>::Ptr points (new pcl::PointCloud<pcl::PointXYZ>);

    if (input_type == "ply"){
        std::cout << "Using ply reader ..." << std::endl;
        pcl::io::loadPLYFile(points_file, *points);
    }
    else if(input_type == "bin"){
        std::cout << "Using bin reader ..." << std::endl;
        // allocate 4 MB buffer (only ~130*4*4 KB are needed)
        int32_t points_num = 1000000;
        auto *points_data = (float*)malloc(points_num*sizeof(float));

        // pointers
        float *px = points_data+0;
        float *py = points_data+1;
        float *pz = points_data+2;

        // load point cloud
        FILE *points_stream;
        char *points_filename = &points_file[0];
        points_stream = fopen (points_filename,"rb");
        points_num = fread(points_data,sizeof(float),points_num,points_stream)/4;

        for (int32_t i=0; i<points_num; i++) {
            pcl::PointXYZ point;

            point.x = *px;
            point.y = *py;
            point.z = *pz;

            points->push_back(point);
            px+=4; py+=4; pz+=4;
        }
        fclose(points_stream);
    }
    else{
        std::cout << "Reading  the defined input is not implemented" << std::endl;
        return nullptr;
    }

    return points;
}

ext: cxx

max_stars_repo_name: KASCedric/PointNet

max_issues_repo_name: KASCedric/PointNet

max_forks_repo_name: KASCedric/PointNet


text:
/*****************************************************************************
*
* Copyright (c) 2013-2018 by The University of Queensland
* http://www.uq.edu.au
*
* Primary Business: Queensland, Australia
* Licensed under the Apache License, version 2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Development until 2012 by Earth Systems Science Computational Center (ESSCC)
* Development 2012-2013 by School of Earth Sciences
* Development from 2014 by Centre for Geoscience Computing (GeoComp)
*
*****************************************************************************/

#include <escript/EsysMPI.h>

#include <algorithm>
#include <vector>

#include <boost/random/mersenne_twister.hpp>

using namespace std;

namespace {

boost::mt19937 base;            // used to seed all the other generators
vector<boost::mt19937*> gens;
vector<boost::uint32_t> seeds;

void seedGens(long seed)
{
#ifdef _OPENMP
    int numthreads=omp_get_max_threads();
#else
    int numthreads=1;
#endif
    if (gens.size()==0)         // we haven't instantiated the generators yet
    {
        gens.resize(numthreads);
        seeds.resize(numthreads);
    }
    if (seed!=0)
    {
        base.seed((boost::uint32_t)seed); // without this cast, icc gets confused
        for (int i=0;i<numthreads;++i)
        {
            boost::uint32_t b=base();
            seeds[i]=b; // initialise each generator with successive random values
        }
#pragma omp parallel for
        for (int i=0; i<numthreads; ++i)
        {
            gens[i]=new boost::mt19937(seeds[i]);
        }
    }
}

} // anonymous namespace

namespace escript
{

// Put n random values from the interval [0,1] into array.
// Idea here is to create an array of seeds by feeding the original seed into
// the random generator.
// The code at the beginning of the function to compute the seed if one is
// given is just supposed to introduce some variety (and ensure that multiple
// ranks don't get the same seed).
// I make no claim about how well these initial seeds are distributed.
// notes:
// - uses openmp
// - don't forget to call CHECK_FOR_EX_WRITE if using this on Data
void randomFillArray(long seed, double* array, size_t n)
{
    // So if we create a bunch of objects we don't get the same start seed
    static unsigned prevseed=0;
    if (seed==0)                // for each one
    {
        if (prevseed==0)
        {
            time_t s=time(0);
            seed=s;
        }
        else
        {
            seed=prevseed+419;  // these numbers are arbitrary
            if (seed>3040101)   // I want to avoid overflow on 32bit systems
            {
                seed=((int)(seed)%0xABCD)+1;
            }
        }
    }
    // now we need to consider MPI since we don't want each rank to start with
    // the same seed. Rank in COMM_WORLD will do
#ifdef ESYS_MPI
    int rank;
    int mperr=MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    if (mperr != MPI_SUCCESS) {
        rank=0;
    }
    seed+=rank*5;
#endif
    prevseed=seed;

    boost::mt19937::result_type RMAX=base.max();
    seedGens(seed);

#pragma omp parallel
    {
        size_t i;
#ifdef _OPENMP
        int tnum=omp_get_thread_num();
#else
        int tnum=0;
#endif
        boost::mt19937& generator=*(gens[tnum]);

#pragma omp for schedule(static)
        for (i=0;i<n;++i)
        {
            array[i]=((double)generator())/RMAX;
        }
    }
}

// see patternFillArray for details on parameters
void patternFillArray2D(size_t x, size_t y, double* array, size_t spacing,
                        size_t basex, size_t basey, size_t numpoints)
{
    std::fill_n(array, x*y*numpoints, 0.);
    size_t xoff=basex%spacing;
    size_t yoff=basey%spacing;
    for (size_t r=0;r<y;++r)
    {
        size_t step=((r+yoff)%spacing)?spacing:1;
        for (size_t c=0;c<x;++c)
        {
            if ((c+xoff)%step==0)
            {
                for (size_t p=0;p<numpoints;++p)
                {
                    array[(c+r*x)*numpoints+p]=1+p;
                }
            }
        }
    }
}

// fill the array (which we assume is 3D with x by y by z points in it) with
// a pattern.
// The base? params give the coordinates (in # of elements) of the origin of
// _this_ rank.
// Used to ensure patterns are generated consistently across multiple ranks.
// This is only for internal debug so the patterns (or this function) may
// disappear without notice
void patternFillArray(int pattern, size_t x, size_t y, size_t z, double* array,
                      size_t spacing, size_t basex, size_t basey, size_t basez,
                      size_t numpoints)
{
    if (pattern==0)     // a cross pattern in the z=0 plane, repeated for each z layer
    {
        std::fill_n(array, x*y*numpoints, 0.);
        size_t xoff=basex%spacing;
        size_t yoff=basey%spacing;
        for (size_t r=0;r<y;++r)
        {
            size_t step=((r+yoff)%spacing)?spacing:1;
            for (size_t c=0;c<x;++c)
            {
                if ((c+xoff)%step==0)
                {
                    for (size_t p=0;p<numpoints;++p)
                    {
                        array[(c+r*x)*numpoints+p]=p+1;
                    }
                }
            }
        }
        for (size_t l=1;l<z;++l)
        {
            std::copy(array, &array[x*y*numpoints], &array[l*x*y*numpoints]);
        }
    }
    else                // pattern 1. A grid in all 3 dimensions
    {
        if (z<2)
        {
            patternFillArray(0, x, y, z, array, spacing, basex, basey, basez, numpoints);
            return;     // this pattern needs a minimum of 2 layers
        }
        size_t xoff=basex%spacing;
        size_t yoff=basey%spacing;
        size_t zoff=basez%spacing;

        double* buff1=new double[x*y*numpoints];        // stores the main cross pattern
        double* buff2=new double[x*y*numpoints];        // stores the "verticals"
        std::fill_n(buff1, x*y*numpoints, 0.);
        std::fill_n(buff2, x*y*numpoints, 0.);
        // fill in buff1
        for (size_t r=0;r<y;++r)
        {
            size_t step=((r+yoff)%spacing)?spacing:1;
            for (size_t c=0;c<x;++c)
            {
                if ((c+xoff)%step==0)
                {
                    for (size_t p=0;p<numpoints;++p)
                    {
                        buff1[(c+r*x)*numpoints+p]=p+1;
                    }
                }
            }
        }

        for (size_t r=(spacing-yoff)%spacing;r<y;r+=spacing)
        {
            for (size_t c=(spacing-xoff)%spacing;c<x;c+=spacing)
            {
                for (size_t p=0;p<numpoints;++p)
                {
                    buff2[(c+r*x)*numpoints+p]=p+1;
                }
            }
        }
        for (size_t l=0;l<z;++l)
        {
            if ((l+zoff)%spacing)
            {
                std::copy(buff2, buff2+x*y*numpoints, &array[x*y*l*numpoints]);
            }
            else
            {
                std::copy(buff1, buff1+x*y*numpoints, &array[x*y*l*numpoints]);
            }
        }
        delete[] buff1;
        delete[] buff2;
    }
}

} // end namespace

ext: cpp


text:
// testApp.cpp : Defines the entry point for the console application.
//

#include <lvTlsCallbackBase.h>
#include <lvTlsEngine.h>
#include <lvTlsSocket.h>
#include <lvTlsConnectionCreator.h>
#include <stdio.h>
#include <algorithm>
#include <memory>
#include <cstdlib>
#include <iostream>
#include <vector>
#include <thread>
#include <boost/bind.hpp>
#include <boost/ref.hpp>
#include <boost/asio.hpp>
#include <boost/asio/ssl.hpp>
#include <boost/thread.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <boost/lockfree/queue.hpp>
#include <boost/lockfree/spsc_queue.hpp>
#include <chrono>

using namespace boost::asio;
using namespace lvasynctls;

class testCB : public lvasynctls::lvTlsCallback {
public:
	std::string pval;
	boost::lockfree::spsc_queue<std::string> * queue;

	testCB(std::string printer, boost::lockfree::spsc_queue<std::string> * q) :pval(printer), queue{ q }
	{
		return;
	}

	void execute() {
		queue->push(pval);
	}

	void printError() {
		if (ec) {
			std::cout << "error occurred: " << ec << "\n" << "error message: " << emsg << "\n";
		}
		else {
			std::cout << "no error but callback called anyway\n";
		}
	}

	virtual void setErrorCondition(int code, std::string message) override {
		ec = code;
		emsg = message;
		printError();
	}

private:
	std::string emsg;
	int ec;
};

int main(int argc, char* argv[])
{
	std::cout << "hello\n";
	std::shared_ptr<lvAsyncEngine> engine { new lvasynctls::lvAsyncEngine() };
	std::cout << "new IO engine\n";
	std::shared_ptr<lvTlsClientConnector> client { new lvasynctls::lvTlsClientConnector(engine, 2) };
	engine->registerConnector(client);
	std::cout << "new client\n";

	auto hostName ="www.google.com";
	auto port = "443";
	auto q = new boost::lockfree::spsc_queue<std::string>(50);

	std::string s;

	client->resolveAndConnect(hostName, port, 5000000, new testCB("connected", q));

	while (!(q->pop(s))) {
		std::this_thread::sleep_for(std::chrono::milliseconds(100));
	}

	std::cout << s;

	auto conn = client->getNextConnection();

	if (conn.get()) {

		std::string req = "GET / HTTP/1.0\r\nAccept: */*\r\nConnection: close\r\n\r\n\0";
		auto vdata = new std::vector<unsigned char>{ req.begin(), req.end() };
		std::cout << "starting write\n";
		conn->startWrite(vdata, new testCB("sent", q));

		while (!(q->pop(s))) {
			std::this_thread::sleep_for(std::chrono::milliseconds(100));
		}
		std::cout << s << "\n";

		conn->startStreamReadUntilTermString("\r\n\r\n", 100000, new testCB("read done", q));

		while (!(q->pop(s))) {
			std::this_thread::sleep_for(std::chrono::milliseconds(100));
		}
		std::cout << s << "\n";

		auto bytesRead = conn->getInputStreamSize();

		std::cout << "bytes available: "<< bytesRead << "\n";

		auto readBuf = new char[bytesRead + 1];

		auto actualSize = conn->inputStreamReadN(readBuf, bytesRead);
		std::cout << "bytes read: " << actualSize << "\n";

		readBuf[actualSize] = 0;

		std::cout << "data:\n" << readBuf << "\nfin\n";

		delete[] readBuf;
		conn->shutdown();
		conn.reset();
	}
	else {
		std::cout << "conn failed\n";
	}

	client->shutdown();
	client.reset();
	std::cout << "dispose client\n";

	engine->shutdown();
	engine.reset();
	std::cout << "dispose eng\n";

	int blah;
	std::cin >> blah;

	return 0;
}

max_stars_repo_path: test code/testApp.cpp

max_stars_repo_name: smithed/lvasynctls

max_issues_repo_path: test code/testApp.cpp

max_issues_repo_name: smithed/lvasynctls

max_forks_repo_path: test code/testApp.cpp

max_forks_repo_name: smithed/lvasynctls


text:
/*
 * Sarus
 *
 * Copyright (c) 2018-2022, ETH Zurich. All rights reserved.
 *
 * Please, refer to the LICENSE file in the root directory.
 * SPDX-License-Identifier: BSD-3-Clause
 *
 */

#include <type_traits>

#include "common/Error.hpp"
#include "common/Utility.hpp"
#include "common/Lockfile.hpp"

#include <boost/filesystem.hpp>
#include "test_utility/unittest_main_function.hpp"

using namespace sarus;

TEST_GROUP(LockfileTestGroup) {
    boost::filesystem::path fileToLock = common::makeUniquePathWithRandomSuffix("/tmp/file-to-lock");
    boost::filesystem::path lockfile = fileToLock.string() + ".lock";
};

TEST(LockfileTestGroup, creation_of_physical_lockfile) {
    CHECK(!boost::filesystem::exists(lockfile));
    common::Lockfile lock{fileToLock};
    CHECK(boost::filesystem::exists(lockfile));
}

TEST(LockfileTestGroup, lock_acquisition) {
    {
        common::Lockfile lock{fileToLock};
    }
    {
        // check that we can reacquire the lock
        // (previous lock was released when went out of scope)
        common::Lockfile lock{fileToLock};
    }
    {
        common::Lockfile lock{fileToLock};
        // check that lock cannot be acquired more than once
        CHECK_THROWS(common::Error, common::Lockfile(fileToLock, 0));
        // even if we try again...
        CHECK_THROWS(common::Error, common::Lockfile(fileToLock, 0));
    }
}

TEST(LockfileTestGroup, move_constructor) {
    common::Lockfile original{fileToLock};
    {
        common::Lockfile moveConstructed{std::move(original)};
        // check that lock cannot be acquired more than once (move constructed lock is still active)
        CHECK_THROWS(common::Error, common::Lockfile(fileToLock, 0));
    }
    // check that lock can be acquired (move-constructed lock went out of scope)
    common::Lockfile newlock{fileToLock};
}

TEST(LockfileTestGroup, move_assignment) {
    common::Lockfile original{fileToLock};
    {
        common::Lockfile moveAssigned;
        moveAssigned = std::move(original);
        // check that lock cannot be acquired more than once (move assigned lock is still active)
        CHECK_THROWS(common::Error, common::Lockfile(fileToLock, 0));
    }
    // check that lock can be acquired (move-assigned lock went out of scope)
    common::Lockfile newlock{fileToLock};
}

static_assert(!std::is_copy_constructible<common::Lockfile>::value, "");
static_assert(!std::is_copy_assignable<common::Lockfile>::value, "");
static_assert(std::is_move_constructible<common::Lockfile>::value, "");
static_assert(std::is_move_assignable<common::Lockfile>::value, "");

SARUS_UNITTEST_MAIN_FUNCTION();

max_stars_repo_name: rayrayson/sarus

max_issues_repo_name: rayrayson/sarus

max_forks_repo_name: rayrayson/sarus


text:
/**
 * $Id$
 *
 * Software License Agreement (GNU General Public License)
 *
 *  Copyright (C) 2015:
 *
 *    Johann Prankl, prankl@acin.tuwien.ac.at
 *    Aitor Aldoma, aldoma@acin.tuwien.ac.at
 *
 *      Automation and Control Institute
 *      Vienna University of Technology
 *      Gusshausstraße 25-29
 *      1170 Vienn, Austria
 *
 *  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 3 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, see <http://www.gnu.org/licenses/>.
 *
 * @author Johann Prankl, Aitor Aldoma
 *
 */
#ifndef EIGEN_BOOST_SERIALIZATION
#define EIGEN_BOOST_SERIALIZATION
#include <Eigen/Sparse>
#include <Eigen/Dense>
#include <boost/serialization/split_free.hpp>
#include <boost/serialization/vector.hpp>

namespace boost{namespace serialization{
    template <class Archive, typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
        void save(Archive & ar, const Eigen::Matrix<_Scalar,_Rows,_Cols,_Options,_MaxRows,_MaxCols> & m, const unsigned int version) {
            int rows=m.rows(),cols=m.cols();
            ar & rows;
            ar & cols;
            ar & boost::serialization::make_array(m.data(), rows*cols);
        }
    template <class Archive, typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
        void load(Archive & ar, Eigen::Matrix<_Scalar,_Rows,_Cols,_Options,_MaxRows,_MaxCols> & m, const unsigned int version) {
            int rows,cols;
            ar & rows;
            ar & cols;
            m.resize(rows,cols);
            ar & boost::serialization::make_array(m.data(), rows*cols);
        }

    template <class Archive, typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
        void serialize(Archive & ar, Eigen::Matrix<_Scalar,_Rows,_Cols,_Options,_MaxRows,_MaxCols> & m, const unsigned int version) {
            split_free(ar,m,version);
        }

    /*template <class Archive, typename _Scalar>
        void save(Archive & ar, const Eigen::Triplet<_Scalar> & m, const unsigned int version) {
            ar & m.row();
            ar & m.col();
            ar & m.value();
        }
    template <class Archive, typename _Scalar>
        void load(Archive & ar, Eigen::Triplet<_Scalar> & m, const unsigned int version) {
            int row,col;
            _Scalar value;
            ar & row;
            ar & col;
            ar & value;
            m = Eigen::Triplet<_Scalar>(row,col,value);
        }

    template <class Archive, typename _Scalar>
        void serialize(Archive & ar, Eigen::Triplet<_Scalar> & m, const unsigned int version) {
            split_free(ar,m,version);
        }

    template <class Archive, typename _Scalar, int _Options,typename _Index>
        void save(Archive & ar, const Eigen::SparseMatrix<_Scalar,_Options,_Index> & m, const unsigned int version) {
            int innerSize=m.innerSize();
            int outerSize=m.outerSize();
            typedef typename Eigen::Triplet<_Scalar> Triplet;
            std::vector<Triplet> triplets;
            for(int i=0; i < outerSize; ++i) {
                for(typename Eigen::SparseMatrix<_Scalar,_Options,_Index>::InnerIterator it(m,i); it; ++it) {
                triplets.push_back(Triplet(it.row(), it.col(), it.value()));
                }
            }
            ar & innerSize;
            ar & outerSize;
            ar & triplets;
        }
    template <class Archive, typename _Scalar, int _Options, typename _Index>
        void load(Archive & ar, Eigen::SparseMatrix<_Scalar,_Options,_Index>  & m, const unsigned int version) {
            int innerSize;
            int outerSize;
            ar & innerSize;
            ar & outerSize;
            int rows = m.IsRowMajor?outerSize:innerSize;
            int cols = m.IsRowMajor?innerSize:outerSize;
            m.resize(rows,cols);
            typedef typename Eigen::Triplet<_Scalar> Triplet;
            std::vector<Triplet> triplets;
            ar & triplets;
            m.setFromTriplets(triplets.begin(), triplets.end());

        }
    template <class Archive, typename _Scalar, int _Options, typename _Index>
        void serialize(Archive & ar, Eigen::SparseMatrix<_Scalar,_Options,_Index> & m, const unsigned int version) {
            split_free(ar,m,version);
        }
    */

}}
#endif

ext: hpp


text: #include <boost/mpl/aux_/largest_int.hpp>

max_stars_repo_name: miathedev/BoostForArduino

max_issues_repo_name: miathedev/BoostForArduino

max_forks_repo_name: miathedev/BoostForArduino


text:
/*
// Copyright (c) 2000-2009, Texas Engineering Experiment Station (TEES), a
// component of the Texas A&M University System.

// All rights reserved.

// The information and source code contained herein is the exclusive
// property of TEES and may not be disclosed, examined or reproduced
// in whole or in part without explicit written authorization from TEES.
*/

#include <iostream>

#include <stapl/utility/tuple.hpp>
#include <stapl/domains/indexed.hpp>

#include <stapl/views/vector_view.hpp>
#include <stapl/containers/vector/vector.hpp>

#include <stapl/views/array_view.hpp>
#include <stapl/containers/array/array.hpp>

#include <stapl/views/map_view.hpp>
#include <stapl/containers/map/map.hpp>

#include <stapl/containers/unordered_multiset/unordered_multiset.hpp>

#include <stapl/skeletons/serial.hpp>
#include <stapl/algorithms/algorithm.hpp>
#include <stapl/algorithms/functional.hpp>

#include <stapl/runtime.hpp>

#include <stapl/stream.hpp>
#include <sstream>

#include <boost/bind.hpp>
#include <boost/program_options.hpp>
#include <boost/property_tree/ptree.hpp>
#include "json_parser.hpp"

using namespace std;
#include "testutil.hpp"
#include "rel_alpha_data.h"

// #define BIG_FILES // Uncomment when big and huge files are present
// #define TRIPLE_MAP_REDUCE // Uncomment when the bug is fixed

// Disable some tests by commenting the defines below:
// 2-lvl tests:
#define TEST_SET_2LVL_01
#define TEST_SET_2LVL_02
#define TEST_SET_2LVL_03
// #define TEST_SET_2LVL_04 // COMPILES BUT DOESN'T RUN : MAP BUG
#define TEST_SET_2LVL_05
#define TEST_SET_2LVL_06

// 3-lvl tests:
#define TEST_SET_3LVL_01
// #define TEST_SET_3LVL_02 // #ifdef TRIPLE_MAP_REDUCE
// #define TEST_SET_3LVL_03 // #ifdef TRIPLE_MAP_REDUCE
// #define TEST_SET_3LVL_04 // #ifdef TRIPLE_MAP_REDUCE
// #define TEST_SET_3LVL_05 // MAP BUG
// #define TEST_SET_3LVL_06 // MAP BUG

/*=========================================================================*/
#ifdef TEST_SET_2LVL_01
size_t nestpar_unordered_multiset_01(size_t, stapl::stream<ofstream>& );
#endif
#ifdef TEST_SET_2LVL_02
size_t nestpar_unordered_multiset_02(size_t, stapl::stream<ofstream>& );
#endif
#ifdef TEST_SET_2LVL_03
size_t nestpar_unordered_multiset_03(size_t, stapl::stream<ofstream>& );
#endif
#ifdef TEST_SET_2LVL_04
size_t nestpar_unordered_multiset_04(size_t, stapl::stream<ofstream>& );
#endif
#ifdef TEST_SET_2LVL_05
size_t nestpar_unordered_multiset_05(size_t, stapl::stream<ofstream>& );
#endif
#ifdef TEST_SET_2LVL_06
size_t nestpar_unordered_multiset_06(size_t,
                                stapl::stream<ifstream>&,
                                stapl::stream<ofstream>& );
#endif
#ifdef TEST_SET_3LVL_01
size_t nestpar_unordered_multiset_10(size_t, stapl::stream<ofstream>& );
#endif
#ifdef TEST_SET_3LVL_02
size_t nestpar_unordered_multiset_11(size_t, stapl::stream<ofstream>& );
#endif
#ifdef TEST_SET_3LVL_03
size_t nestpar_unordered_multiset_12(size_t, stapl::stream<ofstream>& );
#endif
#ifdef TEST_SET_3LVL_04
size_t nestpar_unordered_multiset_13(size_t, stapl::stream<ofstream>& );
#endif
#ifdef TEST_SET_3LVL_05
size_t nestpar_unordered_multiset_14(size_t, stapl::stream<ofstream>& );
#endif
#ifdef TEST_SET_3LVL_06
size_t nestpar_unordered_multiset_15(size_t, stapl::stream<ofstream>& );
#endif

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

extern int prime100k[];
extern int rand100k[];

int fibo[20] = { 1, 2, 3, 5, 8,
                 13, 21, 34, 55, 89,
                 144, 233, 377, 610, 987,
                 1597, 2584, 4181, 6765, 10946 };

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

typedef stapl::unordered_multiset<int> set_int_tp;

// -- 2-lvl set : --
typedef stapl::vector< set_int_tp > vec_set_int_tp;
typedef stapl::vector_view<vec_set_int_tp> vec_set_int_vw_tp;

typedef stapl::array< set_int_tp > ary_set_int_tp;
typedef stapl::array_view<ary_set_int_tp> ary_set_int_vw_tp;

typedef stapl::map< int, set_int_tp > map_set_int_tp;
typedef stapl::map_view<map_set_int_tp> map_set_int_vw_tp;
// 3 level :
  // vec<vec<set>>
typedef stapl::vector<vec_set_int_tp> vec_vec_set_int_tp;
typedef stapl::vector_view<vec_vec_set_int_tp> vec_vec_set_int_vw_tp;

  // ary<vec<set>>
typedef stapl::array<vec_set_int_tp> ary_vec_set_int_tp;
typedef stapl::array_view<ary_vec_set_int_tp> ary_vec_set_int_vw_tp;

  // vec<ary<set>>
typedef stapl::vector<ary_set_int_tp> vec_ary_set_int_tp;
typedef stapl::vector_view<vec_ary_set_int_tp> vec_ary_set_int_vw_tp;

  // vec<map<set>>
typedef stapl::vector<map_set_int_tp> vec_map_set_int_tp;
typedef stapl::vector_view<vec_map_set_int_tp> vec_map_set_int_vw_tp;

  // map<ary<set>>
typedef stapl::map< int, ary_set_int_tp > map_ary_set_int_tp;
typedef stapl::map_view<map_ary_set_int_tp> map_ary_set_int_vw_tp;

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

typedef stapl::array<size_t> ary_sz_tp;
typedef stapl::array_view<ary_sz_tp> ary_sz_vw_tp;

typedef stapl::indexed_domain<int> ndx_dom_tp;

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

typedef stapl::identity<int> id_int_wf;
typedef stapl::identity<size_t> id_un_wf;
typedef stapl::negate<int> neg_int_wf;

typedef stapl::plus<int> add_int_wf;
typedef stapl::minus<int> sub_int_wf;
typedef stapl::min<int> min_int_wf;
typedef stapl::max<int> max_int_wf;

typedef stapl::bit_xor<size_t> xor_un_wf;
typedef stapl::bit_or<size_t> ior_un_wf;
typedef stapl::bit_and<size_t> and_un_wf;

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

void open_zin(int model, int test, stapl::stream<ifstream>& zin)
{
  switch ( model ) {
  case 1:
    switch( test ) {
    case 1:
      zin.open("tiny_factors.zin");
      break;
    default:
      zin.open("tiny_primes.zin");
      break;
    }
    break;
  case 100:
    switch( test ) {
      case 1:
      zin.open("data/small_factors.zin");
      break;
    default:
      zin.open("data/small_primes.zin");
      break;
    }
    break;
  case 10000:
    switch( test ) {
      case 1:
      zin.open("data/medium_factors.zin");
      break;
    default:
      zin.open("data/medium_primes.zin");
      break;
    }
    break;
  #ifdef BIG_FILES
  case 1000000:
    switch( test ) {
    case 1:
      zin.open("data/big_factors.zin");
      break;
    default:
      zin.open("data/big_primes.zin");
      break;
    }
    break;
  case 100000000:
    switch( test ) {
    case 1:
      zin.open("data/huge_factors.zin");
      break;
    default:
      zin.open("data/huge_primes.zin");
      break;
    }
    break;
  #endif
  }
}

struct put_val_wf
{
private:
  // pointer to p_object is necessary to allow work function serialization.
  stapl::stream<ofstream> m_zout;
public:
  typedef void result_type;

  put_val_wf(stapl::stream<ofstream> const& zout)
    : m_zout(zout)
  { }

  template <typename Ref>
  void operator()(Ref val)
  {
    m_zout << val << " ";
  }

  void define_type(stapl::typer& t)
  {
    t.member(m_zout);
  }

};

struct nestpar_cksum_wf
{
  typedef size_t result_type;

  template<typename Ref1>
  size_t operator()(Ref1 v1)
  {
    return stapl::map_reduce(id_un_wf(), xor_un_wf(), v1);
  }
};

struct map_set_cksum_wf
{
  typedef int result_type;

  template<typename Element>
  int operator()(Element elem) const
  {
    return stapl::map_reduce(id_int_wf(), xor_un_wf(), elem.second);
  }
};

struct map_outer_3lvl_cksum_wf
{
  typedef int result_type;

  template<typename Element>
  int operator()(Element elem) const
  {
    return stapl::map_reduce(nestpar_cksum_wf(), xor_un_wf(), elem.second);
  }
};

struct map_middle_3lvl_cksum_wf
{
  typedef int result_type;

  template<typename Element>
  int operator()(Element elem) const
  {
    return stapl::map_reduce(map_set_cksum_wf(), xor_un_wf(), elem);
  }
};

struct inner_set_show_wf
{
private:
 // pointer to p_object is necessary to allow work function serialization.
  stapl::stream<ofstream> m_zout;
public:
  typedef void result_type;

  inner_set_show_wf(stapl::stream<ofstream> const& zout)
    : m_zout(zout)
  { }

  template<typename Element>
  void operator()(Element elem)
  {
    //FIXME, ss shouldn't be necessary
    stringstream ss;
    ss  << "{" << elem << "}" << endl;
    m_zout << ss.str();
  }

  void define_type(stapl::typer& t)
  {
    t.member(m_zout);
  }

};

struct outer_map_show_inn_set_wf
{
private:
 // pointer to p_object is necessary to allow work function serialization.
  stapl::stream<ofstream> m_zout;
public:
  typedef void result_type;

  outer_map_show_inn_set_wf(stapl::stream<ofstream> const& zout)
    : m_zout(zout)
  { }

  template<typename Element>
  void operator()(Element elem)
  {
    stapl::serial_io(inner_set_show_wf(m_zout), elem.second);
  }

  void define_type(stapl::typer& t)
  {
    t.member(m_zout);
  }

};

struct roll_wf
{
  typedef void result_type;

  template <typename View1, typename View2>
  void operator()(View1 length, View2 & limit) const
  {
    length = limit;
  }
};

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

int opt_test = -1;
char *opt_data = 0;

stapl::exit_code stapl_main(int argc, char **argv)
{

  stapl::stream<ifstream> zin;
  stapl::stream<ofstream> zout;

  char *temp = 0;
  for ( int argi = 1; argi < argc; ) {
    char * opt = argv[argi++];
    if ('-' == opt[0] ) {
      switch ( opt[1] ) {
      case 'h':
        cerr << "Specify the data size with -d $X \n"
        << "With $X = "<< endl
        << " t for tiny" << endl
        << " s for small" << endl
        << " m for medium" << endl;
        break;
      case 'd':
        opt_data = argv[argi++];
        break;
      }
    } else {
      cerr << "unknown command line argument " << opt << endl;
    }
  }

  int model = -1;
  switch ( opt_data[0] ) {
  case 't':
    model = 1;
    break;
  case 's':
    model = 100;
    break;
  case 'm':
    model = 10000;
    break;
  case 'b':
    model = 10000000;
    break;
  case 'h':
    model = 100000000;
    break;
  default:
    cerr << "opt_data " << opt_data << endl;
    break;
  }
  if (model == -1) {
    std::cerr << "usage: exe -d [t|s|m]\n";
    exit(1);
  }

  int first_test = 1;
  int last_test = 36;
  if (opt_test != -1 ) {
    first_test = opt_test;
    last_test = opt_test;
  }

  bool ok = true;
  first_test = 1; last_test = 12;
  if ( stapl::get_location_id() == 0 )
        std::cout << "Nested Parallel Set " << endl;
  for ( int test=first_test; test<=last_test; test++ ) {
    if ( stapl::get_location_id() == 0 )
      std::cerr << "Test #" << test << ": ";
    size_t result = 0;
    bool disabled = false;
    switch ( test) {
    case 1:
      #ifdef TEST_SET_2LVL_01
      result = nestpar_unordered_multiset_01(model, zout);
      #else
      disabled = true;
      #endif
      break;
    case 2:
      #ifdef TEST_SET_2LVL_02
      result = nestpar_unordered_multiset_02(model, zout);
      #else
      disabled = true;
      #endif
      break;
    case 3:
      #ifdef TEST_SET_2LVL_03
      result = nestpar_unordered_multiset_03(model, zout);
      #else
      disabled = true;
      #endif
      break;
    case 4:
      #ifdef TEST_SET_2LVL_04
      result = nestpar_unordered_multiset_04(model, zout);
      #else
      disabled = true;
      #endif
      break;
    case 5:
      #ifdef TEST_SET_2LVL_05
      result = nestpar_unordered_multiset_05(model, zout);
      #else
      disabled = true;
      #endif
      break;
    case 6:
      #ifdef TEST_SET_2LVL_06
      result = nestpar_unordered_multiset_06(model, zin, zout);
      #else
      disabled = true;
      #endif
      break;
    case 7:
      #ifdef TEST_SET_3LVL_01
      result = nestpar_unordered_multiset_10(model, zout);
      #else
      disabled = true;
      #endif
      break;
    case 8:
      #ifdef TEST_SET_3LVL_02
      result = nestpar_unordered_multiset_11(model, zout);
      #else
      disabled = true;
      #endif
      break;
    case 9:
      #ifdef TEST_SET_3LVL_03
      result = nestpar_unordered_multiset_12(model, zout);
      #else
      disabled = true;
      #endif
      break;
    case 10:
      #ifdef TEST_SET_3LVL_04
      result = nestpar_unordered_multiset_13(model, zout);
      #else
      disabled = true;
      #endif
      break;
    case 11:
      #ifdef TEST_SET_3LVL_05
      result = nestpar_unordered_multiset_14(model, zout);
      #else
      disabled = true;
      #endif
      break;
    case 12:
      #ifdef TEST_SET_3LVL_06
      result = nestpar_unordered_multiset_15(model, zout);
      #else
      disabled = true;
      #endif
      break;

    default:
      std::cerr << endl
                << "-- test "
                << test
                << " not yet implemented --"
                << endl;
      break;

    }

    bool passed;
    passed = (result == 0);

    if ( stapl::get_location_id() == 0) {
      if (disabled)
        std::cerr << "Disabled" << endl;
      else
      {
        if (passed)
          std::cerr << "[PASSED] " << endl;
        else
          std::cerr << "[FAILED] " << endl;
      }
    }
  }
  return EXIT_SUCCESS;
}

/*=========================================================================
 * heterogeneous nested structures
 *=========================================================================*/

// --------------
// ---- Fill ----
// --------------

struct insert_wf
{

  typedef void result_type;
  size_t m_size;

  insert_wf(size_t sz)
    : m_size(sz)
  { }

  template <typename T,typename View>
  void operator()(T i,View& vw)
  {
    if ( m_size <= 100000 )
      vw.insert(rand_nums[i]);
    else
    {
      size_t k = i % 10000;
      vw.insert( prime_nums[k] * prime_nums[10000-k] );
    }
  }

  void define_type(stapl::typer& t)
  {
    t.member(m_size);
  }

};

struct nestpar_inner_set_fill_wf
{

  typedef void result_type;

  size_t m_size;

  nestpar_inner_set_fill_wf(size_t sz)
    : m_size(sz)
  { }

  template <typename View1>
  void operator()(View1 vw1) //FIXME: View1 & vw1 should work.
  {
    insert_wf insertwf(m_size);
    stapl::map_func(insertwf,
                    stapl::counting_view<size_t>(m_size),
                    stapl::make_repeat_view(vw1));

  }

  void define_type(stapl::typer& t)
  {
    t.member(m_size);
  }

};

struct nestpar_inner_set_fill_fromfile_wf
{
private:
  size_t m_size;
  // pointer to p_object is necessary to allow work function serialization.
  stapl::stream<ifstream> m_zin;
public:
  typedef void result_type;

  nestpar_inner_set_fill_fromfile_wf(size_t sz,
    stapl::stream<ifstream> const& zin)
    : m_size(sz),m_zin(zin)
  { }

  template <typename ViewOverSet>
  void operator()(ViewOverSet vw_set)//FIXME: ViewOverSet & vw_set should work.
  {
    typename ViewOverSet::value_type t;
    for ( size_t i = 0; i < m_size; i++ ) {
      m_zin >> t;
      vw_set.insert(t);
    }
  }

  void define_type(stapl::typer& t)
  {
    t.member(m_size);
    t.member(m_zin);
  }

};
// --------------
// ---- Show ----
// --------------

struct nestpar_inner_set_show_wf
{
private:
  // pointer to p_object is necessary to allow work function serialization.
  stapl::stream<ofstream> m_zout;
public:
  typedef void result_type;

  nestpar_inner_set_show_wf(stapl::stream<ofstream> const& zout)
    : m_zout(zout)
  { }

  template <typename View1>
  void operator()(View1 const &vw1)
  {
    stapl::serial_io(put_val_wf(m_zout), vw1);
  }

  void define_type(stapl::typer& t)
  {
    t.member(m_zout);
  }

};

struct nestpar_outer_cksum_wf
{
  typedef size_t result_type;

  template<typename Ref1>
  size_t operator()(Ref1 v1)
  {
    return stapl::map_reduce(nestpar_cksum_wf(), xor_un_wf(), v1);
  }
};

// -------------
// -- Process --
// -------------
struct nestpar_size_process_wf
{
  typedef long int result_type;

  template <typename View1>
  long int operator()(View1 const &vw1)
  {
    return vw1.size();
  }
};

struct nestpar_map_reduce_process_wf
{
  typedef long int result_type;

  template <typename View1>
  long int operator()(View1 const &vw1)
  {
    return stapl::map_reduce( id_int_wf(), add_int_wf(), vw1);
  }
};

template<typename NestedContainer,
         typename NestedContainerView,
         typename FillWF = nestpar_inner_set_fill_wf >
class two_lvl_test_wrapper
{
public:

  template <typename Filename,typename ProcessWF>
  size_t run_test(size_t model,
                  Filename output_filename,
                  ProcessWF & proc_wf,
                  stapl::stream<ofstream>& zout)
  {

    size_t size = 100 * model;
    size_t limit = 100 * model;
    set_random_seed();
    zout.open(output_filename);

    stapl::counter<stapl::default_timer> ctr;
    ctr.start();

    NestedContainer a(size);
    NestedContainerView a_vw(a);

    stapl::map_func(FillWF(model*2), a_vw );

    stapl::map_func(proc_wf, a_vw );

    stapl::serial_io(nestpar_inner_set_show_wf(zout), a_vw );

    ctr.stop();
    double time1 = ctr.value();

    zout.close();

    size_t result = stapl::map_reduce(nestpar_cksum_wf(), xor_un_wf(), a_vw);
    return result;
  }

  template <typename Filename,typename ProcessWF>
  size_t run_test(size_t model,
                  Filename output_filename,
                  ProcessWF & proc_wf,
                  stapl::stream<ifstream>& zin,
                  stapl::stream<ofstream>& zout)
  {

    size_t size = 100 * model;
    size_t limit = 100 * model;
    set_random_seed();
    zout.open(output_filename);

    stapl::counter<stapl::default_timer> ctr;
    ctr.start();

    NestedContainer a(size);
    NestedContainerView a_vw(a);

    stapl::map_func(FillWF(model*2,zin), a_vw );

    stapl::map_func(proc_wf, a_vw );

    stapl::serial_io(nestpar_inner_set_show_wf(zout), a_vw );

    ctr.stop();
    double time1 = ctr.value();

    zout.close();

    size_t result = stapl::map_reduce(nestpar_cksum_wf(), xor_un_wf(), a_vw);
    return result;
  }

};

template<typename NestedContainer, typename NestedContainerView>
class two_lvl_test_wrapper_mapreduce
{
public:

  template <typename Filename,typename ProcessWF>
  size_t run_test(size_t model,
                  Filename output_filename,
                  ProcessWF & proc_wf,
                  stapl::stream<ofstream>& zout)
  {

    size_t size = 100 * model;
    size_t limit = 100 * model;
    set_random_seed();
    zout.open(output_filename);

    stapl::counter<stapl::default_timer> ctr;
    ctr.start();

    NestedContainer a(size);
    NestedContainerView a_vw(a);

    stapl::map_func(nestpar_inner_set_fill_wf(model*2), a_vw  );

    add_int_wf::result_type res=stapl::map_reduce( proc_wf, add_int_wf(), a_vw);
    if (stapl::get_location_id() == 0)
    {
      //FIXME, ss shouldn't be necessary
      stringstream ss;
      ss << "map_reduce result (accumulate all elements from all sets):"
        << res << endl;
      zout << ss.str();
    }

    stapl::serial_io(nestpar_inner_set_show_wf(zout), a_vw );

    ctr.stop();
    double time1 = ctr.value();

    zout.close();

    return stapl::map_reduce(nestpar_cksum_wf(), xor_un_wf(), a_vw);
  }

};
// --------------------------
// - 3-level-deep functions -
// --------------------------

// --------------
// ---- Fill ----
// --------------

template <typename FillWF>
struct nestpar_outer_fill_wf
{

  typedef void result_type;

  size_t m_size;

  nestpar_outer_fill_wf(size_t sz)
    : m_size(sz)
  { }

  template <typename View1>
  void operator()(View1 const& vw1)
  {
    stapl::map_func(FillWF(m_size), vw1);
  }

  void define_type(stapl::typer& t)
  {
    t.member(m_size);
  }

};

struct middle_insert_wf
{

  typedef void result_type;
  size_t m_size;

  middle_insert_wf(size_t sz)
    : m_size(sz)
  { }

  template <typename T,typename View>
  void operator()(T i,View& vw)
  {
    if ( m_size <= 100000 ) {
      for ( size_t j = 0; j < m_size; j++ ) {
        vw[ prime_nums[i] ].insert(rand_nums[j]);
      }
    } else {
      for ( size_t j = 0; j < m_size; j+=10000 ) {
        for ( size_t k = 0; k < 10000; k++ )
          vw[ prime_nums[i%10000] * prime_nums[10000-(i%10000)] ].insert(
            rand_nums[k] * rand_nums[10000-k]);
      }
    }
  }

  void define_type(stapl::typer& t)
  {
    t.member(m_size);
  }

};

struct nestpar_middlemap_set_fill_wf
{

  typedef void result_type;

  size_t m_size;

  nestpar_middlemap_set_fill_wf(size_t sz)
    : m_size(sz)
  { }

  template <typename View1>
  void operator()(View1 const& map_set_vw1)
  {
    middle_insert_wf insertwf(m_size);
    stapl::map_func(insertwf,
                    stapl::counting_view<size_t>(m_size),
                    stapl::make_repeat_view(map_set_vw1));
  }

  void define_type(stapl::typer& t)
  {
    t.member(m_size);
  }

};

// --------------
// ---- Show ----
// --------------

struct nestpar_outer_show_wf
{

private:
  // pointer to p_object is necessary to allow work function serialization.
  stapl::stream<ofstream> m_zout;
public:
  typedef void result_type;

  nestpar_outer_show_wf(stapl::stream<ofstream> const& zout)
    : m_zout(zout)
  { }

  template <typename View1>
  void operator()(View1 const& vw1)
  {
    stapl::serial_io(nestpar_inner_set_show_wf(m_zout), vw1);
  }

  void define_type(stapl::typer& t)
  {
    t.member(m_zout);
  }
};

struct outer_map_3lvl_show_inn_set_wf
{

private:
 // pointer to p_object is necessary to allow work function serialization.
  stapl::stream<ofstream> m_zout;
public:
  typedef void result_type;

  outer_map_3lvl_show_inn_set_wf(stapl::stream<ofstream> const& zout)
    : m_zout(zout)
  { }

  template<typename Element>
  void operator()(Element elem)
  {
    stapl::serial_io(nestpar_inner_set_show_wf(m_zout), elem.second);
  }

  void define_type(stapl::typer& t)
  {
   t.member(m_zout);
  }
};

struct nestpar_middle_map_show_wf
{
private:
 // pointer to p_object is necessary to allow work function serialization.
  stapl::stream<ofstream> m_zout;
public:
  typedef void result_type;

  nestpar_middle_map_show_wf(stapl::stream<ofstream> const& zout)
    : m_zout(zout)
  { }

  template <typename View1>
  void operator()(View1 const& vw1)
  {
    stapl::serial_io(outer_map_show_inn_set_wf(m_zout), vw1);
  }

  void define_type(stapl::typer& t)
  {
    t.member(m_zout);
  }
};

// -------------
// -- Process --
// -------------
template <typename InnerProcWF>
struct nestpar_outer_process_wf
{
  typedef void result_type;

  InnerProcWF m_proc;
  nestpar_outer_process_wf(InnerProcWF proc)
    : m_proc(proc)
  { }

  template <typename View1>
  void operator()(View1 const& vw1)
  {
    stapl::map_func(m_proc, vw1);
  }

  void define_type(stapl::typer& t)
  {
    t.member(m_proc);
  }

};

struct nestpar_outerMap_process_wf
{
  typedef void result_type;

  template <typename View1>
  void operator()(View1 const& vw1)
  {
    stapl::map_func(nestpar_map_reduce_process_wf(), vw1.second);
  }
};

struct nestpar_middle_map_reduce_process_wf
{
  typedef int result_type;

  template <typename View1>
  int operator()(View1 const &vw1)
  {
    return stapl::map_reduce(nestpar_map_reduce_process_wf(),
                             add_int_wf(),
                             vw1);
  }
};

struct nestpar_3lvl_cksum_wf
{
  typedef size_t result_type;

  template<typename Ref1>
  size_t operator()(Ref1 v1)
  {
    return stapl::map_reduce(nestpar_outer_cksum_wf(), xor_un_wf(), v1);
  }
};

template<typename NestedContainer,
         typename NestedContainerView,
         typename FillWF = nestpar_inner_set_fill_wf>
class three_lvl_test_wrapper
{
public:

  template <typename Filename,typename ProcessWF>
  size_t run_test(size_t model,
                  Filename output_filename,
                  ProcessWF & proc_wf,
                  stapl::stream<ofstream>& zout)
  {

    size_t size = 100 * model;
    size_t limit = 100 * model;
    set_random_seed();
    zout.open(output_filename);

    stapl::counter<stapl::default_timer> ctr;
    ctr.start();
    //Array which specifies the size of the 2nd-lvl container:
    ary_sz_tp len_1(model * 10);
    ary_sz_vw_tp len_1_vw(len_1);

    stapl::map_func(roll_wf(), len_1_vw, stapl::make_repeat_view(limit));

    NestedContainer a(len_1_vw);
    NestedContainerView a_vw(a);

    stapl::map_func(nestpar_outer_fill_wf<FillWF>(model*2), a_vw );

    stapl::map_func(nestpar_outer_process_wf<ProcessWF>(proc_wf), a_vw );

    stapl::serial_io(nestpar_outer_show_wf(zout), a_vw);

    ctr.stop();
    double time1 = ctr.value();

    zout.close();
    #ifdef TRIPLE_MAP_REDUCE
    size_t cksum = stapl::map_reduce(nestpar_3lvl_cksum_wf(),
                                     xor_un_wf(),
                                     a_vw);
    return cksum;
    #else
    return 0;
    #endif
  }

};

template<typename NestedContainer,
         typename NestedContainerView,
         typename FillWF = nestpar_inner_set_fill_wf>
class three_lvl_test_wrapper_mapreduce
{
public:

  template <typename Filename,typename ProcessWF>
  size_t run_test(size_t model,
                  Filename output_filename,
                  ProcessWF & proc_wf,
                  stapl::stream<ofstream>& zout)
  {

    size_t size = 100 * model;
    size_t limit = 100 * model;
    set_random_seed();
    zout.open(output_filename);

    stapl::counter<stapl::default_timer> ctr;
    ctr.start();
    //Array which specifies the size of the 2nd-lvl container:
    ary_sz_tp len_1(model * 10);
    ary_sz_vw_tp len_1_vw(len_1);

    stapl::map_func(roll_wf(), len_1_vw, stapl::make_repeat_view(limit));

    NestedContainer a(len_1_vw);
    NestedContainerView a_vw(a);

    stapl::map_func(nestpar_outer_fill_wf<FillWF>(model*2), a_vw );

    add_int_wf::result_type res = stapl::map_reduce(
      proc_wf,
      add_int_wf(),
      a_vw);

    stringstream ss;
    ss << "map_reduce result (accumulate all elements from all sets):"
      << res << endl;
    zout << ss.str();

    stapl::serial_io(nestpar_outer_show_wf(zout), a_vw);

    ctr.stop();
    double time1 = ctr.value();

    zout.close();
    #ifdef TRIPLE_MAP_REDUCE
    size_t cksum = stapl::map_reduce(nestpar_3lvl_cksum_wf(),
                                     xor_un_wf(),
                                     a_vw);
    return cksum;
    #else
    return 0;
    #endif
  }

};

//////////////////////////////////////////////////////////////////////
// nested parallelism : vec(unordered_multiset(int))
// construct vector with generator, traverse with serial
//////////////////////////////////////////////////////////////////////
#ifdef TEST_SET_2LVL_01

size_t nestpar_unordered_multiset_01(size_t model,stapl::stream<ofstream>& zout)
{
  two_lvl_test_wrapper <vec_set_int_tp, vec_set_int_vw_tp> test_case;
  nestpar_size_process_wf proc;

  return test_case.run_test(model, "np_unordered_multiset_01.zout", proc, zout);
}

#endif
//////////////////////////////////////////////////////////////////////
// nested parallelism : vec(unordered_multiset(int))
// construct vector with generator, traverse with mapreduce
//////////////////////////////////////////////////////////////////////
#ifdef TEST_SET_2LVL_02

size_t nestpar_unordered_multiset_02(size_t model,stapl::stream<ofstream>& zout)
{
  two_lvl_test_wrapper <vec_set_int_tp, vec_set_int_vw_tp> test_case;
  nestpar_map_reduce_process_wf proc;
  return test_case.run_test(model, "np_unordered_multiset_02.zout", proc, zout);
}

#endif
//////////////////////////////////////////////////////////////////////
// nested parallelism : ary(unordered_multiset(int))
// construct array with generator, traverse with mapreduce
//////////////////////////////////////////////////////////////////////
#ifdef TEST_SET_2LVL_03
size_t nestpar_unordered_multiset_03(size_t model,stapl::stream<ofstream>& zout)
{
  two_lvl_test_wrapper <ary_set_int_tp, ary_set_int_vw_tp> test_case;
  nestpar_map_reduce_process_wf proc;
  return test_case.run_test(model, "np_unordered_multiset_03.zout", proc, zout);
}
#endif
//////////////////////////////////////////////////////////////////////
// nested parallelism : map(unordered_multiset(int))
// construct map data from C arrays, traverse with mapreduce
//////////////////////////////////////////////////////////////////////
#ifdef TEST_SET_2LVL_04
struct nestpar_set_04_process_wf
{
  typedef int result_type;

  template <typename Element>
  int operator()(Element elem)
  {
    return stapl::map_reduce( id_int_wf(), add_int_wf(), elem.second);
  }
};

size_t nestpar_unordered_multiset_04(size_t model,stapl::stream<ofstream>& zout)
{

  size_t size = 100 * model;
  size_t limit = 100 * model;
  set_random_seed();
  zout.open("np_unordered_multiset_04.zout");

  stapl::counter<stapl::default_timer> ctr;
  ctr.start();

  ary_sz_tp len(size);
  ary_sz_vw_tp len_vw(len);

  stapl::map_func(roll_wf(), len_vw, stapl::make_repeat_view(limit));

  ndx_dom_tp map_dom(0, 100000);
  map_set_int_tp a(map_dom);
  map_set_int_vw_tp a_vw(a);

  if ( stapl::get_location_id() == 0 ) {
    if ( size <= 100000 ) {
      for ( size_t i = 0; i < size; i++ ) {
        for ( size_t j = 0; j < limit; j++ ) {
          a[ prime_nums[i] ].insert(rand_nums[j]);
        }
      }
    } else {
      for ( size_t i = 0; i < size; i += 10000 ) {
        for ( size_t k = 0; k < 10000; k++ ) {
          for ( size_t jj = 0; jj < limit; jj += 10000 )
            for ( size_t j = 0; j < 10000; j++ ) {
              a[ prime_nums[k] * prime_nums[10000-k] ].insert(
                rand_nums[j] * rand_nums[10000-j]);
          }
        }
      }
    }
  }
  stapl::rmi_fence();

  stapl::map_func(nestpar_set_04_process_wf(), a_vw );

  stapl::serial_io(outer_map_show_inn_set_wf(zout), a_vw );

  ctr.stop();
  double time1 = ctr.value();

  zout.close();

  return stapl::map_reduce(map_set_cksum_wf(), xor_un_wf(), a_vw);
}
#endif
//////////////////////////////////////////////////////////////////////
// nested parallelism : vec(unordered_multiset(int))
// construct vector with generator, process with stapl algorithm
// apply unary function in data parallel manner
//////////////////////////////////////////////////////////////////////
#ifdef TEST_SET_2LVL_05
struct nestpar_set_05_process_wf
{
  typedef int result_type;

  template <typename View1>
  int operator()(View1 const &vw1)
  {
    return stapl::accumulate(vw1, -2000000);
  }
};

size_t nestpar_unordered_multiset_05(size_t model,stapl::stream<ofstream>& zout)
{
  two_lvl_test_wrapper_mapreduce <vec_set_int_tp, vec_set_int_vw_tp> test_case;
  nestpar_set_05_process_wf proc;

  return test_case.run_test(model, "np_unordered_multiset_05.zout", proc, zout);
}
#endif

#ifdef TEST_SET_2LVL_06

//////////////////////////////////////////////////////////////////////
// nested parallelism : vec(ary(int))
// construct vector with serial I/O,
// process with map_reduce / work function, display with counting view
//////////////////////////////////////////////////////////////////////

size_t nestpar_unordered_multiset_06(size_t model, stapl::stream<ifstream>& zin,
                       stapl::stream<ofstream>& zout)
{
  open_zin(model,2,zin);
  two_lvl_test_wrapper <vec_set_int_tp,
                        vec_set_int_vw_tp,
                        nestpar_inner_set_fill_fromfile_wf> test_case;
  nestpar_map_reduce_process_wf proc;
  return test_case.run_test(
    model, "np_unordered_multiset_06.zout", proc, zin, zout);
}
#endif

//////////////////////////////////////////////////////////////////////
// nested parallelism : vec(vec(unordered_multiset(int))
// construct array with serial I/O,
// process with mapreduce / work function, display with serial
//////////////////////////////////////////////////////////////////////

#ifdef TEST_SET_3LVL_01
size_t nestpar_unordered_multiset_10(size_t model,stapl::stream<ofstream>& zout)
{
  three_lvl_test_wrapper <vec_vec_set_int_tp, vec_vec_set_int_vw_tp> test_case;
  nestpar_size_process_wf proc;
  return test_case.run_test(model, "np_unordered_multiset_10.zout", proc, zout);
}
#endif

//////////////////////////////////////////////////////////////////////
// nested parallelism : vec(vec(unordered_multiset(int))
// construct vector with serial I/O,
// process with stapl algorithm, display with serial
//////////////////////////////////////////////////////////////////////
#ifdef TEST_SET_3LVL_02

struct nestpar_set_11_process_wf
{
  typedef long int result_type;

  template <typename View1>
  long int operator()(View1 const &vw1)
  {
    return stapl::accumulate(vw1, -2000000);
  }
};

struct nestpar_set_11_middle_process_wf
{
  typedef long int result_type;

  template <typename View1>
  long int operator()(View1 const &vw1)
  {
    return stapl::map_reduce(nestpar_set_11_process_wf(),
                             add_int_wf(),
                             vw1);
  }
};

size_t nestpar_unordered_multiset_11(size_t model,stapl::stream<ofstream>& zout)
{
  three_lvl_test_wrapper_mapreduce <vec_vec_set_int_tp,
                                    vec_vec_set_int_vw_tp> test_case;
  nestpar_set_11_middle_process_wf proc;
  return test_case.run_test(model, "np_unordered_multiset_11.zout", proc, zout);
}

#endif

//////////////////////////////////////////////////////////////////////
// nested parallelism of various containers
// construct vector with serial I/O,
// process with map_reduce, display with serial
//////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////
// vec<ary<unordered_multiset <int> > >
//////////////////////////////////////////////////////////////////////
#ifdef TEST_SET_3LVL_03
size_t nestpar_unordered_multiset_12(size_t model,stapl::stream<ofstream>& zout)
{
  three_lvl_test_wrapper <vec_ary_set_int_tp, vec_ary_set_int_vw_tp> test_case;
  nestpar_map_reduce_process_wf proc;
  return test_case.run_test(model, "np_unordered_multiset_12.zout", proc, zout);
}
#endif

//////////////////////////////////////////////////////////////////////
// ary<vec<unordered_multiset <int> > >
//////////////////////////////////////////////////////////////////////
#ifdef TEST_SET_3LVL_04
size_t nestpar_unordered_multiset_13(size_t model,stapl::stream<ofstream>& zout)
{
  three_lvl_test_wrapper <ary_vec_set_int_tp, ary_vec_set_int_vw_tp> test_case;
  nestpar_map_reduce_process_wf proc;
  return test_case.run_test(model, "np_unordered_multiset_13.zout", proc, zout);
}
#endif

//////////////////////////////////////////////////////////////////////
// vec<map<unordered_multiset <int> > >
//////////////////////////////////////////////////////////////////////
#ifdef TEST_SET_3LVL_05

struct nestpar_set_14_process_wf
{
  typedef int result_type;

  template <typename Element>
  int operator()(Element elem)
  {
    return stapl::map_reduce( id_int_wf(), add_int_wf(), elem.second);
  }
};

size_t nestpar_unordered_multiset_14(size_t model,stapl::stream<ofstream>& zout)
{

  size_t size = 100 * model;
  size_t limit = 100 * model;
  set_random_seed();
  zout.open("np_unordered_multiset_14.zout");

  stapl::counter<stapl::default_timer> ctr;
  ctr.start();

  vec_map_set_int_tp a(model * 10);
  vec_map_set_int_vw_tp a_vw(a);

  stapl::map_func(nestpar_middlemap_set_fill_wf(model*2), a_vw );

  nestpar_set_14_process_wf proc_wf;
  stapl::map_func(nestpar_outer_process_wf<nestpar_set_14_process_wf>(proc_wf),
                  a_vw );

  stapl::serial_io(nestpar_middle_map_show_wf(zout), a_vw);

  ctr.stop();
  double time1 = ctr.value();

  zout.close();

  return  stapl::map_reduce(map_middle_3lvl_cksum_wf(), xor_un_wf(), a_vw);

}
#endif

//////////////////////////////////////////////////////////////////////
// map<ary<unordered_multiset <int> > >
//////////////////////////////////////////////////////////////////////
#ifdef TEST_SET_3LVL_06

size_t nestpar_unordered_multiset_15(size_t model,stapl::stream<ofstream>& zout)
{

  size_t size = 100 * model;
  size_t limit = 100 * model;
  set_random_seed();
  zout.open("np_unordered_multiset_15.zout");

  stapl::counter<stapl::default_timer> ctr;
  ctr.start();

  ndx_dom_tp map_dom(0, 16277216);
  map_ary_set_int_tp a(map_dom);
  map_ary_set_int_vw_tp a_vw(a);

  ary_sz_tp len(size);
  ary_sz_vw_tp len_vw(len);

  stapl::map_func(roll_wf(), len_vw, stapl::make_repeat_view(limit));

  if ( stapl::get_location_id() == 0 ) {
    if ( size <= 100000 ) {
      for ( size_t i = 0; i < size; i++ ) {
        a[ prime_nums[i]].resize(len_vw[i]);
      }
      for ( size_t i = 0; i < size; i++ ) {
        for ( size_t j = 0; j < len_vw[i]; j++ ) {
          int val = rand_nums[j];
          a[ prime_nums[i] ][ val ].insert(rand_nums[j]);
        }
      }
    } else {
      for ( size_t i = 0; i < size; i += 10000 ) {
        a[ prime_nums[i] ].resize(len_vw[i]);
      }
      for ( size_t i = 0; i < size; i += 10000 ) {
        for ( size_t j = 0; j < len_vw[i]; j++ ) {
          for ( size_t k = 0; k < 10000; k++ ) {
            int val = rand_nums[j];
            a[ prime_nums[k] * prime_nums[10000-k] ][ val ].insert(
              rand_nums[j]);
          }
        }
      }
    }
  }
  stapl::rmi_fence();

  stapl::map_func(nestpar_outerMap_process_wf(), a_vw );
  stapl::serial_io(outer_map_3lvl_show_inn_set_wf(zout), a_vw);

  ctr.stop();
  double time1 = ctr.value();

  zout.close();

  return stapl::map_reduce(map_outer_3lvl_cksum_wf(), xor_un_wf(), a_vw);
}

#endif


text:
/*
 * export.cpp
 *
 *  Created on: 2013-4-29
 *      Author: fasiondog
 */

#include "../../config.h"

#if HKU_SUPPORT_SERIALIZATION

#if HKU_SUPPORT_XML_ARCHIVE
#include <boost/archive/xml_oarchive.hpp>
#include <boost/archive/xml_iarchive.hpp>
#endif /* HKU_SUPPORT_XML_ARCHIVE */

#if HKU_SUPPORT_TEXT_ARCHIVE
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#endif /* HKU_SUPPORT_TEXT_ARCHIVE */

#if HKU_SUPPORT_BINARY_ARCHIVE
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#endif /* HKU_SUPPORT_BINARY_ARCHIVE */

#include <boost/serialization/export.hpp>

#include "imp/EqualWeightAllocateFunds.h"

BOOST_CLASS_EXPORT(hku::EqualWeightAllocateFunds)

#endif /* HKU_SUPPORT_SERIALIZATION */

max_stars_repo_name: CodingNowNow/jiaoyi

max_forks_repo_name: archya/hikyuu