<commit_before>//===----------------------------------------------------------------------===//
// LLVM 'DIS' UTILITY
//
// This utility may be invoked in the following manner:
//  llvm-dis [options]      - Read LLVM bytecode from stdin, write asm to stdout
//  llvm-dis [options] x.bc - Read LLVM bytecode from the x.bc file, write asm
//                            to the x.ll file.
//  Options:
//      --help   - Output information about command line switches
//       -c      - Print C code instead of LLVM assembly
//
//===----------------------------------------------------------------------===//

#include "llvm/Module.h"
#include "llvm/PassManager.h"
#include "llvm/Bytecode/Reader.h"
#include "llvm/Assembly/CWriter.h"
#include "llvm/Assembly/PrintModulePass.h"
#include "Support/CommandLine.h"
#include "Support/Signals.h"
#include <fstream>
#include <memory>

// OutputMode - The different orderings to print basic blocks in...
enum OutputMode {
  llvm = 0,           // Generate LLVM assembly (the default)
  c,                  // Generate C code
};

static cl::opt<std::string>
InputFilename(cl::Positional, cl::desc("<input bytecode>"), cl::init("-"));

static cl::opt<std::string>
OutputFilename("o", cl::desc("Override output filename"),
               cl::value_desc("filename"));

static cl::opt<bool>
Force("f", cl::desc("Overwrite output files"));

static cl::opt<enum OutputMode>
WriteMode(cl::desc("Specify the output format:"),
          cl::values(clEnumVal(llvm, "Output LLVM assembly"),
                     clEnumVal(c   , "Output C code for program"),
                    0));

int main(int argc, char **argv) {
  cl::ParseCommandLineOptions(argc, argv, " llvm .bc -> .ll disassembler\n");
  std::ostream *Out = &std::cout;  // Default to printing to stdout...
  std::string ErrorMessage;

  std::auto_ptr<Module> M(ParseBytecodeFile(InputFilename, &ErrorMessage));
  if (M.get() == 0) {
    std::cerr << argv[0] << ": ";
    if (ErrorMessage.size())
      std::cerr << ErrorMessage << "\n";
    else
      std::cerr << "bytecode didn't read correctly.\n";
    return 1;
  }

  if (OutputFilename != "") {   // Specified an output filename?
    if (OutputFilename != "-") { // Not stdout?
      if (!Force && std::ifstream(OutputFilename.c_str())) {
        // If force is not specified, make sure not to overwrite a file!
        std::cerr << argv[0] << ": error opening '" << OutputFilename
                  << "': file exists! Sending to standard output.\n";
      } else {
        Out = new std::ofstream(OutputFilename.c_str());
      }
    }
  } else {
    if (InputFilename == "-") {
      OutputFilename = "-";
    } else {
      std::string IFN = InputFilename;
      int Len = IFN.length();
      if (IFN[Len-3] == '.' && IFN[Len-2] == 'b' && IFN[Len-1] == 'c') {
	// Source ends in .bc
	OutputFilename = std::string(IFN.begin(), IFN.end()-3);
      } else {
	OutputFilename = IFN;   // Append a .ll to it
      }
      if (WriteMode == c)
        OutputFilename += ".c";
      else
        OutputFilename += ".ll";

      if (!Force && std::ifstream(OutputFilename.c_str())) {
        // If force is not specified, make sure not to overwrite a file!
        std::cerr << argv[0] << ": error opening '" << OutputFilename
                  << "': file exists! Sending to standard output.\n";
      } else {
        Out = new std::ofstream(OutputFilename.c_str());

        // Make sure that the Out file gets unlink'd from the disk if we get a
        // SIGINT
        RemoveFileOnSignal(OutputFilename);
      }
    }
  }

  if (!Out->good()) {
    std::cerr << argv[0] << ": error opening " << OutputFilename
              << ": sending to stdout instead!\n";
    Out = &std::cout;
  }

  // All that dis does is write the assembly or C out to a file...
  //
  PassManager Passes;

  switch (WriteMode) {
  case llvm:           // Output LLVM assembly
    Passes.add(new PrintModulePass(Out));
    break;
  case c:              // Convert LLVM to C
    Passes.add(createWriteToCPass(*Out));
    break;
  }

  Passes.run(*M.get());

  if (Out != &std::cout) {
    ((std::ofstream*)Out)->close();
    delete Out;
  }
  return 0;
}

<commit_msg>Renamed dis.cpp => llvm-dis.cpp<commit_after><|endoftext|>


<commit_before>#ifndef HAVE_LLVM
#error "This code needs LLVM enabled"
#endif

#include <set>
#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <cassert>
#include <cstdio>

// ignore unused parameters in LLVM libraries
#if (__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-parameter"
#else
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#endif

#include <llvm/IR/LLVMContext.h>
#include <llvm/IR/Module.h>
#include <llvm/IR/Instructions.h>
#include <llvm/Support/SourceMgr.h>
#include <llvm/Support/raw_os_ostream.h>
#include <llvm/IRReader/IRReader.h>

#if LLVM_VERSION_MAJOR >= 4
#include <llvm/Bitcode/BitcodeReader.h>
#include <llvm/Bitcode/BitcodeWriter.h>
#else
#include <llvm/Bitcode/ReaderWriter.h>
#endif

#if (__clang__)
#pragma clang diagnostic pop // ignore -Wunused-parameter
#else
#pragma GCC diagnostic pop
#endif

#include "dg/analysis/PointsTo/PointerAnalysisFI.h"
#include "dg/analysis/PointsTo/PointerAnalysisFS.h"
#include "dg/analysis/PointsTo/Pointer.h"

#include "dg/llvm/analysis/PointsTo/PointerAnalysis.h"
#include "dg/llvm/analysis/ReachingDefinitions/ReachingDefinitions.h"

#include "TimeMeasure.h"

using namespace dg;
using namespace dg::analysis;
using namespace dg::analysis::rd;
using llvm::errs;

static bool verbose = false;
static const char *entryFunc = "main";

static std::string
getInstName(const llvm::Value *val)
{
    std::ostringstream ostr;
    llvm::raw_os_ostream ro(ostr);

    assert(val);
    ro << *val;
    ro.flush();

    // break the string if it is too long
    return ostr.str();
}

static void printRDNodeType(enum RDNodeType type)
{
#define ELEM(t) case(t): do {printf("%s", #t); }while(0); break;
    switch(type) {
        ELEM(RDNodeType::ALLOC)
        ELEM(RDNodeType::DYN_ALLOC)
        ELEM(RDNodeType::STORE)
        ELEM(RDNodeType::PHI)
        ELEM(RDNodeType::CALL)
        ELEM(RDNodeType::CALL_RETURN)
        ELEM(RDNodeType::FORK)
        ELEM(RDNodeType::JOIN)
        ELEM(RDNodeType::RETURN)
        ELEM(RDNodeType::NOOP)
        ELEM(RDNodeType::NONE)
        default:
            printf("unknown reaching definitions subgraph type");
    };
#undef ELEM
}

static inline void printAddress(RDNode *node, bool dot)
{
    if (dot)
        printf(" [%p]\\n", static_cast<void*>(node));
    else
        printf(" [%p]\n", static_cast<void*>(node));
}

static void
printName(RDNode *node, bool dot)
{
    if (node == rd::UNKNOWN_MEMORY) {
        printf("UNKNOWN MEMORY");
        return;
    }

    const char *name = nullptr;
#if 0
#ifdef DEBUG_ENABLED
    name = node->getName();
#endif
#endif
    std::string nm;
    if (!name) {
        if (!node->getUserData<llvm::Value>()) {
            printRDNodeType(node->getType());
            printAddress(node, dot);
            return;
        }

        nm = getInstName(node->getUserData<llvm::Value>());
        name = nm.c_str();
    }

    // escape the " character
    for (int i = 0; name[i] != '\0'; ++i) {
        // crop long names
        if (i >= 70) {
            printf(" ...");
            break;
        }

        if (name[i] == '"')
            putchar('\\');

        putchar(name[i]);
    }
}

/*
static void
dumpMap(RDNode *node, bool dot = false)
{
    RDMap& map = node->getReachingDefinitions();
    for (const auto& it : map) {
        for (RDNode *site : it.second) {
            printName(it.first.target, dot);
            // don't print offsets with unknown memory
            if (it.first.target == rd::UNKNOWN_MEMORY) {
                printf(" => ");
            } else {
                if (it.first.offset.isUnknown())
                    printf(" | UNKNOWN | => ");
                else if (it.first.len.isUnknown())
                    printf(" | %lu - UNKNOWN | => ", *it.first.offset);
                else
                    printf(" | %lu - %lu | => ", *it.first.offset,
                           *it.first.offset + *it.first.len - 1);
            }

            printName(site, dot);
            if (dot)
                printf("\\n");
            else
                putchar('\n');
        }
    }
}
*/
static void
dumpDDIMap(RDBBlock *block, bool dot = false)
{
    auto& map = block->definitions;
    for (const auto& it : map) {
       printName(it.first, dot);
       for (auto& it2 : it.second) {
           printf("  [%lu - %lu] => \n",
                  *it2.first.start, *it2.first.end);
           for (auto where : it2.second) {
               printf("    ");
               printName(where, dot);
           }
       }

       if (dot)
           printf("\\n");
       else
           putchar('\n');
    }
}

static void
dumpDefSites(const std::set<DefSite>& defs, const char *kind, bool dot = false)
{
    printf("-------------\\n");
    for (const DefSite& def : defs) {
        printf("%s: ", kind);
        printName(def.target, dot);
            if (def.offset.isUnknown())
                printf(" [ UNKNOWN ]");
            else
                printf(" [ %lu - %lu ]", *def.offset,
                       *def.offset + *def.len - 1);

            if (dot)
                printf("\\n");
            else
                putchar('\n');
    }
}

static void
dumpDefines(RDNode *node, bool dot = false)
{
    if (!node->getDefines().empty())
        dumpDefSites(node->getDefines(), "DEF", dot);
}

static void
dumpOverwrites(RDNode *node, bool dot = false)
{
    if (!node->getOverwrites().empty())
        dumpDefSites(node->getOverwrites(), "DEF strong", dot);
}

static void
dumpUses(RDNode *node, bool dot = false)
{
    if (!node->getUses().empty())
        dumpDefSites(node->getUses(), "USE", dot);
}

static void
dumpRDNode(RDNode *n)
{
    printf("NODE: ");
    printName(n, false);
    if (n->getSize() > 0)
        printf(" [size: %lu]", n->getSize());
    putchar('\n');
    //dumpMap(n);
    printf("---\n");
}

static void nodeToDot(RDNode *node) {
    printf("\tNODE%p [label=\"%lu ", static_cast<void*>(node), node->getID());
    printName(node, true);
    if (node->getSize() > 0) {
        printf("\\n[size: %lu]\\n", node->getSize());
        printf("\\n-------------\\n");
    }

    if (verbose) {
        printf("\\nblock: %p\\n", node->getBBlock());
        printf("\\n-------------\\n");

        dumpDefines(node, true);
        dumpOverwrites(node, true);
        dumpUses(node, true);
        printf("\\n-------------\\n");
    }

    //dumpMap(node, true /* dot */);

    printf("\" shape=box]\n");

}

static void dumpDotOnlyNodes(LLVMReachingDefinitions *RD, bool dump_rd)
{
    auto nodes = RD->getNodes();
    /* dump nodes */
    for(RDNode *node : nodes) {
        nodeToDot(node);
    }
}

static void dumpDotWithBlocks(LLVMReachingDefinitions *RD, bool dump_rd) {

    for (auto I = RD->getGraph()->blocks_begin(),
              E = RD->getGraph()->blocks_end(); I != E; ++I) {
        printf("subgraph cluster_%p {\n", *I);
        /* dump nodes */
        for(RDNode *node : I->getNodes()) {
            nodeToDot(node);
        }

        // dump def-use edges
        for(RDNode *node : I->getNodes()) {
            for (RDNode *def : node->defuse) {
                printf("\tNODE%p->NODE%p [style=dotted]",
                       static_cast<void*>(def), static_cast<void*>(node));
            }
        }
        printf("label=\"\\nblock: %p\\n", *I);
        dumpDDIMap(*I, true);
        printf("\"\nlabelloc=b\n");
        printf("}\n");
    }

    /* dump block edges
    for (auto I = RD->getGraph()->blocks_begin(),
              E = RD->getGraph()->blocks_end(); I != E; ++I) {
        for (auto succ : I->getSuccessors())
            printf("\tNODE%p -> NODE%p [penwidth=2]\n",
                   static_cast<void*>(*I),
                   static_cast<void*>(succ));
    }
    */
}

static void
dumpRDdot(LLVMReachingDefinitions *RD, bool dump_rd)
{

    printf("digraph \"Reaching Definitions Subgraph\" {\n");

    if (RD->getGraph()->getBBlocks().empty())
        dumpDotOnlyNodes(RD, dump_rd);
    else
        dumpDotWithBlocks(RD, dump_rd);

    /* dump edges */
    std::unordered_map<RDNode*, unsigned> colors;
    for (RDNode *node : RD->getNodes()) {
        for (RDNode *succ : node->getSuccessors())
            printf("\tNODE%p -> NODE%p [penwidth=2]\n",
                   static_cast<void*>(node),
                   static_cast<void*>(succ));
    }

    printf("}\n");
}

static void
dumpRD(LLVMReachingDefinitions *RD, bool todot, bool dump_rd)
{
    assert(RD);

    if (todot)
        dumpRDdot(RD, dump_rd);
    else {
        for (RDNode *node : RD->getNodes())
            dumpRDNode(node);
    }
}

int main(int argc, char *argv[])
{
    llvm::Module *M;
    llvm::LLVMContext context;
    llvm::SMDiagnostic SMD;
    bool todot = false;
    bool threads = false;
    bool dump_rd = false;
    const char *module = nullptr;
    Offset::type field_senitivity = Offset::UNKNOWN;
    bool rd_strong_update_unknown = false;
    Offset::type max_set_size = Offset::UNKNOWN;

    enum {
        FLOW_SENSITIVE = 1,
        FLOW_INSENSITIVE,
    } type = FLOW_INSENSITIVE;

    enum class RdaType {
        DENSE,
        SEMISPARSE
    } rda = RdaType::DENSE;

    // parse options
    for (int i = 1; i < argc; ++i) {
        // run given points-to analysis
        if (strcmp(argv[i], "-pta") == 0) {
            if (strcmp(argv[i+1], "fs") == 0)
                type = FLOW_SENSITIVE;
        } else if (strcmp(argv[i], "-rda") == 0) {
            if (strcmp(argv[i+1], "ss") == 0)
                rda = RdaType::SEMISPARSE;
        } else if (strcmp(argv[i], "-pta-field-sensitive") == 0) {
            field_senitivity = static_cast<Offset::type>(atoll(argv[i + 1]));
        } else if (strcmp(argv[i], "-rd-max-set-size") == 0) {
            max_set_size = static_cast<Offset::type>(atoll(argv[i + 1]));
            if (max_set_size == 0) {
                llvm::errs() << "Invalid -rd-max-set-size argument\n";
                abort();
            }
        } else if (strcmp(argv[i], "-rd-strong-update-unknown") == 0) {
            rd_strong_update_unknown = true;
        } else if (strcmp(argv[i], "-dot") == 0) {
            todot = true;
        } else if (strcmp(argv[i], "-threads") == 0) {
            threads = true;
        } else if (strcmp(argv[i], "-v") == 0) {
            verbose = true;
        } else if (strcmp(argv[i], "-dump-rd") == 0) {
            dump_rd = true;
        } else if (strcmp(argv[i], "-entry") == 0) {
            entryFunc = argv[i+1];
        } else {
            module = argv[i];
        }
    }

    if (!module) {
        errs() << "Usage: % IR_module [-pts fs|fi] [-dot] [-v] [output_file]\n";
        return 1;
    }

#if ((LLVM_VERSION_MAJOR == 3) && (LLVM_VERSION_MINOR <= 5))
    M = llvm::ParseIRFile(module, SMD, context);
#else
    auto _M = llvm::parseIRFile(module, SMD, context);
    // _M is unique pointer, we need to get Module *
    M = _M.get();
#endif

    if (!M) {
        llvm::errs() << "Failed parsing '" << module << "' file:\n";
        SMD.print(argv[0], errs());
        return 1;
    }

    debug::TimeMeasure tm;

    LLVMPointerAnalysis PTA(M, entryFunc, field_senitivity, threads);

    tm.start();

    if (type == FLOW_INSENSITIVE) {
        PTA.run<pta::PointerAnalysisFI>();
    } else {
        PTA.run<pta::PointerAnalysisFS>();
    }

    tm.stop();
    tm.report("INFO: Points-to analysis took");

    LLVMReachingDefinitionsAnalysisOptions opts;
    opts.threads = threads;
    opts.entryFunction = entryFunc;
    opts.strongUpdateUnknown = rd_strong_update_unknown;
    opts.maxSetSize = max_set_size;

    LLVMReachingDefinitions RD(M, &PTA, opts);
    tm.start();
    if (rda == RdaType::SEMISPARSE) {
        RD.run<dg::analysis::rd::SSAReachingDefinitionsAnalysis>();
    } else
        RD.run<dg::analysis::rd::ReachingDefinitionsAnalysis>();
    tm.stop();
    tm.report("INFO: Reaching definitions analysis took");

    dumpRD(&RD, todot, dump_rd);

    return 0;
}
<commit_msg>llvm-rd-dump: remove unused variable<commit_after>#ifndef HAVE_LLVM
#error "This code needs LLVM enabled"
#endif

#include <set>
#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <cassert>
#include <cstdio>

// ignore unused parameters in LLVM libraries
#if (__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-parameter"
#else
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#endif

#include <llvm/IR/LLVMContext.h>
#include <llvm/IR/Module.h>
#include <llvm/IR/Instructions.h>
#include <llvm/Support/SourceMgr.h>
#include <llvm/Support/raw_os_ostream.h>
#include <llvm/IRReader/IRReader.h>

#if LLVM_VERSION_MAJOR >= 4
#include <llvm/Bitcode/BitcodeReader.h>
#include <llvm/Bitcode/BitcodeWriter.h>
#else
#include <llvm/Bitcode/ReaderWriter.h>
#endif

#if (__clang__)
#pragma clang diagnostic pop // ignore -Wunused-parameter
#else
#pragma GCC diagnostic pop
#endif

#include "dg/analysis/PointsTo/PointerAnalysisFI.h"
#include "dg/analysis/PointsTo/PointerAnalysisFS.h"
#include "dg/analysis/PointsTo/Pointer.h"

#include "dg/llvm/analysis/PointsTo/PointerAnalysis.h"
#include "dg/llvm/analysis/ReachingDefinitions/ReachingDefinitions.h"

#include "TimeMeasure.h"

using namespace dg;
using namespace dg::analysis;
using namespace dg::analysis::rd;
using llvm::errs;

static bool verbose = false;
static const char *entryFunc = "main";

static std::string
getInstName(const llvm::Value *val)
{
    std::ostringstream ostr;
    llvm::raw_os_ostream ro(ostr);

    assert(val);
    ro << *val;
    ro.flush();

    // break the string if it is too long
    return ostr.str();
}

static void printRDNodeType(enum RDNodeType type)
{
#define ELEM(t) case(t): do {printf("%s", #t); }while(0); break;
    switch(type) {
        ELEM(RDNodeType::ALLOC)
        ELEM(RDNodeType::DYN_ALLOC)
        ELEM(RDNodeType::STORE)
        ELEM(RDNodeType::PHI)
        ELEM(RDNodeType::CALL)
        ELEM(RDNodeType::CALL_RETURN)
        ELEM(RDNodeType::FORK)
        ELEM(RDNodeType::JOIN)
        ELEM(RDNodeType::RETURN)
        ELEM(RDNodeType::NOOP)
        ELEM(RDNodeType::NONE)
        default:
            printf("unknown reaching definitions subgraph type");
    };
#undef ELEM
}

static inline void printAddress(RDNode *node, bool dot)
{
    if (dot)
        printf(" [%p]\\n", static_cast<void*>(node));
    else
        printf(" [%p]\n", static_cast<void*>(node));
}

static void
printName(RDNode *node, bool dot)
{
    if (node == rd::UNKNOWN_MEMORY) {
        printf("UNKNOWN MEMORY");
        return;
    }

    const char *name = nullptr;
#if 0
#ifdef DEBUG_ENABLED
    name = node->getName();
#endif
#endif
    std::string nm;
    if (!name) {
        if (!node->getUserData<llvm::Value>()) {
            printRDNodeType(node->getType());
            printAddress(node, dot);
            return;
        }

        nm = getInstName(node->getUserData<llvm::Value>());
        name = nm.c_str();
    }

    // escape the " character
    for (int i = 0; name[i] != '\0'; ++i) {
        // crop long names
        if (i >= 70) {
            printf(" ...");
            break;
        }

        if (name[i] == '"')
            putchar('\\');

        putchar(name[i]);
    }
}

/*
static void
dumpMap(RDNode *node, bool dot = false)
{
    RDMap& map = node->getReachingDefinitions();
    for (const auto& it : map) {
        for (RDNode *site : it.second) {
            printName(it.first.target, dot);
            // don't print offsets with unknown memory
            if (it.first.target == rd::UNKNOWN_MEMORY) {
                printf(" => ");
            } else {
                if (it.first.offset.isUnknown())
                    printf(" | UNKNOWN | => ");
                else if (it.first.len.isUnknown())
                    printf(" | %lu - UNKNOWN | => ", *it.first.offset);
                else
                    printf(" | %lu - %lu | => ", *it.first.offset,
                           *it.first.offset + *it.first.len - 1);
            }

            printName(site, dot);
            if (dot)
                printf("\\n");
            else
                putchar('\n');
        }
    }
}
*/
static void
dumpDDIMap(RDBBlock *block, bool dot = false)
{
    auto& map = block->definitions;
    for (const auto& it : map) {
       printName(it.first, dot);
       for (auto& it2 : it.second) {
           printf("  [%lu - %lu] => \n",
                  *it2.first.start, *it2.first.end);
           for (auto where : it2.second) {
               printf("    ");
               printName(where, dot);
           }
       }

       if (dot)
           printf("\\n");
       else
           putchar('\n');
    }
}

static void
dumpDefSites(const std::set<DefSite>& defs, const char *kind, bool dot = false)
{
    printf("-------------\\n");
    for (const DefSite& def : defs) {
        printf("%s: ", kind);
        printName(def.target, dot);
            if (def.offset.isUnknown())
                printf(" [ UNKNOWN ]");
            else
                printf(" [ %lu - %lu ]", *def.offset,
                       *def.offset + *def.len - 1);

            if (dot)
                printf("\\n");
            else
                putchar('\n');
    }
}

static void
dumpDefines(RDNode *node, bool dot = false)
{
    if (!node->getDefines().empty())
        dumpDefSites(node->getDefines(), "DEF", dot);
}

static void
dumpOverwrites(RDNode *node, bool dot = false)
{
    if (!node->getOverwrites().empty())
        dumpDefSites(node->getOverwrites(), "DEF strong", dot);
}

static void
dumpUses(RDNode *node, bool dot = false)
{
    if (!node->getUses().empty())
        dumpDefSites(node->getUses(), "USE", dot);
}

static void
dumpRDNode(RDNode *n)
{
    printf("NODE: ");
    printName(n, false);
    if (n->getSize() > 0)
        printf(" [size: %lu]", n->getSize());
    putchar('\n');
    //dumpMap(n);
    printf("---\n");
}

static void nodeToDot(RDNode *node) {
    printf("\tNODE%p [label=\"%lu ", static_cast<void*>(node), node->getID());
    printName(node, true);
    if (node->getSize() > 0) {
        printf("\\n[size: %lu]\\n", node->getSize());
        printf("\\n-------------\\n");
    }

    if (verbose) {
        printf("\\nblock: %p\\n", node->getBBlock());
        printf("\\n-------------\\n");

        dumpDefines(node, true);
        dumpOverwrites(node, true);
        dumpUses(node, true);
        printf("\\n-------------\\n");
    }

    //dumpMap(node, true /* dot */);

    printf("\" shape=box]\n");

}

static void dumpDotOnlyNodes(LLVMReachingDefinitions *RD, bool dump_rd)
{
    auto nodes = RD->getNodes();
    /* dump nodes */
    for(RDNode *node : nodes) {
        nodeToDot(node);
    }
}

static void dumpDotWithBlocks(LLVMReachingDefinitions *RD, bool dump_rd) {

    for (auto I = RD->getGraph()->blocks_begin(),
              E = RD->getGraph()->blocks_end(); I != E; ++I) {
        printf("subgraph cluster_%p {\n", *I);
        /* dump nodes */
        for(RDNode *node : I->getNodes()) {
            nodeToDot(node);
        }

        // dump def-use edges
        for(RDNode *node : I->getNodes()) {
            for (RDNode *def : node->defuse) {
                printf("\tNODE%p->NODE%p [style=dotted]",
                       static_cast<void*>(def), static_cast<void*>(node));
            }
        }
        printf("label=\"\\nblock: %p\\n", *I);
        dumpDDIMap(*I, true);
        printf("\"\nlabelloc=b\n");
        printf("}\n");
    }

    /* dump block edges
    for (auto I = RD->getGraph()->blocks_begin(),
              E = RD->getGraph()->blocks_end(); I != E; ++I) {
        for (auto succ : I->getSuccessors())
            printf("\tNODE%p -> NODE%p [penwidth=2]\n",
                   static_cast<void*>(*I),
                   static_cast<void*>(succ));
    }
    */
}

static void
dumpRDdot(LLVMReachingDefinitions *RD, bool dump_rd)
{

    printf("digraph \"Reaching Definitions Subgraph\" {\n");

    if (RD->getGraph()->getBBlocks().empty())
        dumpDotOnlyNodes(RD, dump_rd);
    else
        dumpDotWithBlocks(RD, dump_rd);

    /* dump edges */
    for (RDNode *node : RD->getNodes()) {
        for (RDNode *succ : node->getSuccessors())
            printf("\tNODE%p -> NODE%p [penwidth=2]\n",
                   static_cast<void*>(node),
                   static_cast<void*>(succ));
    }

    printf("}\n");
}

static void
dumpRD(LLVMReachingDefinitions *RD, bool todot, bool dump_rd)
{
    assert(RD);

    if (todot)
        dumpRDdot(RD, dump_rd);
    else {
        for (RDNode *node : RD->getNodes())
            dumpRDNode(node);
    }
}

int main(int argc, char *argv[])
{
    llvm::Module *M;
    llvm::LLVMContext context;
    llvm::SMDiagnostic SMD;
    bool todot = false;
    bool threads = false;
    bool dump_rd = false;
    const char *module = nullptr;
    Offset::type field_senitivity = Offset::UNKNOWN;
    bool rd_strong_update_unknown = false;
    Offset::type max_set_size = Offset::UNKNOWN;

    enum {
        FLOW_SENSITIVE = 1,
        FLOW_INSENSITIVE,
    } type = FLOW_INSENSITIVE;

    enum class RdaType {
        DENSE,
        SEMISPARSE
    } rda = RdaType::DENSE;

    // parse options
    for (int i = 1; i < argc; ++i) {
        // run given points-to analysis
        if (strcmp(argv[i], "-pta") == 0) {
            if (strcmp(argv[i+1], "fs") == 0)
                type = FLOW_SENSITIVE;
        } else if (strcmp(argv[i], "-rda") == 0) {
            if (strcmp(argv[i+1], "ss") == 0)
                rda = RdaType::SEMISPARSE;
        } else if (strcmp(argv[i], "-pta-field-sensitive") == 0) {
            field_senitivity = static_cast<Offset::type>(atoll(argv[i + 1]));
        } else if (strcmp(argv[i], "-rd-max-set-size") == 0) {
            max_set_size = static_cast<Offset::type>(atoll(argv[i + 1]));
            if (max_set_size == 0) {
                llvm::errs() << "Invalid -rd-max-set-size argument\n";
                abort();
            }
        } else if (strcmp(argv[i], "-rd-strong-update-unknown") == 0) {
            rd_strong_update_unknown = true;
        } else if (strcmp(argv[i], "-dot") == 0) {
            todot = true;
        } else if (strcmp(argv[i], "-threads") == 0) {
            threads = true;
        } else if (strcmp(argv[i], "-v") == 0) {
            verbose = true;
        } else if (strcmp(argv[i], "-dump-rd") == 0) {
            dump_rd = true;
        } else if (strcmp(argv[i], "-entry") == 0) {
            entryFunc = argv[i+1];
        } else {
            module = argv[i];
        }
    }

    if (!module) {
        errs() << "Usage: % IR_module [-pts fs|fi] [-dot] [-v] [output_file]\n";
        return 1;
    }

#if ((LLVM_VERSION_MAJOR == 3) && (LLVM_VERSION_MINOR <= 5))
    M = llvm::ParseIRFile(module, SMD, context);
#else
    auto _M = llvm::parseIRFile(module, SMD, context);
    // _M is unique pointer, we need to get Module *
    M = _M.get();
#endif

    if (!M) {
        llvm::errs() << "Failed parsing '" << module << "' file:\n";
        SMD.print(argv[0], errs());
        return 1;
    }

    debug::TimeMeasure tm;

    LLVMPointerAnalysis PTA(M, entryFunc, field_senitivity, threads);

    tm.start();

    if (type == FLOW_INSENSITIVE) {
        PTA.run<pta::PointerAnalysisFI>();
    } else {
        PTA.run<pta::PointerAnalysisFS>();
    }

    tm.stop();
    tm.report("INFO: Points-to analysis took");

    LLVMReachingDefinitionsAnalysisOptions opts;
    opts.threads = threads;
    opts.entryFunction = entryFunc;
    opts.strongUpdateUnknown = rd_strong_update_unknown;
    opts.maxSetSize = max_set_size;

    LLVMReachingDefinitions RD(M, &PTA, opts);
    tm.start();
    if (rda == RdaType::SEMISPARSE) {
        RD.run<dg::analysis::rd::SSAReachingDefinitionsAnalysis>();
    } else
        RD.run<dg::analysis::rd::ReachingDefinitionsAnalysis>();
    tm.stop();
    tm.report("INFO: Reaching definitions analysis took");

    dumpRD(&RD, todot, dump_rd);

    return 0;
}
<|endoftext|>


<commit_before>// Copyright 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "sync/engine/build_commit_command.h"

#include <limits>
#include <set>
#include <string>
#include <vector>

#include "base/strings/string_util.h"
#include "sync/engine/syncer_proto_util.h"
#include "sync/internal_api/public/base/unique_position.h"
#include "sync/protocol/bookmark_specifics.pb.h"
#include "sync/protocol/sync.pb.h"
#include "sync/sessions/ordered_commit_set.h"
#include "sync/sessions/sync_session.h"
#include "sync/syncable/directory.h"
#include "sync/syncable/entry.h"
#include "sync/syncable/syncable_base_transaction.h"
#include "sync/syncable/syncable_changes_version.h"
#include "sync/syncable/syncable_proto_util.h"
#include "sync/util/time.h"

using std::set;
using std::string;
using std::vector;

namespace syncer {

using sessions::SyncSession;
using syncable::Entry;
using syncable::IS_DEL;
using syncable::IS_UNAPPLIED_UPDATE;
using syncable::IS_UNSYNCED;
using syncable::Id;
using syncable::SPECIFICS;
using syncable::UNIQUE_POSITION;

BuildCommitCommand::BuildCommitCommand(
    syncable::BaseTransaction* trans,
    const sessions::OrderedCommitSet& batch_commit_set,
    sync_pb::ClientToServerMessage* commit_message,
    ExtensionsActivity::Records* extensions_activity_buffer)
  : trans_(trans),
    batch_commit_set_(batch_commit_set),
    commit_message_(commit_message),
    extensions_activity_buffer_(extensions_activity_buffer) {
}

BuildCommitCommand::~BuildCommitCommand() {}

void BuildCommitCommand::AddExtensionsActivityToMessage(
    SyncSession* session, sync_pb::CommitMessage* message) {
  // We only send ExtensionsActivity to the server if bookmarks are being
  // committed.
  ExtensionsActivity* activity = session->context()->extensions_activity();
  if (batch_commit_set_.HasBookmarkCommitId()) {
    // This isn't perfect, since the set of extensions activity may not
    // correlate exactly with the items being committed.  That's OK as
    // long as we're looking for a rough estimate of extensions activity,
    // not an precise mapping of which commits were triggered by which
    // extension.
    //
    // We will push this list of extensions activity back into the
    // ExtensionsActivityMonitor if this commit fails.  That's why we must keep
    // a copy of these records in the session.
    activity->GetAndClearRecords(extensions_activity_buffer_);

    const ExtensionsActivity::Records& records =
        *extensions_activity_buffer_;
    for (ExtensionsActivity::Records::const_iterator it =
         records.begin();
         it != records.end(); ++it) {
      sync_pb::ChromiumExtensionsActivity* activity_message =
          message->add_extensions_activity();
      activity_message->set_extension_id(it->second.extension_id);
      activity_message->set_bookmark_writes_since_last_commit(
          it->second.bookmark_write_count);
    }
  }
}

void BuildCommitCommand::AddClientConfigParamsToMessage(
    SyncSession* session, sync_pb::CommitMessage* message) {
  const ModelSafeRoutingInfo& routing_info = session->context()->routing_info();
  sync_pb::ClientConfigParams* config_params = message->mutable_config_params();
  for (std::map<ModelType, ModelSafeGroup>::const_iterator iter =
          routing_info.begin(); iter != routing_info.end(); ++iter) {
    if (ProxyTypes().Has(iter->first))
      continue;
    int field_number = GetSpecificsFieldNumberFromModelType(iter->first);
    config_params->mutable_enabled_type_ids()->Add(field_number);
  }
  config_params->set_tabs_datatype_enabled(
      routing_info.count(syncer::PROXY_TABS) > 0);
}

namespace {
void SetEntrySpecifics(Entry* meta_entry,
                       sync_pb::SyncEntity* sync_entry) {
  // Add the new style extension and the folder bit.
  sync_entry->mutable_specifics()->CopyFrom(meta_entry->Get(SPECIFICS));
  sync_entry->set_folder(meta_entry->Get(syncable::IS_DIR));

  CHECK(!sync_entry->specifics().password().has_client_only_encrypted_data());
  DCHECK_EQ(meta_entry->GetModelType(), GetModelType(*sync_entry));
}
}  // namespace

SyncerError BuildCommitCommand::ExecuteImpl(SyncSession* session) {
  commit_message_->set_share(session->context()->account_name());
  commit_message_->set_message_contents(sync_pb::ClientToServerMessage::COMMIT);

  sync_pb::CommitMessage* commit_message = commit_message_->mutable_commit();
  commit_message->set_cache_guid(trans_->directory()->cache_guid());
  AddExtensionsActivityToMessage(session, commit_message);
  AddClientConfigParamsToMessage(session, commit_message);

  // Cache previously computed position values.  Because |commit_ids|
  // is already in sibling order, we should always hit this map after
  // the first sibling in a consecutive run of commit items.  The
  // entries in this map are (low, high) values describing the
  // space of positions that are immediate successors of the item
  // whose ID is the map's key.
  std::map<Id, std::pair<int64, int64> > position_map;

  for (size_t i = 0; i < batch_commit_set_.Size(); i++) {
    Id id = batch_commit_set_.GetCommitIdAt(i);
    sync_pb::SyncEntity* sync_entry = commit_message->add_entries();
    sync_entry->set_id_string(SyncableIdToProto(id));
    Entry meta_entry(trans_, syncable::GET_BY_ID, id);
    CHECK(meta_entry.good());

    DCHECK_NE(0UL,
              session->context()->routing_info().count(
                  meta_entry.GetModelType()))
        << "Committing change to datatype that's not actively enabled.";

    string name = meta_entry.Get(syncable::NON_UNIQUE_NAME);
    CHECK(!name.empty());  // Make sure this isn't an update.
    // Note: Truncation is also performed in WriteNode::SetTitle(..). But this
    // call is still necessary to handle any title changes that might originate
    // elsewhere, or already be persisted in the directory.
    TruncateUTF8ToByteSize(name, 255, &name);
    sync_entry->set_name(name);

    // Set the non_unique_name.  If we do, the server ignores
    // the |name| value (using |non_unique_name| instead), and will return
    // in the CommitResponse a unique name if one is generated.
    // We send both because it may aid in logging.
    sync_entry->set_non_unique_name(name);

    if (!meta_entry.Get(syncable::UNIQUE_CLIENT_TAG).empty()) {
      sync_entry->set_client_defined_unique_tag(
          meta_entry.Get(syncable::UNIQUE_CLIENT_TAG));
    }

    // Deleted items with server-unknown parent ids can be a problem so we set
    // the parent to 0. (TODO(sync): Still true in protocol?).
    Id new_parent_id;
    if (meta_entry.Get(syncable::IS_DEL) &&
        !meta_entry.Get(syncable::PARENT_ID).ServerKnows()) {
      new_parent_id = trans_->root_id();
    } else {
      new_parent_id = meta_entry.Get(syncable::PARENT_ID);
    }
    sync_entry->set_parent_id_string(SyncableIdToProto(new_parent_id));

    // If our parent has changed, send up the old one so the server
    // can correctly deal with multiple parents.
    // TODO(nick): With the server keeping track of the primary sync parent,
    // it should not be necessary to provide the old_parent_id: the version
    // number should suffice.
    if (new_parent_id != meta_entry.Get(syncable::SERVER_PARENT_ID) &&
        0 != meta_entry.Get(syncable::BASE_VERSION) &&
        syncable::CHANGES_VERSION != meta_entry.Get(syncable::BASE_VERSION)) {
      sync_entry->set_old_parent_id(
          SyncableIdToProto(meta_entry.Get(syncable::SERVER_PARENT_ID)));
    }

    int64 version = meta_entry.Get(syncable::BASE_VERSION);
    if (syncable::CHANGES_VERSION == version || 0 == version) {
      // Undeletions are only supported for items that have a client tag.
      DCHECK(!id.ServerKnows() ||
             !meta_entry.Get(syncable::UNIQUE_CLIENT_TAG).empty())
          << meta_entry;

      // Version 0 means to create or undelete an object.
      sync_entry->set_version(0);
    } else {
      DCHECK(id.ServerKnows()) << meta_entry;
      sync_entry->set_version(meta_entry.Get(syncable::BASE_VERSION));
    }
    sync_entry->set_ctime(TimeToProtoTime(meta_entry.Get(syncable::CTIME)));
    sync_entry->set_mtime(TimeToProtoTime(meta_entry.Get(syncable::MTIME)));

    // Deletion is final on the server, let's move things and then delete them.
    if (meta_entry.Get(IS_DEL)) {
      sync_entry->set_deleted(true);
    } else {
      if (meta_entry.Get(SPECIFICS).has_bookmark()) {
        // Both insert_after_item_id and position_in_parent fields are set only
        // for legacy reasons.  See comments in sync.proto for more information.
        const Id& prev_id = meta_entry.GetPredecessorId();
        string prev_id_string =
            prev_id.IsRoot() ? string() : prev_id.GetServerId();
        sync_entry->set_insert_after_item_id(prev_id_string);
        sync_entry->set_position_in_parent(
            meta_entry.Get(UNIQUE_POSITION).ToInt64());
        meta_entry.Get(UNIQUE_POSITION).ToProto(
            sync_entry->mutable_unique_position());
      }
      SetEntrySpecifics(&meta_entry, sync_entry);
    }
  }

  return SYNCER_OK;
}

}  // namespace syncer
<commit_msg>Remove unused variable declaration.<commit_after>// Copyright 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "sync/engine/build_commit_command.h"

#include <limits>
#include <set>
#include <string>
#include <vector>

#include "base/strings/string_util.h"
#include "sync/engine/syncer_proto_util.h"
#include "sync/internal_api/public/base/unique_position.h"
#include "sync/protocol/bookmark_specifics.pb.h"
#include "sync/protocol/sync.pb.h"
#include "sync/sessions/ordered_commit_set.h"
#include "sync/sessions/sync_session.h"
#include "sync/syncable/directory.h"
#include "sync/syncable/entry.h"
#include "sync/syncable/syncable_base_transaction.h"
#include "sync/syncable/syncable_changes_version.h"
#include "sync/syncable/syncable_proto_util.h"
#include "sync/util/time.h"

using std::set;
using std::string;
using std::vector;

namespace syncer {

using sessions::SyncSession;
using syncable::Entry;
using syncable::IS_DEL;
using syncable::IS_UNAPPLIED_UPDATE;
using syncable::IS_UNSYNCED;
using syncable::Id;
using syncable::SPECIFICS;
using syncable::UNIQUE_POSITION;

BuildCommitCommand::BuildCommitCommand(
    syncable::BaseTransaction* trans,
    const sessions::OrderedCommitSet& batch_commit_set,
    sync_pb::ClientToServerMessage* commit_message,
    ExtensionsActivity::Records* extensions_activity_buffer)
  : trans_(trans),
    batch_commit_set_(batch_commit_set),
    commit_message_(commit_message),
    extensions_activity_buffer_(extensions_activity_buffer) {
}

BuildCommitCommand::~BuildCommitCommand() {}

void BuildCommitCommand::AddExtensionsActivityToMessage(
    SyncSession* session, sync_pb::CommitMessage* message) {
  // We only send ExtensionsActivity to the server if bookmarks are being
  // committed.
  ExtensionsActivity* activity = session->context()->extensions_activity();
  if (batch_commit_set_.HasBookmarkCommitId()) {
    // This isn't perfect, since the set of extensions activity may not
    // correlate exactly with the items being committed.  That's OK as
    // long as we're looking for a rough estimate of extensions activity,
    // not an precise mapping of which commits were triggered by which
    // extension.
    //
    // We will push this list of extensions activity back into the
    // ExtensionsActivityMonitor if this commit fails.  That's why we must keep
    // a copy of these records in the session.
    activity->GetAndClearRecords(extensions_activity_buffer_);

    const ExtensionsActivity::Records& records =
        *extensions_activity_buffer_;
    for (ExtensionsActivity::Records::const_iterator it =
         records.begin();
         it != records.end(); ++it) {
      sync_pb::ChromiumExtensionsActivity* activity_message =
          message->add_extensions_activity();
      activity_message->set_extension_id(it->second.extension_id);
      activity_message->set_bookmark_writes_since_last_commit(
          it->second.bookmark_write_count);
    }
  }
}

void BuildCommitCommand::AddClientConfigParamsToMessage(
    SyncSession* session, sync_pb::CommitMessage* message) {
  const ModelSafeRoutingInfo& routing_info = session->context()->routing_info();
  sync_pb::ClientConfigParams* config_params = message->mutable_config_params();
  for (std::map<ModelType, ModelSafeGroup>::const_iterator iter =
          routing_info.begin(); iter != routing_info.end(); ++iter) {
    if (ProxyTypes().Has(iter->first))
      continue;
    int field_number = GetSpecificsFieldNumberFromModelType(iter->first);
    config_params->mutable_enabled_type_ids()->Add(field_number);
  }
  config_params->set_tabs_datatype_enabled(
      routing_info.count(syncer::PROXY_TABS) > 0);
}

namespace {
void SetEntrySpecifics(Entry* meta_entry,
                       sync_pb::SyncEntity* sync_entry) {
  // Add the new style extension and the folder bit.
  sync_entry->mutable_specifics()->CopyFrom(meta_entry->Get(SPECIFICS));
  sync_entry->set_folder(meta_entry->Get(syncable::IS_DIR));

  CHECK(!sync_entry->specifics().password().has_client_only_encrypted_data());
  DCHECK_EQ(meta_entry->GetModelType(), GetModelType(*sync_entry));
}
}  // namespace

SyncerError BuildCommitCommand::ExecuteImpl(SyncSession* session) {
  commit_message_->set_share(session->context()->account_name());
  commit_message_->set_message_contents(sync_pb::ClientToServerMessage::COMMIT);

  sync_pb::CommitMessage* commit_message = commit_message_->mutable_commit();
  commit_message->set_cache_guid(trans_->directory()->cache_guid());
  AddExtensionsActivityToMessage(session, commit_message);
  AddClientConfigParamsToMessage(session, commit_message);

  for (size_t i = 0; i < batch_commit_set_.Size(); i++) {
    Id id = batch_commit_set_.GetCommitIdAt(i);
    sync_pb::SyncEntity* sync_entry = commit_message->add_entries();
    sync_entry->set_id_string(SyncableIdToProto(id));
    Entry meta_entry(trans_, syncable::GET_BY_ID, id);
    CHECK(meta_entry.good());

    DCHECK_NE(0UL,
              session->context()->routing_info().count(
                  meta_entry.GetModelType()))
        << "Committing change to datatype that's not actively enabled.";

    string name = meta_entry.Get(syncable::NON_UNIQUE_NAME);
    CHECK(!name.empty());  // Make sure this isn't an update.
    // Note: Truncation is also performed in WriteNode::SetTitle(..). But this
    // call is still necessary to handle any title changes that might originate
    // elsewhere, or already be persisted in the directory.
    TruncateUTF8ToByteSize(name, 255, &name);
    sync_entry->set_name(name);

    // Set the non_unique_name.  If we do, the server ignores
    // the |name| value (using |non_unique_name| instead), and will return
    // in the CommitResponse a unique name if one is generated.
    // We send both because it may aid in logging.
    sync_entry->set_non_unique_name(name);

    if (!meta_entry.Get(syncable::UNIQUE_CLIENT_TAG).empty()) {
      sync_entry->set_client_defined_unique_tag(
          meta_entry.Get(syncable::UNIQUE_CLIENT_TAG));
    }

    // Deleted items with server-unknown parent ids can be a problem so we set
    // the parent to 0. (TODO(sync): Still true in protocol?).
    Id new_parent_id;
    if (meta_entry.Get(syncable::IS_DEL) &&
        !meta_entry.Get(syncable::PARENT_ID).ServerKnows()) {
      new_parent_id = trans_->root_id();
    } else {
      new_parent_id = meta_entry.Get(syncable::PARENT_ID);
    }
    sync_entry->set_parent_id_string(SyncableIdToProto(new_parent_id));

    // If our parent has changed, send up the old one so the server
    // can correctly deal with multiple parents.
    // TODO(nick): With the server keeping track of the primary sync parent,
    // it should not be necessary to provide the old_parent_id: the version
    // number should suffice.
    if (new_parent_id != meta_entry.Get(syncable::SERVER_PARENT_ID) &&
        0 != meta_entry.Get(syncable::BASE_VERSION) &&
        syncable::CHANGES_VERSION != meta_entry.Get(syncable::BASE_VERSION)) {
      sync_entry->set_old_parent_id(
          SyncableIdToProto(meta_entry.Get(syncable::SERVER_PARENT_ID)));
    }

    int64 version = meta_entry.Get(syncable::BASE_VERSION);
    if (syncable::CHANGES_VERSION == version || 0 == version) {
      // Undeletions are only supported for items that have a client tag.
      DCHECK(!id.ServerKnows() ||
             !meta_entry.Get(syncable::UNIQUE_CLIENT_TAG).empty())
          << meta_entry;

      // Version 0 means to create or undelete an object.
      sync_entry->set_version(0);
    } else {
      DCHECK(id.ServerKnows()) << meta_entry;
      sync_entry->set_version(meta_entry.Get(syncable::BASE_VERSION));
    }
    sync_entry->set_ctime(TimeToProtoTime(meta_entry.Get(syncable::CTIME)));
    sync_entry->set_mtime(TimeToProtoTime(meta_entry.Get(syncable::MTIME)));

    // Deletion is final on the server, let's move things and then delete them.
    if (meta_entry.Get(IS_DEL)) {
      sync_entry->set_deleted(true);
    } else {
      if (meta_entry.Get(SPECIFICS).has_bookmark()) {
        // Both insert_after_item_id and position_in_parent fields are set only
        // for legacy reasons.  See comments in sync.proto for more information.
        const Id& prev_id = meta_entry.GetPredecessorId();
        string prev_id_string =
            prev_id.IsRoot() ? string() : prev_id.GetServerId();
        sync_entry->set_insert_after_item_id(prev_id_string);
        sync_entry->set_position_in_parent(
            meta_entry.Get(UNIQUE_POSITION).ToInt64());
        meta_entry.Get(UNIQUE_POSITION).ToProto(
            sync_entry->mutable_unique_position());
      }
      SetEntrySpecifics(&meta_entry, sync_entry);
    }
  }

  return SYNCER_OK;
}

}  // namespace syncer
<|endoftext|>


<commit_before>/**
 *  @file
 *  @copyright defined in eos/LICENSE.txt
 */

#include <iostream>
#include <iomanip>
#include <limits>
#include <random>

#include <boost/program_options.hpp>

namespace po = boost::program_options;

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

   unsigned int seed = std::mt19937::default_seed;

   unsigned int num_cases = 10;

   po::options_description desc("Options");
   desc.add_options()
      ("help,h", "Print this help message and exit")
      ("seed,s", po::value<unsigned int>(&seed)->default_value(seed), "random seed")
      ("num-cases,n", po::value<unsigned int>(&num_cases)->default_value(num_cases), "number of test cases to generate" )
      ("avoid-specials", po::bool_switch()->default_value(false), "Avoid printing test cases for special values of double" )
   ;

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

   if( vm.count("help") ) {
      std::cout << desc << std::endl;
      return 1;
   }

   std::cout << "Seed: " << seed << std::endl;
   std::mt19937 gen(seed);

   double lbound = std::numeric_limits<double>::lowest();
   double ubound = std::numeric_limits<double>::max();

   std::uniform_int_distribution<uint64_t> dis(0, std::numeric_limits<uint64_t>::max());

   std::cout.precision(std::numeric_limits<double>::digits10 + 1);

   auto print_triplet = [&]( double d, bool add_trailing_comma = false,
                             int left_padding = 0, bool add_newline_at_end = true) {
      std::cout << std::setw(left_padding) << "";
      std::cout << "[\"0x" << std::hex << *(uint64_t*)(&d) << "\", \""
                << std::hexfloat << d << "\", \"" << std::fixed << d << "\"]";
      if( add_trailing_comma )
         std::cout << ",";
      if( add_newline_at_end )
         std::cout << std::endl;
   };

   if( num_cases > 0 ) {
      std::cout << std::endl;
      std::cout <<    "Randomly generated double test cases (raw hex dump, hexidecimal float, decimal fixed) "
                      "within the interval [" << std::fixed << lbound << ", " << ubound << "]:" << std::endl
                <<    " [" << std::endl;
      for( int n = 1, end = num_cases; n <= end; )
      {

         uint64_t x = dis(gen);
         double v = *(double*)(&x);

         if( !(lbound <= v && v <= ubound) ) continue;

         print_triplet(v, n != end, 2);
         ++n;
      }
      std::cout << "]" << std::endl;
   }

   if( !vm["avoid-specials"].as<bool>() ) {
      std::cout << std::endl;
      std::cout << "Special double value test cases (raw hex dump, hexidecimal float, decimal fixed):" << std::endl;

      using nld = std::numeric_limits<double>;

      std::cout << " lowest():        "; print_triplet(nld::lowest());
      std::cout << " min():           "; print_triplet(nld::min());
      std::cout << " max():           "; print_triplet(nld::max());
      std::cout << " epsilon():       "; print_triplet(nld::epsilon());
      std::cout << " round_error():   "; print_triplet(nld::round_error());
      std::cout << " infinity():      "; print_triplet(nld::infinity());
      std::cout << " quiet_NaN():     "; print_triplet(nld::quiet_NaN());
      std::cout << " signaling_NaN(): "; print_triplet(nld::signaling_NaN());
      std::cout << " denorm_min():    "; print_triplet(nld::denorm_min(), false);

   }

   return 0;
}
<commit_msg>small changes to print_floats<commit_after>/**
 *  @file
 *  @copyright defined in eos/LICENSE.txt
 */

#include <iostream>
#include <iomanip>
#include <limits>
#include <random>

#include <boost/program_options.hpp>

namespace po = boost::program_options;

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

   unsigned int seed = std::mt19937::default_seed;

   unsigned int num_cases = 10;

   po::options_description desc("Options");
   desc.add_options()
      ("help,h", "Print this help message and exit")
      ("seed,s", po::value<unsigned int>(&seed)->default_value(seed), "random seed")
      ("num-cases,n", po::value<unsigned int>(&num_cases)->default_value(num_cases), "number of test cases to generate" )
      ("avoid-specials", po::bool_switch()->default_value(false), "Avoid printing test cases for special values of double" )
   ;

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

   if( vm.count("help") ) {
      std::cout << desc << std::endl;
      return 1;
   }

   std::cout << "Seed: " << seed << std::endl;
   std::mt19937 gen(seed);

   double lbound = std::numeric_limits<double>::lowest();
   double ubound = std::numeric_limits<double>::max();

   std::uniform_int_distribution<uint64_t> dis(0, std::numeric_limits<uint64_t>::max());

   std::cout.precision(std::numeric_limits<double>::digits10 + 1);

   auto print_triplet = [&]( double d, int left_padding = 0 ) {
      std::cout << std::setw(left_padding) << "";
      std::cout << "[\"0x" << std::hex << *(uint64_t*)(&d) << "\", \""
                << std::hexfloat << d << "\", \"" << std::fixed << d << "\"]";
   };

   if( num_cases > 0 ) {
      std::cout << std::endl;
      std::cout <<    "Randomly generated double test cases (raw hex dump, hexidecimal float, decimal fixed) "
                      "within the interval [" << std::fixed << lbound << ", " << ubound << "]:" << std::endl
                <<    " [" << std::endl;
      for( int n = 1, end = num_cases; n <= end; )
      {

         uint64_t x = dis(gen);
         double v = *(double*)(&x);

         if( !(lbound <= v && v <= ubound) ) continue;

         print_triplet(v, 2);
         if( n != end )
            std::cout << ",";

         std::cout << std::endl;

         ++n;
      }
      std::cout << "]" << std::endl;
   }

   if( !vm["avoid-specials"].as<bool>() ) {
      std::cout << std::endl;
      std::cout << "Special double value test cases (raw hex dump, hexidecimal float, decimal fixed):" << std::endl;

      using nld = std::numeric_limits<double>;

      std::cout << std::endl << " lowest():        "; print_triplet(nld::lowest());
      std::cout << std::endl << " min():           "; print_triplet(nld::min());
      std::cout << std::endl << " max():           "; print_triplet(nld::max());
      std::cout << std::endl << " epsilon():       "; print_triplet(nld::epsilon());
      std::cout << std::endl << " round_error():   "; print_triplet(nld::round_error());
      std::cout << std::endl << " +0:              "; print_triplet(0.0);
      std::cout << std::endl << " -0:              "; print_triplet(-0.0);
      std::cout << std::endl << " infinity():      "; print_triplet(nld::infinity());
      std::cout << std::endl << " -infinity():     "; print_triplet(-nld::infinity());
      std::cout << std::endl << " quiet_NaN():     "; print_triplet(nld::quiet_NaN());
      std::cout << std::endl << " signaling_NaN(): "; print_triplet(nld::signaling_NaN());
      std::cout << std::endl << " denorm_min():    "; print_triplet(nld::denorm_min());
      std::cout << std::endl;

   }

   return 0;
}
<|endoftext|>


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

#include <znc/FileUtils.h>
#include <znc/Server.h>
#include <znc/IRCNetwork.h>
#include <znc/User.h>
#include <znc/ZNCDebug.h>

class CAdminDebugMod : public CModule {
  private:
      CString m_sEnabledBy;

  public:
    MODCONSTRUCTOR(CAdminDebugMod) {
        AddHelpCommand();
        AddCommand("Enable", "", t_d("Enable Debug Mode"),
                   [=](const CString& sLine) { CommandEnable(sLine); });
        AddCommand("Disable", "", t_d("Disable Debug Mode"),
                   [=](const CString& sLine) { CommandDisable(sLine); });
        AddCommand("Status", "", t_d("Show the Debug Mode status"),
                   [=](const CString& sLine) { CommandStatus(sLine); });
    }

    void CommandEnable(const CString& sCommand) {
        if (GetUser()->IsAdmin() == false) {
            PutModule(t_s("Access denied!"));
            return;
        }

        ToggleDebug(true, GetUser()->GetNick());
    }

    void CommandDisable(const CString& sCommand) {
        if (GetUser()->IsAdmin() == false) {
            PutModule(t_s("Access denied!"));
            return;
        }

        ToggleDebug(false, m_sEnabledBy);
    }

    bool ToggleDebug(bool bEnable, CString sEnabledBy) {
        bool bValue = CDebug::Debug();

        if (bEnable == bValue) {
            if (bEnable) {
                PutModule(t_s("Already enabled."));
            } else {
                PutModule(t_s("Already disabled."));
            }
            return false;
        }

        CDebug::SetDebug(bEnable);
        CString sEnabled = CString(bEnable ? "on" : "off");
        CZNC::Get().Broadcast(CString(
            "An administrator has just turned Debug Mode \02" + sEnabled + "\02. It was enabled by \02" + sEnabledBy + "\02."
        ));
        if (bEnable) {
            CZNC::Get().Broadcast(
                CString("Messages, credentials, and other sensitive data may"
                " become exposed to the host during this period.")
            );
            m_sEnabledBy = sEnabledBy;
        } else {
            m_sEnabledBy = nullptr;
        }

        return true;
    }

    void CommandStatus(const CString& sCommand) {
        if (CDebug::Debug()) {
            PutModule(t_s("Debugging mode is \02on\02."));
        } else {
             PutModule(t_s("Debugging mode is \02off\02."));
        }
        PutModule(t_s("Logging to: \02stdout\02."));
    }
};

template <>
void TModInfo<CAdminDebugMod>(CModInfo& Info) {
    Info.SetWikiPage("admindebug");
}

GLOBALMODULEDEFS(CAdminDebugMod, t_s("Enable Debug mode dynamically."))
<commit_msg>admindebug: Enforce need of TTY to turn on debug mode<commit_after>/*
 * Copyright (C) 2004-2018 ZNC, see the NOTICE file for details.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <znc/FileUtils.h>
#include <znc/Server.h>
#include <znc/IRCNetwork.h>
#include <znc/User.h>
#include <znc/ZNCDebug.h>

class CAdminDebugMod : public CModule {
  private:
      CString m_sEnabledBy;

  public:
    MODCONSTRUCTOR(CAdminDebugMod) {
        AddHelpCommand();
        AddCommand("Enable", "", t_d("Enable Debug Mode"),
                   [=](const CString& sLine) { CommandEnable(sLine); });
        AddCommand("Disable", "", t_d("Disable Debug Mode"),
                   [=](const CString& sLine) { CommandDisable(sLine); });
        AddCommand("Status", "", t_d("Show the Debug Mode status"),
                   [=](const CString& sLine) { CommandStatus(sLine); });
    }

    void CommandEnable(const CString& sCommand) {
        if (GetUser()->IsAdmin() == false) {
            PutModule(t_s("Access denied!"));
            return;
        }

        ToggleDebug(true, GetUser()->GetNick());
    }

    void CommandDisable(const CString& sCommand) {
        if (GetUser()->IsAdmin() == false) {
            PutModule(t_s("Access denied!"));
            return;
        }

        ToggleDebug(false, m_sEnabledBy);
    }

    bool ToggleDebug(bool bEnable, CString sEnabledBy) {
        if (!CDebug::StdoutIsTTY()) {
            PutModule(t_s("Failure. We need to be running with a TTY. (is ZNC running with --foreground?)"));
            return false;
        }

        bool bValue = CDebug::Debug();

        if (bEnable == bValue) {
            if (bEnable) {
                PutModule(t_s("Already enabled."));
            } else {
                PutModule(t_s("Already disabled."));
            }
            return false;
        }

        CDebug::SetDebug(bEnable);
        CString sEnabled = CString(bEnable ? "on" : "off");
        CZNC::Get().Broadcast(CString(
            "An administrator has just turned Debug Mode \02" + sEnabled + "\02. It was enabled by \02" + sEnabledBy + "\02."
        ));
        if (bEnable) {
            CZNC::Get().Broadcast(
                CString("Messages, credentials, and other sensitive data may"
                " become exposed to the host during this period.")
            );
            m_sEnabledBy = sEnabledBy;
        } else {
            m_sEnabledBy = "";
        }

        return true;
    }

    void CommandStatus(const CString& sCommand) {
        if (CDebug::Debug()) {
            PutModule(t_s("Debugging mode is \02on\02."));
        } else {
             PutModule(t_s("Debugging mode is \02off\02."));
        }
        PutModule(t_s("Logging to: \02stdout\02."));
    }
};

template <>
void TModInfo<CAdminDebugMod>(CModInfo& Info) {
    Info.SetWikiPage("admindebug");
}

GLOBALMODULEDEFS(CAdminDebugMod, t_s("Enable Debug mode dynamically."))
<|endoftext|>


<commit_before>#include "triangle_free_graph.hh"

Triangle_Free_Graph::Triangle_Free_Graph(uint16_t n)
	: Graph(n)
	, available_edges(n * (n - 1) / 2) {}

void Triangle_Free_Graph::set(uint16_t u, uint16_t v, Entry e) {
	Graph::set(u,v,e);
	available_edges--;
	for (uint16_t i = 0; i < n(); i++) {
		if (i != u && i != v) {
			if (adjacency_matrix[u][i] == Entry::mini ||
					adjacency_matrix[u][i] == Entry::maxi) {
				adjacency_matrix[v][i] = Entry::blocked;
				available_edges--; // (u i) or (v i) would complete a triangle
			} else if (adjacency_matrix[v][i] == Entry::mini ||
					adjacency_matrix[v][i] == Entry::maxi) {
				adjacency_matrix[u][i] = Entry::blocked;
				available_edges--; // (u i) or (v i) would complete a triangle
			}
		}
	}
}

bool Triangle_Free_Graph::is_valid(uint16_t u, uint16_t v, Entry e) {
	(void) e;
	for (uint16_t i = 0; i < n(); i++) {
		if (adjacency_matrix[u][i] != Entry::empty &&
				adjacency_matrix[v][i] != Entry::empty) {
			return false; // Triangle u,v,i
		}
	}
	return true;
}

bool Triangle_Free_Graph::saturated(void) {
	return available_edges == 0;
}
<commit_msg>Bugfix edge counting<commit_after>#include "triangle_free_graph.hh"

Triangle_Free_Graph::Triangle_Free_Graph(uint16_t n)
	: Graph(n)
	, available_edges(n * (n - 1) / 2) {}

void Triangle_Free_Graph::set(uint16_t u, uint16_t v, Entry e) {
	Graph::set(u,v,e);
	available_edges--;
	for (uint16_t i = 0; i < n(); i++) {
		if (i != u && i != v) {
			if ((adjacency_matrix[u][i] == Entry::mini ||
					adjacency_matrix[u][i] == Entry::maxi) &&
					adjacency_matrix[v][i] == Entry::empty) {
				adjacency_matrix[v][i] = Entry::blocked;
				adjacency_matrix[i][v] = Entry::blocked;
				available_edges--; // (u i) or (v i) would complete a triangle
			} else if ((adjacency_matrix[v][i] == Entry::mini ||
					adjacency_matrix[v][i] == Entry::maxi) &&
					adjacency_matrix[u][i] == Entry::empty) {
				adjacency_matrix[u][i] = Entry::blocked;
				adjacency_matrix[i][u] = Entry::blocked;
				available_edges--; // (u i) or (v i) would complete a triangle
			}
		}
	}
}

bool Triangle_Free_Graph::is_valid(uint16_t u, uint16_t v, Entry e) {
	(void) e;
	for (uint16_t i = 0; i < n(); i++) {
		if (adjacency_matrix[u][i] != Entry::empty &&
				adjacency_matrix[v][i] != Entry::empty) {
			return false; // Triangle u,v,i
		}
	}
	return true;
}

bool Triangle_Free_Graph::saturated(void) {
	return available_edges == 0;
}
<|endoftext|>


<commit_before>#include <cerrno>
#include <cstring>
#include <iostream>

#include <pqxx/pqxx>

#include "test_helpers.hxx"

using namespace PGSTD;
using namespace pqxx;

// Mixed-mode, seeking test program for libpqxx's Large Objects interface.
namespace
{
const string Contents = "Large object test contents";

class WriteLargeObject : public transactor<>
{
public:
  explicit WriteLargeObject() :
    transactor<>("WriteLargeObject")
  {
  }

  void operator()(argument_type &T)
  {
    largeobjectaccess A(T);
    cout << "Writing to large object #" << largeobject(A).id() << endl;

    A.write(Contents);

    char Buf[200];
    const size_t Size = sizeof(Buf) - 1;
    PQXX_CHECK_EQUAL(
	A.read(Buf, Size),
	0u,
	"Could read bytes from large object after writing.");

    // Overwrite terminating zero
    largeobjectaccess::size_type Here = A.seek(-1, ios::cur);

    // Redundant typedef to work around bug in Visual C++.NET
    typedef largeobjectaccess::size_type loa_size;
    PQXX_CHECK_EQUAL(
	Here,
	loa_size(Contents.size()-1),
	"Ended up in wrong place after moving back 1 byte.");

    A.write("!", 1);

    // Now check that we really did
    PQXX_CHECK_EQUAL(
	A.seek(-1, ios::cur),
	loa_size(Contents.size()-1),
	"Inconsistent seek.");

    char Check;
    PQXX_CHECK_EQUAL(
	A.read(&Check, 1),
	1,
	"Unexpected result from read().");
    PQXX_CHECK_EQUAL(string(&Check, 1), "!", "Read back wrong character.");

    PQXX_CHECK_EQUAL(
	A.seek(0, ios::beg),
	0,
	"Ended up in wrong place after seeking back to beginning.");

    PQXX_CHECK_EQUAL(
	A.read(&Check, 1),
	1,
	"Unexpected result when trying to read back 1st byte.");

    PQXX_CHECK_EQUAL(
	string(&Check, 1),
	string(Contents, 0, 1),
	"Wrong first character in large object.");

    // Clean up after ourselves
    A.remove(T);
  }

private:
  largeobject m_Object;
};

void test_058(connection_base &C, transaction_base &orgT)
{
  orgT.abort();

  C.perform(WriteLargeObject());
}
} // namespace

PQXX_REGISTER_TEST_T(test_058, nontransaction)
<commit_msg>Test build fix.<commit_after>#include <cerrno>
#include <cstring>
#include <iostream>

#include <pqxx/pqxx>

#include "test_helpers.hxx"

using namespace PGSTD;
using namespace pqxx;

// Mixed-mode, seeking test program for libpqxx's Large Objects interface.
namespace
{
const string Contents = "Large object test contents";

class WriteLargeObject : public transactor<>
{
public:
  explicit WriteLargeObject() :
    transactor<>("WriteLargeObject")
  {
  }

  void operator()(argument_type &T)
  {
    largeobjectaccess A(T);
    cout << "Writing to large object #" << largeobject(A).id() << endl;

    A.write(Contents);

    char Buf[200];
    const size_t Size = sizeof(Buf) - 1;
    PQXX_CHECK_EQUAL(
	A.read(Buf, Size),
	0,
	"Could read bytes from large object after writing.");

    // Overwrite terminating zero
    largeobjectaccess::size_type Here = A.seek(-1, ios::cur);

    // Redundant typedef to work around bug in Visual C++.NET
    typedef largeobjectaccess::size_type loa_size;
    PQXX_CHECK_EQUAL(
	Here,
	loa_size(Contents.size()-1),
	"Ended up in wrong place after moving back 1 byte.");

    A.write("!", 1);

    // Now check that we really did
    PQXX_CHECK_EQUAL(
	A.seek(-1, ios::cur),
	loa_size(Contents.size()-1),
	"Inconsistent seek.");

    char Check;
    PQXX_CHECK_EQUAL(
	A.read(&Check, 1),
	1,
	"Unexpected result from read().");
    PQXX_CHECK_EQUAL(string(&Check, 1), "!", "Read back wrong character.");

    PQXX_CHECK_EQUAL(
	A.seek(0, ios::beg),
	0,
	"Ended up in wrong place after seeking back to beginning.");

    PQXX_CHECK_EQUAL(
	A.read(&Check, 1),
	1,
	"Unexpected result when trying to read back 1st byte.");

    PQXX_CHECK_EQUAL(
	string(&Check, 1),
	string(Contents, 0, 1),
	"Wrong first character in large object.");

    // Clean up after ourselves
    A.remove(T);
  }

private:
  largeobject m_Object;
};

void test_058(connection_base &C, transaction_base &orgT)
{
  orgT.abort();

  C.perform(WriteLargeObject());
}
} // namespace

PQXX_REGISTER_TEST_T(test_058, nontransaction)
<|endoftext|>


<commit_before>/**
 * Clever programming language
 * Copyright (c) Clever Team
 *
 * This file is distributed under the MIT license. See LICENSE for details.
 */

#include <cstdlib>
#include <sstream>

#ifdef CLEVER_WIN32
# include <direct.h>
# include <windows.h>
# define PATH_MAX MAX_PATH
#else
# include <dirent.h>
# include <sys/resource.h>
# include <sys/time.h>
# include <unistd.h>
#endif
#include "core/clever.h"
#include "core/value.h"
#include "core/driver.h"
#include "core/native_types.h"
#include "core/modmanager.h"
#include "core/cexception.h"
#include "modules/std/sys/sys.h"

#ifndef PATH_MAX
# define PATH_MAX 1024
#endif

namespace clever { namespace modules { namespace std {

namespace sys {

// system(string command)
// Calls a command and returns the exit code
static CLEVER_FUNCTION(system)
{
	if (!clever_static_check_args("s")) {
		return;
	}

	result->setInt(::system(args[0]->getStr()->c_str()));
}

// putenv(string env)
// Sets an environment variable
static CLEVER_FUNCTION(putenv)
{
	if (!clever_static_check_args("s")) {
		return;
	}

	::putenv(const_cast<char*>(args[0]->getStr()->c_str()));
}

// getenv(string env)
// Gets an environment variable
static CLEVER_FUNCTION(getenv)
{
	if (!clever_static_check_args("s")) {
		return;
	}

	const char* ret = ::getenv(const_cast<char*>(args[0]->getStr()->c_str()));

	if (ret) {
		result->setStr(CSTRINGT(ret));
	} else {
		result->setStr(CSTRING(""));
	}
}

// getcwd()
// Gets the current working directory
static CLEVER_FUNCTION(getcwd)
{
	if (!clever_static_check_no_args()) {
		return;
	}

	char temp[PATH_MAX];
	const char* path = ::getcwd(temp, PATH_MAX);

	result->setStr(CSTRING(path ? path : ""));
}

// argv(int n)
// Get n-th argv value
static CLEVER_FUNCTION(argv)
{
	if (!clever_static_check_args("i")) {
		return;
	}

	if (args[0]->getInt() >= *g_clever_argc) {
		result->setBool(false);
	} else {
		result->setStr(new StrObject((*g_clever_argv)[args[0]->getInt()]));
	}
}

// argc()
// Get argc value
static CLEVER_FUNCTION(argc)
{
	if (!clever_static_check_no_args()) {
		return;
	}

	result->setInt(*g_clever_argc);
}

// sleep(int time)
// Sleep for 'time' milliseconds
static CLEVER_FUNCTION(sleep)
{
	if (!clever_static_check_args("i")) {
		return;
	}

	int time = static_cast<int>(args[0]->getInt());

#ifdef CLEVER_WIN32
	SleepEx(time, false);
#else
	usleep(time * 1000);
#endif
}

// clock()
// Returns the execution clock
static CLEVER_FUNCTION(clock)
{
	if (!clever_static_check_no_args()) {
		return;
	}

	result->setInt(clock());
}

// time()
// Returns the execution time in sec
static CLEVER_FUNCTION(time)
{
	if (!clever_static_check_no_args()) {
		return;
	}

	struct timeval tp = {0};
	if (gettimeofday(&tp, NULL)) {
		result->setBool(false);
		return;
	}
	result->setDouble(tp.tv_sec);
}

// microtime()
// Returns the unix timestamp with microseconds
static CLEVER_FUNCTION(microtime)
{
	struct timeval tp = {0};

	if (!clever_static_check_no_args()) {
		return;
	}
	if (gettimeofday(&tp, NULL)) {
		result->setBool(false);
		return;
	}

	result->setDouble(tp.tv_sec + tp.tv_usec / 1000000.00);
}

// getpid()
// Returns the current process id
static CLEVER_FUNCTION(getpid)
{
	if (!clever_static_check_no_args()) {
		return;
	}

	result->setInt(::getpid());
}

// getppid()
// Returns the current process id
static CLEVER_FUNCTION(getppid)
{
	if (!clever_static_check_no_args()) {
		return;
	}

	result->setInt(::getppid());
}

// getuid()
// Returns the process user id
static CLEVER_FUNCTION(getuid)
{
	if (!clever_static_check_no_args()) {
		return;
	}

	result->setInt(::geteuid());
}

// getsid()
// Returns the process group id
static CLEVER_FUNCTION(getsid)
{
	if (!clever_static_check_no_args()) {
		return;
	}

	result->setInt(::getsid(0));
}

// info()
// Returns information about the build and environment
static CLEVER_FUNCTION(info)
{
	if (!clever_static_check_no_args()) {
		return;
	}

	::std::ostringstream oss;
	oss << "Version: " << CLEVER_VERSION_STRING << "\n";
	oss << "Debug Mode: " << (CLEVER_DEBUG ? "Yes" : "No") << "\n";
	oss << "OS: ";
#ifdef CLEVER_WIN32
	oss << "Windows";
# ifdef CLEVER_CYGWIN
	oss << " (Cygwin)";
# elif CLEVER_MSVC
	oss << " (MSVC)";
# endif
#elif CLEVER_APPLE
	oss << "Mac OSX";
#elif CLEVER_HAIKU
	oss << "Haiku";
#else
	oss << "Unknown";
#endif
	oss << "\n";

	// TODO(muriloadriano): Add more and more detailed information about the
	// environment and the enabled modules.

	return result->setStr(new StrObject(oss.str()));
}

} // clever::modules::std::sys

// Initializes Standard module
CLEVER_MODULE_INIT(SYSModule)
{
	addFunction(new Function("system",    &CLEVER_NS_FNAME(sys, system)));
	addFunction(new Function("putenv",    &CLEVER_NS_FNAME(sys, putenv)));
	addFunction(new Function("getenv",    &CLEVER_NS_FNAME(sys, getenv)));
	addFunction(new Function("getcwd",    &CLEVER_NS_FNAME(sys, getcwd)));
	addFunction(new Function("getpid",    &CLEVER_NS_FNAME(sys, getpid)));
	addFunction(new Function("getppid",   &CLEVER_NS_FNAME(sys, getppid)));
	addFunction(new Function("getuid",    &CLEVER_NS_FNAME(sys, getuid)));
	addFunction(new Function("getsid",    &CLEVER_NS_FNAME(sys, getsid)));
	addFunction(new Function("argc",      &CLEVER_NS_FNAME(sys, argc)));
	addFunction(new Function("argv",      &CLEVER_NS_FNAME(sys, argv)));
	addFunction(new Function("sleep",     &CLEVER_NS_FNAME(sys, sleep)));
	addFunction(new Function("clock",     &CLEVER_NS_FNAME(sys, clock)));
	addFunction(new Function("time",      &CLEVER_NS_FNAME(sys, time)));
	addFunction(new Function("microtime", &CLEVER_NS_FNAME(sys, microtime)));
	addFunction(new Function("info",      &CLEVER_NS_FNAME(sys, info)));
}

}}} // clever::modules::std
<commit_msg>Added integer size to sys:info<commit_after>/**
 * Clever programming language
 * Copyright (c) Clever Team
 *
 * This file is distributed under the MIT license. See LICENSE for details.
 */

#include <cstdlib>
#include <sstream>

#ifdef CLEVER_WIN32
# include <direct.h>
# include <windows.h>
# define PATH_MAX MAX_PATH
#else
# include <dirent.h>
# include <sys/resource.h>
# include <sys/time.h>
# include <unistd.h>
#endif
#include "core/clever.h"
#include "core/value.h"
#include "core/driver.h"
#include "core/native_types.h"
#include "core/modmanager.h"
#include "core/cexception.h"
#include "modules/std/sys/sys.h"

#ifndef PATH_MAX
# define PATH_MAX 1024
#endif

namespace clever { namespace modules { namespace std {

namespace sys {

// system(string command)
// Calls a command and returns the exit code
static CLEVER_FUNCTION(system)
{
	if (!clever_static_check_args("s")) {
		return;
	}

	result->setInt(::system(args[0]->getStr()->c_str()));
}

// putenv(string env)
// Sets an environment variable
static CLEVER_FUNCTION(putenv)
{
	if (!clever_static_check_args("s")) {
		return;
	}

	::putenv(const_cast<char*>(args[0]->getStr()->c_str()));
}

// getenv(string env)
// Gets an environment variable
static CLEVER_FUNCTION(getenv)
{
	if (!clever_static_check_args("s")) {
		return;
	}

	const char* ret = ::getenv(const_cast<char*>(args[0]->getStr()->c_str()));

	if (ret) {
		result->setStr(CSTRINGT(ret));
	} else {
		result->setStr(CSTRING(""));
	}
}

// getcwd()
// Gets the current working directory
static CLEVER_FUNCTION(getcwd)
{
	if (!clever_static_check_no_args()) {
		return;
	}

	char temp[PATH_MAX];
	const char* path = ::getcwd(temp, PATH_MAX);

	result->setStr(CSTRING(path ? path : ""));
}

// argv(int n)
// Get n-th argv value
static CLEVER_FUNCTION(argv)
{
	if (!clever_static_check_args("i")) {
		return;
	}

	if (args[0]->getInt() >= *g_clever_argc) {
		result->setBool(false);
	} else {
		result->setStr(new StrObject((*g_clever_argv)[args[0]->getInt()]));
	}
}

// argc()
// Get argc value
static CLEVER_FUNCTION(argc)
{
	if (!clever_static_check_no_args()) {
		return;
	}

	result->setInt(*g_clever_argc);
}

// sleep(int time)
// Sleep for 'time' milliseconds
static CLEVER_FUNCTION(sleep)
{
	if (!clever_static_check_args("i")) {
		return;
	}

	int time = static_cast<int>(args[0]->getInt());

#ifdef CLEVER_WIN32
	SleepEx(time, false);
#else
	usleep(time * 1000);
#endif
}

// clock()
// Returns the execution clock
static CLEVER_FUNCTION(clock)
{
	if (!clever_static_check_no_args()) {
		return;
	}

	result->setInt(clock());
}

// time()
// Returns the execution time in sec
static CLEVER_FUNCTION(time)
{
	if (!clever_static_check_no_args()) {
		return;
	}

	struct timeval tp = {0};
	if (gettimeofday(&tp, NULL)) {
		result->setBool(false);
		return;
	}
	result->setDouble(tp.tv_sec);
}

// microtime()
// Returns the unix timestamp with microseconds
static CLEVER_FUNCTION(microtime)
{
	struct timeval tp = {0};

	if (!clever_static_check_no_args()) {
		return;
	}
	if (gettimeofday(&tp, NULL)) {
		result->setBool(false);
		return;
	}

	result->setDouble(tp.tv_sec + tp.tv_usec / 1000000.00);
}

// getpid()
// Returns the current process id
static CLEVER_FUNCTION(getpid)
{
	if (!clever_static_check_no_args()) {
		return;
	}

	result->setInt(::getpid());
}

// getppid()
// Returns the current process id
static CLEVER_FUNCTION(getppid)
{
	if (!clever_static_check_no_args()) {
		return;
	}

	result->setInt(::getppid());
}

// getuid()
// Returns the process user id
static CLEVER_FUNCTION(getuid)
{
	if (!clever_static_check_no_args()) {
		return;
	}

	result->setInt(::geteuid());
}

// getsid()
// Returns the process group id
static CLEVER_FUNCTION(getsid)
{
	if (!clever_static_check_no_args()) {
		return;
	}

	result->setInt(::getsid(0));
}

// info()
// Returns information about the build and environment
static CLEVER_FUNCTION(info)
{
	if (!clever_static_check_no_args()) {
		return;
	}

	::std::ostringstream oss;
	oss << "Version: " << CLEVER_VERSION_STRING << "\n";
	oss << "Debug Mode: " << (CLEVER_DEBUG ? "Yes" : "No") << "\n";
	oss << "OS: ";
#ifdef CLEVER_WIN32
	oss << "Windows";
# ifdef CLEVER_CYGWIN
	oss << " (Cygwin)";
# elif CLEVER_MSVC
	oss << " (MSVC)";
# endif
#elif CLEVER_APPLE
	oss << "Mac OSX";
#elif CLEVER_HAIKU
	oss << "Haiku";
#else
	oss << "Unknown";
#endif
	oss << "\n\n";

	oss << "Integer Size: " << sizeof(long) * 8 << " bits (" << sizeof(long)
		<< " bytes)";

	// TODO(muriloadriano): Add more and more detailed information about the
	// environment and the enabled modules.

	return result->setStr(new StrObject(oss.str()));
}

} // clever::modules::std::sys

// Initializes Standard module
CLEVER_MODULE_INIT(SYSModule)
{
	addFunction(new Function("system",    &CLEVER_NS_FNAME(sys, system)));
	addFunction(new Function("putenv",    &CLEVER_NS_FNAME(sys, putenv)));
	addFunction(new Function("getenv",    &CLEVER_NS_FNAME(sys, getenv)));
	addFunction(new Function("getcwd",    &CLEVER_NS_FNAME(sys, getcwd)));
	addFunction(new Function("getpid",    &CLEVER_NS_FNAME(sys, getpid)));
	addFunction(new Function("getppid",   &CLEVER_NS_FNAME(sys, getppid)));
	addFunction(new Function("getuid",    &CLEVER_NS_FNAME(sys, getuid)));
	addFunction(new Function("getsid",    &CLEVER_NS_FNAME(sys, getsid)));
	addFunction(new Function("argc",      &CLEVER_NS_FNAME(sys, argc)));
	addFunction(new Function("argv",      &CLEVER_NS_FNAME(sys, argv)));
	addFunction(new Function("sleep",     &CLEVER_NS_FNAME(sys, sleep)));
	addFunction(new Function("clock",     &CLEVER_NS_FNAME(sys, clock)));
	addFunction(new Function("time",      &CLEVER_NS_FNAME(sys, time)));
	addFunction(new Function("microtime", &CLEVER_NS_FNAME(sys, microtime)));
	addFunction(new Function("info",      &CLEVER_NS_FNAME(sys, info)));
}

}}} // clever::modules::std
<|endoftext|>


<commit_before>//---------------------------------------------------------------------------//
/*!
 * \file tstMCSA.cpp
 * \author Stuart R. Slattery
 * \brief MCSA tests.
 */
//---------------------------------------------------------------------------//

#include <iostream>
#include <vector>
#include <cmath>
#include <cstdlib>
#include <sstream>
#include <algorithm>
#include <string>
#include <cassert>

#include <Chimera_LinearSolver.hpp>
#include <Chimera_LinearProblem.hpp>
#include <Chimera_LinearSolverFactory.hpp>

#include <Teuchos_UnitTestHarness.hpp>
#include <Teuchos_DefaultComm.hpp>
#include <Teuchos_CommHelpers.hpp>
#include <Teuchos_RCP.hpp>
#include <Teuchos_ArrayRCP.hpp>
#include <Teuchos_Array.hpp>
#include <Teuchos_OpaqueWrapper.hpp>
#include <Teuchos_TypeTraits.hpp>
#include <Teuchos_Tuple.hpp>
#include <Teuchos_ParameterList.hpp>

#include <Tpetra_Map.hpp>
#include <Tpetra_CrsMatrix.hpp>
#include <Tpetra_Vector.hpp>

//---------------------------------------------------------------------------//
// Tests
//---------------------------------------------------------------------------//
TEUCHOS_UNIT_TEST( MCSA, mcsa_test )
{
    // Setup parallel distribution.
    Teuchos::RCP<const Teuchos::Comm<int> > comm =
	Teuchos::DefaultComm<int>::getComm();

    // Build the linear operator - this is a 2D Transient Diffusion operator.
    int N = 50;
    int problem_size = N*N;
    double dx = 0.01;
    double dy = 0.01;
    double dt = 0.05;
    double alpha = 0.001;
    Teuchos::RCP<const Tpetra::Map<int> > row_map =
	Tpetra::createUniformContigMap<int,int>( problem_size, comm );
    Teuchos::RCP<Tpetra::CrsMatrix<double,int,int> > A =
	Tpetra::createCrsMatrix<double,int,int>( row_map, 3 );

    Teuchos::Array<double> diag( 1, 1.0 + 2*dt*alpha*( 1/(dx*dx) + 1/(dy*dy) ) );
    Teuchos::Array<double> i_minus( 1, -dt*alpha/(dx*dx) );
    Teuchos::Array<double> i_plus( 1, -dt*alpha/(dx*dx) );
    Teuchos::Array<double> j_minus( 1, -dt*alpha/(dy*dy) );
    Teuchos::Array<double> j_plus( 1, -dt*alpha/(dy*dy) );

    Teuchos::Array<int> idx(1);
    Teuchos::Array<int> idx_iminus(1);
    Teuchos::Array<int> idx_iplus(1);
    Teuchos::Array<int> idx_jminus(1);
    Teuchos::Array<int> idx_jplus(1);
    Teuchos::Array<double> one(1,1.0);

    if ( comm->getRank() == 0 )
    {
	// Min X boundary Dirichlet.
	for ( int j = 1; j < N-1; ++j )
	{
	    int i = 0;
	    idx[0] = i + j*N;
	    A->insertGlobalValues( idx[0], idx(), one() );
	}

	// Max X boundary Dirichlet.
	for ( int j = 1; j < N-1; ++j )
	{
	    int i = N-1;
	    idx[0] = i + j*N;
	    A->insertGlobalValues( idx[0], idx(), one() );
	}

	// Min Y boundary Dirichlet.
	for ( int i = 0; i < N; ++i )
	{
	    int j = 0;
	    idx[0] = i + j*N;
	    A->insertGlobalValues( idx[0], idx(), one() );
	}

	// Max Y boundary Dirichlet.
	for ( int i = 0; i < N; ++i )
	{
	    int j = N-1;
	    idx[0] = i + j*N;
	    A->insertGlobalValues( idx[0], idx(), one() );
	}

	// Central grid points.
	for ( int i = 1; i < N-1; ++i )
	{
	    for ( int j = 1; j < N-1; ++j )
	    {
		idx[0] = i + j*N;
		idx_iminus[0] = (i-1) + j*N;
		idx_iplus[0] = (i+1) + j*N;
		idx_jminus[0] = i + (j-1)*N;
		idx_jplus[0] = i + (j+1)*N;

		A->insertGlobalValues( idx[0], idx_jminus(), j_minus() );
		A->insertGlobalValues( idx[0], idx_iminus(), i_minus() );
		A->insertGlobalValues( idx[0], idx(),        diag()    );
		A->insertGlobalValues( idx[0], idx_iplus(),  i_plus()  );
		A->insertGlobalValues( idx[0], idx_jplus(),  j_plus()  );
	    }
	}
    }
    comm->barrier();

    A->fillComplete();

    // Build the solution vector.
    double X_val = 0.0;
    Teuchos::RCP<Tpetra::Vector<double,int> > X =
	Tpetra::createVector<double,int>( row_map );
    X->putScalar( X_val );

    // Build the right hand side.
    double B_val = 0.0;
    Teuchos::RCP<Tpetra::Vector<double,int> > B =
	Tpetra::createVector<double,int>( row_map );
    B->putScalar( B_val );

    // Set dirichlet boundary conditions.
    int row;
    // left
    for ( int j = 1; j < N-1; ++j )
    {
	int i = 0;
	row = i + j*N;
	if ( row_map->isNodeGlobalElement( row ) )
	{
	    B->replaceGlobalValue( row, 5.0 );
	}
    }
    // right
    for ( int j = 1; j < N-1; ++j )
    {
	int i = N-1;
	row = i + j*N;
	if ( row_map->isNodeGlobalElement( row ) )
	{
	    B->replaceGlobalValue( row, 5.0 );
	}
    }
    // bottom
    for ( int i = 0; i < N; ++i )
    {
	int j = 0;
	row = i + j*N;
	if ( row_map->isNodeGlobalElement( row ) )
	{
	    B->replaceGlobalValue( row, 0.0 );
	}
    }
    // top
    for ( int i = 0; i < N; ++i )
    {
	int j = N-1;
	row = i + j*N;
	if ( row_map->isNodeGlobalElement( row ) )
	{
	    B->replaceGlobalValue( row, 0.0 );
	}
    }

    // Build the linear problem.
    comm->barrier();
    Teuchos::RCP<Chimera::LinearProblem<double,int,int> > linear_problem =
	Teuchos::rcp( new Chimera::LinearProblem<double,int,int>( A, X, B ) );

    // Set the solver parameters.
    Teuchos::RCP<Teuchos::ParameterList> plist =
	Teuchos::rcp( new Teuchos::ParameterList() );
    plist->set<std::string>( "SOLVER TYPE",         "MCSA"    );
    plist->set<std::string>( "RNG TYPE",            "MT19937" );
    plist->set<double>(      "TOLERANCE",           1.0e-8    );
    plist->set<int>(         "MAX ITERS",           100       );
    plist->set<std::string>( "SPLIT TYPE",          "JACOBI"  );
    plist->set<std::string>( "MC TYPE",             "ADJOINT" );
    plist->set<double>(      "WEIGHT CUTOFF",       1.0e-4    );
    plist->set<int>(         "HISTORIES PER STAGE", 1000      );
    plist->set<int>(         "NUM OVERLAP",         0         );

    // Build the solver.
    Teuchos::RCP<Chimera::LinearSolver<double,int,int> > solver =
	Chimera::LinearSolverFactory::create( plist, linear_problem );

    // Solve.
    solver->iterate();

    // Check the solution vector.
    Teuchos::ArrayRCP<const double> X_view =
	linear_problem->getLHS()->get1dView();
    std::cout << X_view() << std::endl;
}

//---------------------------------------------------------------------------//
// end tstMCSA.cpp
//---------------------------------------------------------------------------//

<commit_msg>updating size of mcsa test<commit_after>//---------------------------------------------------------------------------//
/*!
 * \file tstMCSA.cpp
 * \author Stuart R. Slattery
 * \brief MCSA tests.
 */
//---------------------------------------------------------------------------//

#include <iostream>
#include <vector>
#include <cmath>
#include <cstdlib>
#include <sstream>
#include <algorithm>
#include <string>
#include <cassert>

#include <Chimera_LinearSolver.hpp>
#include <Chimera_LinearProblem.hpp>
#include <Chimera_LinearSolverFactory.hpp>

#include <Teuchos_UnitTestHarness.hpp>
#include <Teuchos_DefaultComm.hpp>
#include <Teuchos_CommHelpers.hpp>
#include <Teuchos_RCP.hpp>
#include <Teuchos_ArrayRCP.hpp>
#include <Teuchos_Array.hpp>
#include <Teuchos_OpaqueWrapper.hpp>
#include <Teuchos_TypeTraits.hpp>
#include <Teuchos_Tuple.hpp>
#include <Teuchos_ParameterList.hpp>

#include <Tpetra_Map.hpp>
#include <Tpetra_CrsMatrix.hpp>
#include <Tpetra_Vector.hpp>

//---------------------------------------------------------------------------//
// Tests
//---------------------------------------------------------------------------//
TEUCHOS_UNIT_TEST( MCSA, mcsa_test )
{
    // Setup parallel distribution.
    Teuchos::RCP<const Teuchos::Comm<int> > comm =
	Teuchos::DefaultComm<int>::getComm();

    // Build the linear operator - this is a 2D Transient Diffusion operator.
    int N = 50;
    int problem_size = N*N;
    double dx = 0.01;
    double dy = 0.01;
    double dt = 0.05;
    double alpha = 0.001;
    Teuchos::RCP<const Tpetra::Map<int> > row_map =
	Tpetra::createUniformContigMap<int,int>( problem_size, comm );
    Teuchos::RCP<Tpetra::CrsMatrix<double,int,int> > A =
	Tpetra::createCrsMatrix<double,int,int>( row_map, 3 );

    Teuchos::Array<double> diag( 1, 1.0 + 2*dt*alpha*( 1/(dx*dx) + 1/(dy*dy) ) );
    Teuchos::Array<double> i_minus( 1, -dt*alpha/(dx*dx) );
    Teuchos::Array<double> i_plus( 1, -dt*alpha/(dx*dx) );
    Teuchos::Array<double> j_minus( 1, -dt*alpha/(dy*dy) );
    Teuchos::Array<double> j_plus( 1, -dt*alpha/(dy*dy) );

    Teuchos::Array<int> idx(1);
    Teuchos::Array<int> idx_iminus(1);
    Teuchos::Array<int> idx_iplus(1);
    Teuchos::Array<int> idx_jminus(1);
    Teuchos::Array<int> idx_jplus(1);
    Teuchos::Array<double> one(1,1.0);

    if ( comm->getRank() == 0 )
    {
	// Min X boundary Dirichlet.
	for ( int j = 1; j < N-1; ++j )
	{
	    int i = 0;
	    idx[0] = i + j*N;
	    A->insertGlobalValues( idx[0], idx(), one() );
	}

	// Max X boundary Dirichlet.
	for ( int j = 1; j < N-1; ++j )
	{
	    int i = N-1;
	    idx[0] = i + j*N;
	    A->insertGlobalValues( idx[0], idx(), one() );
	}

	// Min Y boundary Dirichlet.
	for ( int i = 0; i < N; ++i )
	{
	    int j = 0;
	    idx[0] = i + j*N;
	    A->insertGlobalValues( idx[0], idx(), one() );
	}

	// Max Y boundary Dirichlet.
	for ( int i = 0; i < N; ++i )
	{
	    int j = N-1;
	    idx[0] = i + j*N;
	    A->insertGlobalValues( idx[0], idx(), one() );
	}

	// Central grid points.
	for ( int i = 1; i < N-1; ++i )
	{
	    for ( int j = 1; j < N-1; ++j )
	    {
		idx[0] = i + j*N;
		idx_iminus[0] = (i-1) + j*N;
		idx_iplus[0] = (i+1) + j*N;
		idx_jminus[0] = i + (j-1)*N;
		idx_jplus[0] = i + (j+1)*N;

		A->insertGlobalValues( idx[0], idx_jminus(), j_minus() );
		A->insertGlobalValues( idx[0], idx_iminus(), i_minus() );
		A->insertGlobalValues( idx[0], idx(),        diag()    );
		A->insertGlobalValues( idx[0], idx_iplus(),  i_plus()  );
		A->insertGlobalValues( idx[0], idx_jplus(),  j_plus()  );
	    }
	}
    }
    comm->barrier();

    A->fillComplete();

    // Build the solution vector.
    double X_val = 0.0;
    Teuchos::RCP<Tpetra::Vector<double,int> > X =
	Tpetra::createVector<double,int>( row_map );
    X->putScalar( X_val );

    // Build the right hand side.
    double B_val = 0.0;
    Teuchos::RCP<Tpetra::Vector<double,int> > B =
	Tpetra::createVector<double,int>( row_map );
    B->putScalar( B_val );

    // Set dirichlet boundary conditions.
    int row;
    // left
    for ( int j = 1; j < N-1; ++j )
    {
	int i = 0;
	row = i + j*N;
	if ( row_map->isNodeGlobalElement( row ) )
	{
	    B->replaceGlobalValue( row, 5.0 );
	}
    }
    // right
    for ( int j = 1; j < N-1; ++j )
    {
	int i = N-1;
	row = i + j*N;
	if ( row_map->isNodeGlobalElement( row ) )
	{
	    B->replaceGlobalValue( row, 5.0 );
	}
    }
    // bottom
    for ( int i = 0; i < N; ++i )
    {
	int j = 0;
	row = i + j*N;
	if ( row_map->isNodeGlobalElement( row ) )
	{
	    B->replaceGlobalValue( row, 0.0 );
	}
    }
    // top
    for ( int i = 0; i < N; ++i )
    {
	int j = N-1;
	row = i + j*N;
	if ( row_map->isNodeGlobalElement( row ) )
	{
	    B->replaceGlobalValue( row, 0.0 );
	}
    }

    // Build the linear problem.
    comm->barrier();
    Teuchos::RCP<Chimera::LinearProblem<double,int,int> > linear_problem =
	Teuchos::rcp( new Chimera::LinearProblem<double,int,int>( A, X, B ) );

    // Set the solver parameters.
    Teuchos::RCP<Teuchos::ParameterList> plist =
	Teuchos::rcp( new Teuchos::ParameterList() );
    plist->set<std::string>( "SOLVER TYPE",         "MCSA"    );
    plist->set<std::string>( "RNG TYPE",            "MT19937" );
    plist->set<double>(      "TOLERANCE",           1.0e-8    );
    plist->set<int>(         "MAX ITERS",           100       );
    plist->set<std::string>( "SPLIT TYPE",          "JACOBI"  );
    plist->set<std::string>( "MC TYPE",             "ADJOINT" );
    plist->set<double>(      "WEIGHT CUTOFF",       1.0e-4    );
    plist->set<int>(         "HISTORIES PER STAGE", 10000     );
    plist->set<int>(         "NUM OVERLAP",         20        );

    // Build the solver.
    Teuchos::RCP<Chimera::LinearSolver<double,int,int> > solver =
	Chimera::LinearSolverFactory::create( plist, linear_problem );

    // Solve.
    solver->iterate();

    // Check the solution vector.
    Teuchos::ArrayRCP<const double> X_view =
	linear_problem->getLHS()->get1dView();
    std::cout << X_view() << std::endl;
}

//---------------------------------------------------------------------------//
// end tstMCSA.cpp
//---------------------------------------------------------------------------//

<|endoftext|>