<commit_before>#include "CodeGen_Internal.h"
#include "Debug.h"

namespace Halide {
namespace Internal {

using std::string;
using std::map;
using std::vector;

using namespace llvm;

void Closure::visit(const Let *op) {
    op->value.accept(this);
    ignore.push(op->name, 0);
    op->body.accept(this);
    ignore.pop(op->name);
}

void Closure::visit(const LetStmt *op) {
    op->value.accept(this);
    ignore.push(op->name, 0);
    op->body.accept(this);
    ignore.pop(op->name);
}

void Closure::visit(const For *op) {
    ignore.push(op->name, 0);
    op->min.accept(this);
    op->extent.accept(this);
    op->body.accept(this);
    ignore.pop(op->name);
}

void Closure::visit(const Load *op) {
    op->index.accept(this);
    if (!ignore.contains(op->name)) {
        debug(3) << "Adding buffer " << op->name << " to closure\n";
        BufferRef & ref = buffers[op->name];
        ref.type = op->type; // TODO: Validate type is the same as existing refs?
        ref.read = true;

        // If reading an image/buffer, compute the size.
        if (op->image.defined()) {
            ref.dimensions = op->image.dimensions();
            ref.size = 1;
            for (int i = 0; i < op->image.dimensions(); i++) {
                ref.size += (op->image.extent(i) - 1)*op->image.stride(i);
            }
            ref.size *= op->image.type().bytes();
        }
    } else {
        debug(3) << "Not adding " << op->name << " to closure\n";
    }
}

void Closure::visit(const Store *op) {
    op->index.accept(this);
    op->value.accept(this);
    if (!ignore.contains(op->name)) {
        debug(3) << "Adding buffer " << op->name << " to closure\n";
        BufferRef & ref = buffers[op->name];
        ref.type = op->value.type(); // TODO: Validate type is the same as existing refs?
        // TODO: do we need to set ref.dimensions?
        ref.write = true;
    } else {
        debug(3) << "Not adding " << op->name << " to closure\n";
    }
}

void Closure::visit(const Allocate *op) {
    ignore.push(op->name, 0);
    for (size_t i = 0; i < op->extents.size(); i++) {
        op->extents[i].accept(this);
    }
    op->body.accept(this);
    ignore.pop(op->name);
}

void Closure::visit(const Variable *op) {
    if (ignore.contains(op->name)) {
        debug(3) << "Not adding " << op->name << " to closure\n";
    } else {
        debug(3) << "Adding " << op->name << " to closure\n";
        vars[op->name] = op->type;
    }
}

Closure::Closure(Stmt s, const string &loop_variable, llvm::StructType *buffer_t) : buffer_t(buffer_t) {
    ignore.push(loop_variable, 0);
    s.accept(this);
}

vector<llvm::Type*> Closure::llvm_types(LLVMContext *context) {
    vector<llvm::Type *> res;
    for (map<string, Type>::const_iterator iter = vars.begin(); iter != vars.end(); ++iter) {
        res.push_back(llvm_type_of(context, iter->second));
    }
    for (map<string, BufferRef>::const_iterator iter = buffers.begin(); iter != buffers.end(); ++iter) {
        res.push_back(llvm_type_of(context, iter->second.type)->getPointerTo());
        res.push_back(buffer_t->getPointerTo());
    }
    return res;
}

vector<string> Closure::names() {
    vector<string> res;
    for (map<string, Type>::const_iterator iter = vars.begin(); iter != vars.end(); ++iter) {
        debug(2) << "vars:  " << iter->first << "\n";
        res.push_back(iter->first);
    }
    for (map<string, BufferRef>::const_iterator iter = buffers.begin(); iter != buffers.end(); ++iter) {
        debug(2) << "buffers: " << iter->first << "\n";
        res.push_back(iter->first + ".host");
        res.push_back(iter->first + ".buffer");
    }
    return res;
}

StructType *Closure::build_type(LLVMContext *context) {
    StructType *struct_t = StructType::create(*context, "closure_t");
    struct_t->setBody(llvm_types(context), false);
    return struct_t;
}

void Closure::pack_struct(llvm::Type *type, Value *dst, const Scope<Value *> &src, IRBuilder<> *builder) {
    // type, type of dst should be a pointer to a struct of the type returned by build_type
    int idx = 0;
    LLVMContext &context = builder->getContext();
    vector<string> nm = names();
    vector<llvm::Type*> ty = llvm_types(&context);
    for (size_t i = 0; i < nm.size(); i++) {
#if LLVM_VERSION >= 37
        Value *ptr = builder->CreateConstInBoundsGEP2_32(type, dst, 0, idx);
#else
        Value *ptr = builder->CreateConstInBoundsGEP2_32(dst, 0, idx);
#endif
        Value *val;
        if (!ends_with(nm[i], ".buffer") || src.contains(nm[i])) {
            val = src.get(nm[i]);
            if (val->getType() != ty[i]) {
                val = builder->CreateBitCast(val, ty[i]);
            }
        } else {
            // Skip over buffers not in the symbol table. They must not be needed.
            val = ConstantPointerNull::get(buffer_t->getPointerTo());
        }
        builder->CreateStore(val, ptr);
        idx++;
    }
}

void Closure::unpack_struct(Scope<Value *> &dst,
                            llvm::Type *type,
                            Value *src,
                            IRBuilder<> *builder) {
    // type, type of src should be a pointer to a struct of the type returned by build_type
    int idx = 0;
    LLVMContext &context = builder->getContext();
    vector<string> nm = names();
    for (size_t i = 0; i < nm.size(); i++) {
#if LLVM_VERSION >= 37
        Value *ptr = builder->CreateConstInBoundsGEP2_32(type, src, 0, idx++);
#else
        Value *ptr = builder->CreateConstInBoundsGEP2_32(src, 0, idx++);
#endif
        LoadInst *load = builder->CreateLoad(ptr);
        if (load->getType()->isPointerTy()) {
            // Give it a unique type so that tbaa tells llvm that this can't alias anything
            load->setMetadata("tbaa", MDNode::get(context,
                                                  vec<LLVMMDNodeArgumentType>(MDString::get(context, nm[i]))));
        }
        dst.push(nm[i], load);
        load->setName(nm[i]);
    }
}

llvm::Type *llvm_type_of(LLVMContext *c, Halide::Type t) {
    if (t.width == 1) {
        if (t.is_float()) {
            switch (t.bits) {
            case 16:
                return llvm::Type::getHalfTy(*c);
            case 32:
                return llvm::Type::getFloatTy(*c);
            case 64:
                return llvm::Type::getDoubleTy(*c);
            default:
                internal_error << "There is no llvm type matching this floating-point bit width: " << t << "\n";
                return NULL;
            }
        } else if (t.is_handle()) {
            return llvm::Type::getInt8PtrTy(*c);
        } else {
            return llvm::Type::getIntNTy(*c, t.bits);
        }
    } else {
        llvm::Type *element_type = llvm_type_of(c, t.element_of());
        return VectorType::get(element_type, t.width);
    }
}

bool constant_allocation_size(const std::vector<Expr> &extents, const std::string &name, int32_t &size) {
    int64_t result = 1;

    for (size_t i = 0; i < extents.size(); i++) {
        if (const IntImm *int_size = extents[i].as<IntImm>()) {
            // Check if the individual dimension is > 2^31 - 1. Not
            // currently necessary because it's an int32_t, which is
            // always smaller than 2^31 - 1. If we ever upgrade the
            // type of IntImm but not the maximum allocation size, we
            // should re-enable this.
            /*
            if ((int64_t)int_size->value > (((int64_t)(1)<<31) - 1)) {
                user_error
                    << "Dimension " << i << " for allocation " << name << " has size " <<
                    int_size->value << " which is greater than 2^31 - 1.";
            }
            */
            result *= int_size->value;
            if (result > (static_cast<int64_t>(1)<<31) - 1) {
                user_error
                    << "Total size for allocation " << name
                    << " is constant but exceeds 2^31 - 1.\n";
            }
        } else {
            return false;
        }
    }

    size = static_cast<int32_t>(result);
    return true;
}

// Returns true if the given function name is one of the Halide runtime
// functions that takes a user_context pointer as its first parameter.
bool function_takes_user_context(const std::string &name) {
    static const char *user_context_runtime_funcs[] = {
        "halide_copy_to_host",
        "halide_copy_to_device",
        "halide_current_time_ns",
        "halide_debug_to_file",
        "halide_device_free",
        "halide_device_malloc",
        "halide_device_sync",
        "halide_do_par_for",
        "halide_do_task",
        "halide_error",
        "halide_free",
        "halide_malloc",
        "halide_print",
        "halide_profiling_timer",
        "halide_device_release",
        "halide_start_clock",
        "halide_trace",
        "halide_memoization_cache_lookup",
        "halide_memoization_cache_store",
        "halide_cuda_run",
        "halide_opencl_run",
        "halide_opengl_run",
        "halide_cuda_initialize_kernels",
        "halide_opencl_initialize_kernels",
        "halide_opengl_initialize_kernels",
        "halide_get_gpu_device",
    };
    const int num_funcs = sizeof(user_context_runtime_funcs) /
        sizeof(user_context_runtime_funcs[0]);
    for (int i = 0; i < num_funcs; ++i) {
        if (name == user_context_runtime_funcs[i]) {
            return true;
        }
    }
    return false;
}

}
}
<commit_msg>Remove unused name - put it under appropriate #if<commit_after>#include "CodeGen_Internal.h"
#include "Debug.h"

namespace Halide {
namespace Internal {

using std::string;
using std::map;
using std::vector;

using namespace llvm;

void Closure::visit(const Let *op) {
    op->value.accept(this);
    ignore.push(op->name, 0);
    op->body.accept(this);
    ignore.pop(op->name);
}

void Closure::visit(const LetStmt *op) {
    op->value.accept(this);
    ignore.push(op->name, 0);
    op->body.accept(this);
    ignore.pop(op->name);
}

void Closure::visit(const For *op) {
    ignore.push(op->name, 0);
    op->min.accept(this);
    op->extent.accept(this);
    op->body.accept(this);
    ignore.pop(op->name);
}

void Closure::visit(const Load *op) {
    op->index.accept(this);
    if (!ignore.contains(op->name)) {
        debug(3) << "Adding buffer " << op->name << " to closure\n";
        BufferRef & ref = buffers[op->name];
        ref.type = op->type; // TODO: Validate type is the same as existing refs?
        ref.read = true;

        // If reading an image/buffer, compute the size.
        if (op->image.defined()) {
            ref.dimensions = op->image.dimensions();
            ref.size = 1;
            for (int i = 0; i < op->image.dimensions(); i++) {
                ref.size += (op->image.extent(i) - 1)*op->image.stride(i);
            }
            ref.size *= op->image.type().bytes();
        }
    } else {
        debug(3) << "Not adding " << op->name << " to closure\n";
    }
}

void Closure::visit(const Store *op) {
    op->index.accept(this);
    op->value.accept(this);
    if (!ignore.contains(op->name)) {
        debug(3) << "Adding buffer " << op->name << " to closure\n";
        BufferRef & ref = buffers[op->name];
        ref.type = op->value.type(); // TODO: Validate type is the same as existing refs?
        // TODO: do we need to set ref.dimensions?
        ref.write = true;
    } else {
        debug(3) << "Not adding " << op->name << " to closure\n";
    }
}

void Closure::visit(const Allocate *op) {
    ignore.push(op->name, 0);
    for (size_t i = 0; i < op->extents.size(); i++) {
        op->extents[i].accept(this);
    }
    op->body.accept(this);
    ignore.pop(op->name);
}

void Closure::visit(const Variable *op) {
    if (ignore.contains(op->name)) {
        debug(3) << "Not adding " << op->name << " to closure\n";
    } else {
        debug(3) << "Adding " << op->name << " to closure\n";
        vars[op->name] = op->type;
    }
}

Closure::Closure(Stmt s, const string &loop_variable, llvm::StructType *buffer_t) : buffer_t(buffer_t) {
    ignore.push(loop_variable, 0);
    s.accept(this);
}

vector<llvm::Type*> Closure::llvm_types(LLVMContext *context) {
    vector<llvm::Type *> res;
    for (map<string, Type>::const_iterator iter = vars.begin(); iter != vars.end(); ++iter) {
        res.push_back(llvm_type_of(context, iter->second));
    }
    for (map<string, BufferRef>::const_iterator iter = buffers.begin(); iter != buffers.end(); ++iter) {
        res.push_back(llvm_type_of(context, iter->second.type)->getPointerTo());
        res.push_back(buffer_t->getPointerTo());
    }
    return res;
}

vector<string> Closure::names() {
    vector<string> res;
    for (map<string, Type>::const_iterator iter = vars.begin(); iter != vars.end(); ++iter) {
        debug(2) << "vars:  " << iter->first << "\n";
        res.push_back(iter->first);
    }
    for (map<string, BufferRef>::const_iterator iter = buffers.begin(); iter != buffers.end(); ++iter) {
        debug(2) << "buffers: " << iter->first << "\n";
        res.push_back(iter->first + ".host");
        res.push_back(iter->first + ".buffer");
    }
    return res;
}

StructType *Closure::build_type(LLVMContext *context) {
    StructType *struct_t = StructType::create(*context, "closure_t");
    struct_t->setBody(llvm_types(context), false);
    return struct_t;
}

void Closure::pack_struct(llvm::Type *
#if LLVM_VERSION >= 37
                          type
#endif
                          ,
                          Value *dst,
                          const Scope<Value *> &src,
                          IRBuilder<> *builder) {
    // type, type of dst should be a pointer to a struct of the type returned by build_type
    int idx = 0;
    LLVMContext &context = builder->getContext();
    vector<string> nm = names();
    vector<llvm::Type*> ty = llvm_types(&context);
    for (size_t i = 0; i < nm.size(); i++) {
#if LLVM_VERSION >= 37
        Value *ptr = builder->CreateConstInBoundsGEP2_32(type, dst, 0, idx);
#else
        Value *ptr = builder->CreateConstInBoundsGEP2_32(dst, 0, idx);
#endif
        Value *val;
        if (!ends_with(nm[i], ".buffer") || src.contains(nm[i])) {
            val = src.get(nm[i]);
            if (val->getType() != ty[i]) {
                val = builder->CreateBitCast(val, ty[i]);
            }
        } else {
            // Skip over buffers not in the symbol table. They must not be needed.
            val = ConstantPointerNull::get(buffer_t->getPointerTo());
        }
        builder->CreateStore(val, ptr);
        idx++;
    }
}

void Closure::unpack_struct(Scope<Value *> &dst,
                            llvm::Type *
#if LLVM_VERSION >= 37
                            type
#endif
                            ,
                            Value *src,
                            IRBuilder<> *builder) {
    // type, type of src should be a pointer to a struct of the type returned by build_type
    int idx = 0;
    LLVMContext &context = builder->getContext();
    vector<string> nm = names();
    for (size_t i = 0; i < nm.size(); i++) {
#if LLVM_VERSION >= 37
        Value *ptr = builder->CreateConstInBoundsGEP2_32(type, src, 0, idx++);
#else
        Value *ptr = builder->CreateConstInBoundsGEP2_32(src, 0, idx++);
#endif
        LoadInst *load = builder->CreateLoad(ptr);
        if (load->getType()->isPointerTy()) {
            // Give it a unique type so that tbaa tells llvm that this can't alias anything
            load->setMetadata("tbaa", MDNode::get(context,
                                                  vec<LLVMMDNodeArgumentType>(MDString::get(context, nm[i]))));
        }
        dst.push(nm[i], load);
        load->setName(nm[i]);
    }
}

llvm::Type *llvm_type_of(LLVMContext *c, Halide::Type t) {
    if (t.width == 1) {
        if (t.is_float()) {
            switch (t.bits) {
            case 16:
                return llvm::Type::getHalfTy(*c);
            case 32:
                return llvm::Type::getFloatTy(*c);
            case 64:
                return llvm::Type::getDoubleTy(*c);
            default:
                internal_error << "There is no llvm type matching this floating-point bit width: " << t << "\n";
                return NULL;
            }
        } else if (t.is_handle()) {
            return llvm::Type::getInt8PtrTy(*c);
        } else {
            return llvm::Type::getIntNTy(*c, t.bits);
        }
    } else {
        llvm::Type *element_type = llvm_type_of(c, t.element_of());
        return VectorType::get(element_type, t.width);
    }
}

bool constant_allocation_size(const std::vector<Expr> &extents, const std::string &name, int32_t &size) {
    int64_t result = 1;

    for (size_t i = 0; i < extents.size(); i++) {
        if (const IntImm *int_size = extents[i].as<IntImm>()) {
            // Check if the individual dimension is > 2^31 - 1. Not
            // currently necessary because it's an int32_t, which is
            // always smaller than 2^31 - 1. If we ever upgrade the
            // type of IntImm but not the maximum allocation size, we
            // should re-enable this.
            /*
            if ((int64_t)int_size->value > (((int64_t)(1)<<31) - 1)) {
                user_error
                    << "Dimension " << i << " for allocation " << name << " has size " <<
                    int_size->value << " which is greater than 2^31 - 1.";
            }
            */
            result *= int_size->value;
            if (result > (static_cast<int64_t>(1)<<31) - 1) {
                user_error
                    << "Total size for allocation " << name
                    << " is constant but exceeds 2^31 - 1.\n";
            }
        } else {
            return false;
        }
    }

    size = static_cast<int32_t>(result);
    return true;
}

// Returns true if the given function name is one of the Halide runtime
// functions that takes a user_context pointer as its first parameter.
bool function_takes_user_context(const std::string &name) {
    static const char *user_context_runtime_funcs[] = {
        "halide_copy_to_host",
        "halide_copy_to_device",
        "halide_current_time_ns",
        "halide_debug_to_file",
        "halide_device_free",
        "halide_device_malloc",
        "halide_device_sync",
        "halide_do_par_for",
        "halide_do_task",
        "halide_error",
        "halide_free",
        "halide_malloc",
        "halide_print",
        "halide_profiling_timer",
        "halide_device_release",
        "halide_start_clock",
        "halide_trace",
        "halide_memoization_cache_lookup",
        "halide_memoization_cache_store",
        "halide_cuda_run",
        "halide_opencl_run",
        "halide_opengl_run",
        "halide_cuda_initialize_kernels",
        "halide_opencl_initialize_kernels",
        "halide_opengl_initialize_kernels",
        "halide_get_gpu_device",
    };
    const int num_funcs = sizeof(user_context_runtime_funcs) /
        sizeof(user_context_runtime_funcs[0]);
    for (int i = 0; i < num_funcs; ++i) {
        if (name == user_context_runtime_funcs[i]) {
            return true;
        }
    }
    return false;
}

}
}
<|endoftext|>


<commit_before>#include "CodeGen_SPIR_Dev.h"
#include "IROperator.h"
#include <iostream>
#include "buffer_t.h"
#include "IRPrinter.h"
#include "IRMatch.h"
#include "Debug.h"
#include "Util.h"
#include "Var.h"
#include "Param.h"
#include "Target.h"
#include "integer_division_table.h"
#include "LLVM_Headers.h"

namespace Halide {
namespace Internal {

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

using namespace llvm;

CodeGen_SPIR_Dev::CodeGen_SPIR_Dev() : CodeGen() {
    #if !(WITH_SPIR)
    assert(false && "spir not enabled for this build of Halide.");
    #endif
}

void CodeGen_SPIR_Dev::compile(Stmt stmt, std::string name, const std::vector<Argument> &args) {

    // Now deduce the types of the arguments to our function
    vector<llvm::Type *> arg_types(args.size());
    for (size_t i = 0; i < args.size(); i++) {
        if (args[i].is_buffer) {
            arg_types[i] = llvm_type_of(UInt(8))->getPointerTo(1);
        } else {
            arg_types[i] = llvm_type_of(args[i].type);
        }
    }

    // Make our function
    function_name = name;
    FunctionType *func_t = FunctionType::get(void_t, arg_types, false);
    function = llvm::Function::Create(func_t, llvm::Function::ExternalLinkage, name, module);
    function->setCallingConv(llvm::CallingConv::SPIR_KERNEL);

    // Mark the buffer args as no alias
    for (size_t i = 0; i < args.size(); i++) {
        if (args[i].is_buffer) {
            function->setDoesNotAlias(i+1);
        }
    }

    // Make the initial basic block
    entry_block = BasicBlock::Create(*context, "entry", function);
    builder->SetInsertPoint(entry_block);

    // Put the arguments in the symbol table
    {
        size_t i = 0;
        for (llvm::Function::arg_iterator iter = function->arg_begin();
             iter != function->arg_end();
             iter++) {

            if (args[i].is_buffer) {
                // HACK: codegen expects a load from foo to use base
                // address 'foo.host', so we store the device pointer
                // as foo.host in this scope.
                sym_push(args[i].name + ".host", iter);
            } else {
                sym_push(args[i].name, iter);
            }
            iter->setName(args[i].name);

            i++;
        }
    }

    // We won't end the entry block yet, because we'll want to add
    // some allocas to it later if there are local allocations. Start
    // a new block to put all the code.
    BasicBlock *body_block = BasicBlock::Create(*context, "body", function);
    builder->SetInsertPoint(body_block);

    debug(1) << "Generating llvm bitcode...\n";
    // Ok, we have a module, function, context, and a builder
    // pointing at a brand new basic block. We're good to go.
    stmt.accept(this);

    // Now we need to end the function
    builder->CreateRetVoid();

    // Make the entry block point to the body block
    builder->SetInsertPoint(entry_block);
    builder->CreateBr(body_block);

    // Add the nvvm annotation that it is a kernel function.
    MDNode *mdNode = MDNode::get(*context, vec<Value *>(function));
    module->getOrInsertNamedMetadata("opencl.kernels")->addOperand(mdNode);

    // Now verify the function is ok
    verifyFunction(*function);

    // Finally, verify the module is ok
    verifyModule(*module);
    debug(2) << "Done generating llvm bitcode\n";
}

const std::string spirDataLayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v16:16:16-v24:32:32-v32:32:32-v48:64:64-v64:64:64-v96:128:128-v128:128:128-v192:256:256-v256:256:256-v512:512:512-v1024:1024:1024";
const std::string spir64DataLayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v16:16:16-v24:32:32-v32:32:32-v48:64:64-v64:64:64-v96:128:128-v128:128:128-v192:256:256-v256:256:256-v512:512:512-v1024:1024:1024";

void CodeGen_SPIR_Dev::init_module() {

    CodeGen::init_module();

    module = get_initial_module_for_spir_device(context);

    module->setTargetTriple(Triple::normalize(march()+"-unknown-unknown"));
    module->setDataLayout(spirDataLayout);

    // Fix the target triple
    debug(1) << "Target triple of initial module: " << module->getTargetTriple() << "\n";

    module->setModuleIdentifier("<halide_spir>");

    for(Module::iterator i = module->begin(); i != module->end(); ++i)
        i->setCallingConv(CallingConv::SPIR_FUNC);

    owns_module = true;
}

string CodeGen_SPIR_Dev::simt_intrinsic(const string &name) {
    if (ends_with(name, ".threadidx")) {
        return "halide.spir.lid.x";
    } else if (ends_with(name, ".threadidy")) {
        return "halide.spir.lid.y";
    } else if (ends_with(name, ".threadidz")) {
        return "halide.spir.lid.z";
    }
    //else if (ends_with(name, ".threadidw")) {
    //    return "halide.spir.lid.w";
    //}
    else if (ends_with(name, ".blockidx")) {
        return "halide.spir.gid.x";
    } else if (ends_with(name, ".blockidy")) {
        return "halide.spir.gid.y";
    } else if (ends_with(name, ".blockidz")) {
        return "halide.spir.gid.z";
    }
    //else if (ends_with(name, ".blockidw")) {
    //    return "halide.spir.gid.w";
    //}
    assert(false && "simt_intrinsic called on bad variable name");
}

void CodeGen_SPIR_Dev::visit(const For *loop) {
    if (is_gpu_var(loop->name)) {
        debug(2) << "Dropping loop " << loop->name << " (" << loop->min << ", " << loop->extent << ")\n";
        assert(loop->for_type == For::Parallel && "kernel loop must be parallel");

        Expr simt_idx = Call::make(Int(32), simt_intrinsic(loop->name), std::vector<Expr>(), Call::Extern);
        Expr loop_var = loop->min + simt_idx;
        Expr cond = simt_idx < loop->extent;
        debug(3) << "for -> if (" << cond << ")\n";

        BasicBlock *loop_bb = BasicBlock::Create(*context, loop->name + "_loop", function);
        BasicBlock *after_bb = BasicBlock::Create(*context, loop->name + "_after_loop", function);

        builder->CreateCondBr(codegen(cond), loop_bb, after_bb);
        builder->SetInsertPoint(loop_bb);

        sym_push(loop->name, codegen(loop_var));
        codegen(loop->body);
        sym_pop(loop->name);

        builder->CreateBr(after_bb);
        builder->SetInsertPoint(after_bb);
    } else {
        CodeGen::visit(loop);
    }
}

void CodeGen_SPIR_Dev::visit(const Pipeline *n) {
    n->produce.accept(this);

    // Grab the syncthreads intrinsic, or declare it if it doesn't exist yet
    llvm::Function *barrier = module->getFunction("halide.spir.barrier");

    if (n->update.defined()) {
        // If we're producing into shared or global memory we need a
        // syncthreads before continuing.
        builder->CreateCall(barrier, std::vector<Value *>());
        n->update.accept(this);
    }

    builder->CreateCall(barrier, std::vector<Value *>());
    n->consume.accept(this);
}

void CodeGen_SPIR_Dev::visit(const Allocate *alloc) {

    debug(1) << "Allocate " << alloc->name << " on device\n";

    llvm::Type *llvm_type = llvm_type_of(alloc->type);

    string allocation_name = alloc->name + ".host";
    debug(3) << "Pushing allocation called " << allocation_name << " onto the symbol table\n";

    // If this is a shared allocation, there should already be a
    // pointer into shared memory in the symbol table.
    Value *ptr;
    Value *offset = sym_get(alloc->name + ".shared_mem", false);

    if (offset) {
        // Bit-cast it to a shared memory pointer (address-space 3 is shared memory)
        ptr = builder->CreateIntToPtr(offset, PointerType::get(llvm_type, 3));
    } else {
        // Otherwise jump back to the entry and generate an
        // alloca. Note that by jumping back we're rendering any
        // expression we carry back meaningless, so we had better only
        // be dealing with constants here.
        const IntImm *size = alloc->size.as<IntImm>();
        assert(size && "Only fixed-size allocations are supported on the gpu. Try storing into shared memory instead.");

        BasicBlock *here = builder->GetInsertBlock();

        builder->SetInsertPoint(entry_block);
        ptr = builder->CreateAlloca(llvm_type_of(alloc->type), ConstantInt::get(i32, size->value));
        builder->SetInsertPoint(here);
    }

    sym_push(allocation_name, ptr);
    codegen(alloc->body);

}

void CodeGen_SPIR_Dev::visit(const Free *f) {
    sym_pop(f->name + ".host");
}

string CodeGen_SPIR_Dev::march() const {
    return "spir";
}

string CodeGen_SPIR_Dev::mcpu() const {
    return "unknown";
}

string CodeGen_SPIR_Dev::mattrs() const {
    return "unknown";
}

bool CodeGen_SPIR_Dev::use_soft_float_abi() const {
    return false;
}

vector<char> CodeGen_SPIR_Dev::compile_to_src() {

    // Optimize it - this really only optimizes the current function
    optimize_module();

    SmallVector<char, 1024> buffer;
    raw_svector_ostream stream(buffer);
    WriteBitcodeToFile(module, stream);
    stream.flush();
    return vector<char>(buffer.begin(), buffer.end());
}

string CodeGen_SPIR_Dev::get_current_kernel_name() {
    return function->getName();
}

void CodeGen_SPIR_Dev::dump() {
    module->dump();
}

}}
<commit_msg>Fixed optimize_module call for SPIR dev code<commit_after>#include "CodeGen_SPIR_Dev.h"
#include "IROperator.h"
#include <iostream>
#include "buffer_t.h"
#include "IRPrinter.h"
#include "IRMatch.h"
#include "Debug.h"
#include "Util.h"
#include "Var.h"
#include "Param.h"
#include "Target.h"
#include "integer_division_table.h"
#include "LLVM_Headers.h"

namespace Halide {
namespace Internal {

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

using namespace llvm;

CodeGen_SPIR_Dev::CodeGen_SPIR_Dev() : CodeGen() {
    #if !(WITH_SPIR)
    assert(false && "spir not enabled for this build of Halide.");
    #endif
}

void CodeGen_SPIR_Dev::compile(Stmt stmt, std::string name, const std::vector<Argument> &args) {

    // Now deduce the types of the arguments to our function
    vector<llvm::Type *> arg_types(args.size());
    for (size_t i = 0; i < args.size(); i++) {
        if (args[i].is_buffer) {
            arg_types[i] = llvm_type_of(UInt(8))->getPointerTo(1);
        } else {
            arg_types[i] = llvm_type_of(args[i].type);
        }
    }

    // Make our function
    function_name = name;
    FunctionType *func_t = FunctionType::get(void_t, arg_types, false);
    function = llvm::Function::Create(func_t, llvm::Function::ExternalLinkage, name, module);
    function->setCallingConv(llvm::CallingConv::SPIR_KERNEL);

    // Mark the buffer args as no alias
    for (size_t i = 0; i < args.size(); i++) {
        if (args[i].is_buffer) {
            function->setDoesNotAlias(i+1);
        }
    }

    // Make the initial basic block
    entry_block = BasicBlock::Create(*context, "entry", function);
    builder->SetInsertPoint(entry_block);

    // Put the arguments in the symbol table
    {
        size_t i = 0;
        for (llvm::Function::arg_iterator iter = function->arg_begin();
             iter != function->arg_end();
             iter++) {

            if (args[i].is_buffer) {
                // HACK: codegen expects a load from foo to use base
                // address 'foo.host', so we store the device pointer
                // as foo.host in this scope.
                sym_push(args[i].name + ".host", iter);
            } else {
                sym_push(args[i].name, iter);
            }
            iter->setName(args[i].name);

            i++;
        }
    }

    // We won't end the entry block yet, because we'll want to add
    // some allocas to it later if there are local allocations. Start
    // a new block to put all the code.
    BasicBlock *body_block = BasicBlock::Create(*context, "body", function);
    builder->SetInsertPoint(body_block);

    debug(1) << "Generating llvm bitcode...\n";
    // Ok, we have a module, function, context, and a builder
    // pointing at a brand new basic block. We're good to go.
    stmt.accept(this);

    // Now we need to end the function
    builder->CreateRetVoid();

    // Make the entry block point to the body block
    builder->SetInsertPoint(entry_block);
    builder->CreateBr(body_block);

    // Add the nvvm annotation that it is a kernel function.
    MDNode *mdNode = MDNode::get(*context, vec<Value *>(function));
    module->getOrInsertNamedMetadata("opencl.kernels")->addOperand(mdNode);

    // Now verify the function is ok
    verifyFunction(*function);

    // Finally, verify the module is ok
    verifyModule(*module);
    debug(2) << "Done generating llvm bitcode\n";
}

const std::string spirDataLayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v16:16:16-v24:32:32-v32:32:32-v48:64:64-v64:64:64-v96:128:128-v128:128:128-v192:256:256-v256:256:256-v512:512:512-v1024:1024:1024";
const std::string spir64DataLayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v16:16:16-v24:32:32-v32:32:32-v48:64:64-v64:64:64-v96:128:128-v128:128:128-v192:256:256-v256:256:256-v512:512:512-v1024:1024:1024";

void CodeGen_SPIR_Dev::init_module() {

    CodeGen::init_module();

    module = get_initial_module_for_spir_device(context);

    module->setTargetTriple(Triple::normalize(march()+"-unknown-unknown"));
    module->setDataLayout(spirDataLayout);

    // Fix the target triple
    debug(1) << "Target triple of initial module: " << module->getTargetTriple() << "\n";

    module->setModuleIdentifier("<halide_spir>");

    for(Module::iterator i = module->begin(); i != module->end(); ++i)
        i->setCallingConv(CallingConv::SPIR_FUNC);

    owns_module = true;
}

string CodeGen_SPIR_Dev::simt_intrinsic(const string &name) {
    if (ends_with(name, ".threadidx")) {
        return "halide.spir.lid.x";
    } else if (ends_with(name, ".threadidy")) {
        return "halide.spir.lid.y";
    } else if (ends_with(name, ".threadidz")) {
        return "halide.spir.lid.z";
    }
    //else if (ends_with(name, ".threadidw")) {
    //    return "halide.spir.lid.w";
    //}
    else if (ends_with(name, ".blockidx")) {
        return "halide.spir.gid.x";
    } else if (ends_with(name, ".blockidy")) {
        return "halide.spir.gid.y";
    } else if (ends_with(name, ".blockidz")) {
        return "halide.spir.gid.z";
    }
    //else if (ends_with(name, ".blockidw")) {
    //    return "halide.spir.gid.w";
    //}
    assert(false && "simt_intrinsic called on bad variable name");
}

void CodeGen_SPIR_Dev::visit(const For *loop) {
    if (is_gpu_var(loop->name)) {
        debug(2) << "Dropping loop " << loop->name << " (" << loop->min << ", " << loop->extent << ")\n";
        assert(loop->for_type == For::Parallel && "kernel loop must be parallel");

        Expr simt_idx = Call::make(Int(32), simt_intrinsic(loop->name), std::vector<Expr>(), Call::Extern);
        Expr loop_var = loop->min + simt_idx;
        Expr cond = simt_idx < loop->extent;
        debug(3) << "for -> if (" << cond << ")\n";

        BasicBlock *loop_bb = BasicBlock::Create(*context, loop->name + "_loop", function);
        BasicBlock *after_bb = BasicBlock::Create(*context, loop->name + "_after_loop", function);

        builder->CreateCondBr(codegen(cond), loop_bb, after_bb);
        builder->SetInsertPoint(loop_bb);

        sym_push(loop->name, codegen(loop_var));
        codegen(loop->body);
        sym_pop(loop->name);

        builder->CreateBr(after_bb);
        builder->SetInsertPoint(after_bb);
    } else {
        CodeGen::visit(loop);
    }
}

void CodeGen_SPIR_Dev::visit(const Pipeline *n) {
    n->produce.accept(this);

    // Grab the syncthreads intrinsic, or declare it if it doesn't exist yet
    llvm::Function *barrier = module->getFunction("halide.spir.barrier");

    if (n->update.defined()) {
        // If we're producing into shared or global memory we need a
        // syncthreads before continuing.
        builder->CreateCall(barrier, std::vector<Value *>());
        n->update.accept(this);
    }

    builder->CreateCall(barrier, std::vector<Value *>());
    n->consume.accept(this);
}

void CodeGen_SPIR_Dev::visit(const Allocate *alloc) {

    debug(1) << "Allocate " << alloc->name << " on device\n";

    llvm::Type *llvm_type = llvm_type_of(alloc->type);

    string allocation_name = alloc->name + ".host";
    debug(3) << "Pushing allocation called " << allocation_name << " onto the symbol table\n";

    // If this is a shared allocation, there should already be a
    // pointer into shared memory in the symbol table.
    Value *ptr;
    Value *offset = sym_get(alloc->name + ".shared_mem", false);

    if (offset) {
        // Bit-cast it to a shared memory pointer (address-space 3 is shared memory)
        ptr = builder->CreateIntToPtr(offset, PointerType::get(llvm_type, 3));
    } else {
        // Otherwise jump back to the entry and generate an
        // alloca. Note that by jumping back we're rendering any
        // expression we carry back meaningless, so we had better only
        // be dealing with constants here.
        const IntImm *size = alloc->size.as<IntImm>();
        assert(size && "Only fixed-size allocations are supported on the gpu. Try storing into shared memory instead.");

        BasicBlock *here = builder->GetInsertBlock();

        builder->SetInsertPoint(entry_block);
        ptr = builder->CreateAlloca(llvm_type_of(alloc->type), ConstantInt::get(i32, size->value));
        builder->SetInsertPoint(here);
    }

    sym_push(allocation_name, ptr);
    codegen(alloc->body);

    // Optimize it - this really only optimizes the current function
    optimize_module();
}

void CodeGen_SPIR_Dev::visit(const Free *f) {
    sym_pop(f->name + ".host");
}

string CodeGen_SPIR_Dev::march() const {
    return "spir";
}

string CodeGen_SPIR_Dev::mcpu() const {
    return "unknown";
}

string CodeGen_SPIR_Dev::mattrs() const {
    return "unknown";
}

bool CodeGen_SPIR_Dev::use_soft_float_abi() const {
    return false;
}

vector<char> CodeGen_SPIR_Dev::compile_to_src() {

    SmallVector<char, 1024> buffer;
    raw_svector_ostream stream(buffer);
    WriteBitcodeToFile(module, stream);
    stream.flush();
    return vector<char>(buffer.begin(), buffer.end());
}

string CodeGen_SPIR_Dev::get_current_kernel_name() {
    return function->getName();
}

void CodeGen_SPIR_Dev::dump() {
    module->dump();
}

}}
<|endoftext|>


<commit_before>/**************************************************************************
 * Copyright(c) 1998-2003, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

//-----------------------------------------------------------------
//           Implementation of the Primary Vertex class
//           for the Event Data Summary class
//           This class contains the Primary Vertex
//           of the event coming from reconstruction
// Origin: A.Dainese, Padova, andrea.dainese@pd.infn.it
//-----------------------------------------------------------------

//---- standard headers ----
#include "Riostream.h"
//---- Root headers --------
#include <TMath.h>
#include <TROOT.h>
//---- AliRoot headers -----
#include "AliESDVertex.h"

ClassImp(AliESDVertex)

//--------------------------------------------------------------------------
AliESDVertex::AliESDVertex() :
  AliVertex(),
  fCovXX(0.005*0.005),
  fCovXY(0),
  fCovYY(0.005*0.005),
  fCovXZ(0),
  fCovYZ(0),
  fCovZZ(5.3*5.3),
  fChi2(0)
{
  //
  // Default Constructor, set everything to 0
  //
  SetToZero();
}

//--------------------------------------------------------------------------
AliESDVertex::AliESDVertex(Double_t positionZ,Double_t sigmaZ,
			   Int_t nContributors,const Char_t *vtxName) :
  AliVertex(),
  fCovXX(0.005*0.005),
  fCovXY(0),
  fCovYY(0.005*0.005),
  fCovXZ(0),
  fCovYZ(0),
  fCovZZ(sigmaZ*sigmaZ),
  fChi2(0)
{
  //
  // Constructor for vertex Z from pixels
  //

  SetToZero();

  fPosition[2]   = positionZ;
  SetName(vtxName);
  SetNContributors(nContributors);

}

//-------------------------------------------------------------------------
AliESDVertex::AliESDVertex(Double_t position[3],Double_t covmatrix[6],
			   Double_t chi2,Int_t nContributors,
			   const Char_t *vtxName) :
  AliVertex(position,0.,nContributors),
  fCovXX(covmatrix[0]),
  fCovXY(covmatrix[1]),
  fCovYY(covmatrix[2]),
  fCovXZ(covmatrix[3]),
  fCovYZ(covmatrix[4]),
  fCovZZ(covmatrix[5]),
  fChi2(chi2)
{
  //
  // Constructor for vertex in 3D from tracks
  //

  SetToZero();
  SetName(vtxName);

}
//--------------------------------------------------------------------------
AliESDVertex::AliESDVertex(Double_t position[3],Double_t sigma[3],
			   const Char_t *vtxName) :
  AliVertex(position,0.,0),
  fCovXX(sigma[0]*sigma[0]),
  fCovXY(0),
  fCovYY(sigma[1]*sigma[1]),
  fCovXZ(0),
  fCovYZ(0),
  fCovZZ(sigma[2]*sigma[2]),
  fChi2(0)
{
  //
  // Constructor for smearing of true position
  //

  SetToZero();
  SetName(vtxName);

}
//--------------------------------------------------------------------------
AliESDVertex::AliESDVertex(Double_t position[3],Double_t sigma[3],
			   Double_t snr[3], const Char_t *vtxName) :
  AliVertex(position,0.,0),
  fCovXX(sigma[0]*sigma[0]),
  fCovXY(0),
  fCovYY(sigma[1]*sigma[1]),
  fCovXZ(0),
  fCovYZ(0),
  fCovZZ(sigma[2]*sigma[2]),
  fChi2(0)
{
  //
  // Constructor for Pb-Pb
  //

  SetToZero();
  SetName(vtxName);

  fSNR[0]        = snr[0];
  fSNR[1]        = snr[1];
  fSNR[2]        = snr[2];

}

//--------------------------------------------------------------------------
void AliESDVertex::SetToZero() {
  //
  // Set the content of arrays to 0. Used by constructors
  //
  for(Int_t i=0; i<3; i++){
    fTruePos[i] = 0;
    fSNR[i] = 0.;
  }
}
//--------------------------------------------------------------------------
void AliESDVertex::GetSigmaXYZ(Double_t sigma[3]) const {
//
// Return errors on vertex position in thrust frame
//
  sigma[0] = TMath::Sqrt(fCovXX);
  sigma[1] = TMath::Sqrt(fCovYY);
  sigma[2] = TMath::Sqrt(fCovZZ);

  return;
}
//--------------------------------------------------------------------------
void AliESDVertex::GetCovMatrix(Double_t covmatrix[6]) const {
//
// Return covariance matrix of the vertex
//
  covmatrix[0] = fCovXX;
  covmatrix[1] = fCovXY;
  covmatrix[2] = fCovYY;
  covmatrix[3] = fCovXZ;
  covmatrix[4] = fCovYZ;
  covmatrix[5] = fCovZZ;

  return;
}

//--------------------------------------------------------------------------
void AliESDVertex::GetSNR(Double_t snr[3]) const {
//
// Return S/N ratios
//
  for(Int_t i=0;i<3;i++) snr[i] = fSNR[i];

  return;
}
//--------------------------------------------------------------------------
void AliESDVertex::Print(Option_t* /*option*/) const {
//
// Print out information on all data members
//
  printf("ESD vertex position:\n");
  printf("   x = %f +- %f\n",fPosition[0],TMath::Sqrt(fCovXX));
  printf("   y = %f +- %f\n",fPosition[1],TMath::Sqrt(fCovYY));
  printf("   z = %f +- %f\n",fPosition[2],TMath::Sqrt(fCovZZ));
  printf(" Covariance matrix:\n");
  printf(" %12.10f  %12.10f  %12.10f\n %12.10f  %12.10f  %12.10f\n %12.10f  %12.10f  %12.10f\n",fCovXX,fCovXY,fCovXZ,fCovXY,fCovYY,fCovYZ,fCovXZ,fCovYZ,fCovZZ);
  printf(" S/N = (%f, %f, %f)\n",fSNR[0],fSNR[1],fSNR[2]);
  printf(" chi2 = %f\n",fChi2);
  printf(" # tracks (or tracklets) = %d\n",fNContributors);

  printf(" True vertex position - for comparison: %12.10f  %12.10f  %12.10f\n ",fTruePos[0],fTruePos[1],fTruePos[2]);

  return;
}

<commit_msg>Corrected comment (Andrea)<commit_after>/**************************************************************************
 * Copyright(c) 1998-2003, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

//-----------------------------------------------------------------
//           Implementation of the Primary Vertex class
//           for the Event Data Summary class
//           This class contains the Primary Vertex
//           of the event coming from reconstruction
// Origin: A.Dainese, Padova, andrea.dainese@pd.infn.it
//-----------------------------------------------------------------

//---- standard headers ----
#include "Riostream.h"
//---- Root headers --------
#include <TMath.h>
#include <TROOT.h>
//---- AliRoot headers -----
#include "AliESDVertex.h"

ClassImp(AliESDVertex)

//--------------------------------------------------------------------------
AliESDVertex::AliESDVertex() :
  AliVertex(),
  fCovXX(0.005*0.005),
  fCovXY(0),
  fCovYY(0.005*0.005),
  fCovXZ(0),
  fCovYZ(0),
  fCovZZ(5.3*5.3),
  fChi2(0)
{
  //
  // Default Constructor, set everything to 0
  //
  SetToZero();
}

//--------------------------------------------------------------------------
AliESDVertex::AliESDVertex(Double_t positionZ,Double_t sigmaZ,
			   Int_t nContributors,const Char_t *vtxName) :
  AliVertex(),
  fCovXX(0.005*0.005),
  fCovXY(0),
  fCovYY(0.005*0.005),
  fCovXZ(0),
  fCovYZ(0),
  fCovZZ(sigmaZ*sigmaZ),
  fChi2(0)
{
  //
  // Constructor for vertex Z from pixels
  //

  SetToZero();

  fPosition[2]   = positionZ;
  SetName(vtxName);
  SetNContributors(nContributors);

}

//-------------------------------------------------------------------------
AliESDVertex::AliESDVertex(Double_t position[3],Double_t covmatrix[6],
			   Double_t chi2,Int_t nContributors,
			   const Char_t *vtxName) :
  AliVertex(position,0.,nContributors),
  fCovXX(covmatrix[0]),
  fCovXY(covmatrix[1]),
  fCovYY(covmatrix[2]),
  fCovXZ(covmatrix[3]),
  fCovYZ(covmatrix[4]),
  fCovZZ(covmatrix[5]),
  fChi2(chi2)
{
  //
  // Constructor for vertex in 3D from tracks
  //

  SetToZero();
  SetName(vtxName);

}
//--------------------------------------------------------------------------
AliESDVertex::AliESDVertex(Double_t position[3],Double_t sigma[3],
			   const Char_t *vtxName) :
  AliVertex(position,0.,0),
  fCovXX(sigma[0]*sigma[0]),
  fCovXY(0),
  fCovYY(sigma[1]*sigma[1]),
  fCovXZ(0),
  fCovYZ(0),
  fCovZZ(sigma[2]*sigma[2]),
  fChi2(0)
{
  //
  // Constructor for smearing of true position
  //

  SetToZero();
  SetName(vtxName);

}
//--------------------------------------------------------------------------
AliESDVertex::AliESDVertex(Double_t position[3],Double_t sigma[3],
			   Double_t snr[3], const Char_t *vtxName) :
  AliVertex(position,0.,0),
  fCovXX(sigma[0]*sigma[0]),
  fCovXY(0),
  fCovYY(sigma[1]*sigma[1]),
  fCovXZ(0),
  fCovYZ(0),
  fCovZZ(sigma[2]*sigma[2]),
  fChi2(0)
{
  //
  // Constructor for Pb-Pb
  //

  SetToZero();
  SetName(vtxName);

  fSNR[0]        = snr[0];
  fSNR[1]        = snr[1];
  fSNR[2]        = snr[2];

}

//--------------------------------------------------------------------------
void AliESDVertex::SetToZero() {
  //
  // Set the content of arrays to 0. Used by constructors
  //
  for(Int_t i=0; i<3; i++){
    fTruePos[i] = 0;
    fSNR[i] = 0.;
  }
}
//--------------------------------------------------------------------------
void AliESDVertex::GetSigmaXYZ(Double_t sigma[3]) const {
//
// Return errors on vertex position
//
  sigma[0] = TMath::Sqrt(fCovXX);
  sigma[1] = TMath::Sqrt(fCovYY);
  sigma[2] = TMath::Sqrt(fCovZZ);

  return;
}
//--------------------------------------------------------------------------
void AliESDVertex::GetCovMatrix(Double_t covmatrix[6]) const {
//
// Return covariance matrix of the vertex
//
  covmatrix[0] = fCovXX;
  covmatrix[1] = fCovXY;
  covmatrix[2] = fCovYY;
  covmatrix[3] = fCovXZ;
  covmatrix[4] = fCovYZ;
  covmatrix[5] = fCovZZ;

  return;
}

//--------------------------------------------------------------------------
void AliESDVertex::GetSNR(Double_t snr[3]) const {
//
// Return S/N ratios
//
  for(Int_t i=0;i<3;i++) snr[i] = fSNR[i];

  return;
}
//--------------------------------------------------------------------------
void AliESDVertex::Print(Option_t* /*option*/) const {
//
// Print out information on all data members
//
  printf("ESD vertex position:\n");
  printf("   x = %f +- %f\n",fPosition[0],TMath::Sqrt(fCovXX));
  printf("   y = %f +- %f\n",fPosition[1],TMath::Sqrt(fCovYY));
  printf("   z = %f +- %f\n",fPosition[2],TMath::Sqrt(fCovZZ));
  printf(" Covariance matrix:\n");
  printf(" %12.10f  %12.10f  %12.10f\n %12.10f  %12.10f  %12.10f\n %12.10f  %12.10f  %12.10f\n",fCovXX,fCovXY,fCovXZ,fCovXY,fCovYY,fCovYZ,fCovXZ,fCovYZ,fCovZZ);
  printf(" S/N = (%f, %f, %f)\n",fSNR[0],fSNR[1],fSNR[2]);
  printf(" chi2 = %f\n",fChi2);
  printf(" # tracks (or tracklets) = %d\n",fNContributors);

  printf(" True vertex position - for comparison: %12.10f  %12.10f  %12.10f\n ",fTruePos[0],fTruePos[1],fTruePos[2]);

  return;
}

<|endoftext|>


<commit_before>// Edit : rewritten for cURLpp 0.7.3
// Note : namespace changed, was cURLpp in 0.7.2 ...

#include <curlpp/cURLpp.hpp>
#include <curlpp/Options.hpp>

// RAII cleanup

curlpp::Cleanup myCleanup;

// Send request and get a result.
// Here I use a shortcut to get it in a string stream ...

std::ostringstream os;
os << curlpp::options::Url(std::string("http://www.wikipedia.org"));

string asAskedInQuestion = os.str();<commit_msg>please work ó.ò<commit_after>#include <CkHttp.h>
#include <CkString.h>

CkHttp http;
CkString html;
html = http.quickGetStr("http://www.w3.org/Protocols/");

printf("%s\n",(const char *)html);<|endoftext|>


<commit_before>//
//  JdEnvironment.h
//  Jigidesign
//
//  Created by Steven Massey on 8/24/16.
//  Copyright © 2016 Jigidesign. All rights reserved.
//

#ifndef JdEnvironment_h
#define JdEnvironment_h

//#include "JdLibraryManager.h"
#include "JdServer.h"
#include "JdLibraryFactory.h"

#include "IJdBroadcaster.h"
#include "IJdTimers.h"

class JdEnvironment
{
	public:

	JdEnvironment				(bool i_enableTimers = false, bool i_deferSetup = true)
	:
	m_server					(m_libraries),
	m_timersEnabled				(i_enableTimers)
	{
		if (not i_deferSetup)
			Setup ();
	}

	virtual ~ JdEnvironment		()
	{
		Teardown ();
	}

	void DisableModules (cstr_t i_disabledModules)
	{
		if (i_disabledModules)
			m_disabledModules = Jd::SplitString (i_disabledModules, ",");
	}

	JdResult Setup (EpigramRef i_configuration = Epigram ())
	{
		JdResult result;

		if (not m_initialized)
		{
			result = m_server.Setup ();

			if (not result)
			{
				m_libraries.ParseLibraries (& JdLibraryFactory::Get ());

				if (i_configuration)
					m_server.SetConfiguration (i_configuration);

				for (auto moduleName : m_disabledModules)
				{
					//epilog_(normal,  "disable: %s", epistr (moduleName));

					m_libraries.DisableModule (moduleName);
				}

				if (m_timersEnabled)
				{
					try
					{
//						jd_broadcaster.Bind (& m_server); // This is the notification delivery module
						jd_timers.Bind (& m_server);
					}

					catch (...)
					{

					}

//					auto timers = JdPlatform::Get <IJdPlatform::Notification> ();
//					m_timer = timers->ScheduleTimer (10, this, 0);
				}

				auto scheduler = m_server.GetScheduler ();

				if (m_timersEnabled)
				{
					auto driver = jd_timers.Cast <IJdTimerDriver> ();

					scheduler->AddTimerThread (driver);
				}
//				else
//				scheduler->AddThreads (1);

				scheduler->Start ();

				m_initialized = true;
			}
		}

		return result;
	}

	void Teardown ()
	{
		JdResult result;

		if (m_timersEnabled)
		{
			jd_lock (jd_timers)
			{
				jd_timers->StopAllTimers ();
			}
		}

		jd_timers.Release ();

		result = m_server.GetScheduler()->Teardown ();

		m_server.Teardown ();

#if FIX
		jd_broadcaster.ForceRelease ();	// teardown broadcaster last
#endif

		m_server.Teardown (true);

		m_initialized = false;
	}

	void  			RunMainThread			(f64 i_maxDurationInSeconds);
	void  			RunMainLoop				(f64 i_durationInSeconds);

	operator IJdModuleServer		()
	{
		return & m_server;
	}

	//	IJdModuleServer					GetServer					() { return & m_server; }

	protected ://------------------------------------------------------------------------------------------------------

	vector <string>					m_disabledModules;

	JdLibrarian						m_libraries;

	JdServer						m_server;

	IJdBroadcaster					jd_broadcaster;
	IJdTimers						jd_timers;

	bool							m_timersEnabled				= false;
	bool							m_initialized				= false;
};

struct JdLinkBasic		{ static void Setup (); };
struct JdLinkSimple		{ static void Setup (); };

#endif /* JdEnvironment_h */
<commit_msg>no message<commit_after>//
//  JdEnvironment.h
//  Jigidesign
//
//  Created by Steven Massey on 8/24/16.
//  Copyright © 2016 Jigidesign. All rights reserved.
//

#ifndef JdEnvironment_h
#define JdEnvironment_h

//#include "JdLibraryManager.h"
#include "JdServer.h"
#include "JdLibraryFactory.h"

#include "IJdBroadcaster.h"
#include "IJdTimers.h"

class JdEnvironment
{
	public:

	JdEnvironment				(bool i_enableTimers = false, bool i_deferSetup = false)
	:
	m_server					(m_libraries),
	m_timersEnabled				(i_enableTimers)
	{
		if (not i_deferSetup)
			Setup ();
	}

	virtual ~ JdEnvironment		()
	{
		Teardown ();
	}

	void DisableModules (cstr_t i_disabledModules)
	{
		if (i_disabledModules)
			m_disabledModules = Jd::SplitString (i_disabledModules, ",");
	}

	JdResult Setup (EpigramRef i_configuration = Epigram ())
	{
		JdResult result;

		if (not m_initialized)
		{
			result = m_server.Setup ();

			if (not result)
			{
				m_libraries.ParseLibraries (& JdLibraryFactory::Get ());

				if (i_configuration)
					m_server.SetConfiguration (i_configuration);

				for (auto moduleName : m_disabledModules)
				{
					//epilog_(normal,  "disable: %s", epistr (moduleName));

					m_libraries.DisableModule (moduleName);
				}

				if (m_timersEnabled)
				{
					try
					{
//						jd_broadcaster.Bind (& m_server); // This is the notification delivery module
						jd_timers.Bind (& m_server);
					}

					catch (...)
					{

					}

//					auto timers = JdPlatform::Get <IJdPlatform::Notification> ();
//					m_timer = timers->ScheduleTimer (10, this, 0);
				}

				auto scheduler = m_server.GetScheduler ();

				if (m_timersEnabled)
				{
					auto driver = jd_timers.Cast <IJdTimerDriver> ();

					scheduler->AddTimerThread (driver);
				}
//				else
//				scheduler->AddThreads (1);

				scheduler->Start ();

				m_initialized = true;
			}
		}

		return result;
	}

	void Teardown ()
	{
		JdResult result;

		if (m_timersEnabled)
		{
			jd_lock (jd_timers)
			{
				jd_timers->StopAllTimers ();
			}
		}

		jd_timers.Release ();

		result = m_server.GetScheduler()->Teardown ();

		m_server.Teardown ();

#if FIX
		jd_broadcaster.ForceRelease ();	// teardown broadcaster last
#endif

		m_server.Teardown (true);

		m_initialized = false;
	}

	void  			RunMainThread			(f64 i_maxDurationInSeconds);
	void  			RunMainLoop				(f64 i_durationInSeconds);

	operator IJdModuleServer		()
	{
		return & m_server;
	}

	//	IJdModuleServer					GetServer					() { return & m_server; }

	protected ://------------------------------------------------------------------------------------------------------

	vector <string>					m_disabledModules;

	JdLibrarian						m_libraries;

	JdServer						m_server;

	IJdBroadcaster					jd_broadcaster;
	IJdTimers						jd_timers;

	bool							m_timersEnabled				= false;
	bool							m_initialized				= false;
};

struct JdLinkBasic		{ static void Setup (); };
struct JdLinkSimple		{ static void Setup (); };

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


<commit_before>/*
 * DISTRHO Plugin Framework (DPF)
 * Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com>
 *
 * Permission to use, copy, modify, and/or distribute this software for any purpose with
 * or without fee is hereby granted, provided that the above copyright notice and this
 * permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
 * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#ifndef DISTRHO_IS_STANDALONE
# error Wrong build configuration
#endif

#include "extra/String.hpp"

#ifndef DISTRHO_OS_WINDOWS
# include <dlfcn.h>
#endif

#if defined(DISTRHO_OS_WINDOWS) && !DISTRHO_IS_STANDALONE
static HINSTANCE hInstance = nullptr;

DISTRHO_PLUGIN_EXPORT
BOOL WINAPI DllMain(HINSTANCE hInst, DWORD reason, LPVOID)
{
    if (reason == DLL_PROCESS_ATTACH)
        hInstance = hInst;
    return 1;
}
#endif

START_NAMESPACE_DISTRHO

#ifdef DISTRHO_PLUGIN_TARGET_JACK
#endif

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

const char* getBinaryFilename()
{
    static String filename;

    if (filename.isNotEmpty())
        return filename;

#ifdef DISTRHO_OS_WINDOWS
# if DISTRHO_IS_STANDALONE
    // TODO
# else
    CHAR filenameBuf[MAX_PATH + 256];
    filenameBuf[0] = '\0';
    GetModuleFileName(hInstance, filenameBuf, sizeof(filenameBuf));
    filename = filenameBuf;
# endif
#else
    Dl_info info;
    dladdr((void*)getBinaryFilename, &info);
    filename = info.dli_fname;
#endif

    return filename;
}

const char* getPluginFormatName() noexcept
{
#if defined(DISTRHO_PLUGIN_TARGET_CARLA)
    return "Carla";
#elif defined(DISTRHO_PLUGIN_TARGET_JACK)
    return "JACK/Standalone";
#elif defined(DISTRHO_PLUGIN_TARGET_LADSPA)
    return "LADSPA";
#elif defined(DISTRHO_PLUGIN_TARGET_DSSI)
    return "DSSI";
#elif defined(DISTRHO_PLUGIN_TARGET_LV2)
    return "LV2";
#elif defined(DISTRHO_PLUGIN_TARGET_VST2)
    return "VST2";
#elif defined(DISTRHO_PLUGIN_TARGET_VST3)
    return "VST3";
#else
    return "Unknown";
#endif
}

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

END_NAMESPACE_DISTRHO
<commit_msg>Make getBinaryFilename work in standalone windows too<commit_after>/*
 * DISTRHO Plugin Framework (DPF)
 * Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com>
 *
 * Permission to use, copy, modify, and/or distribute this software for any purpose with
 * or without fee is hereby granted, provided that the above copyright notice and this
 * permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
 * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#ifndef DISTRHO_IS_STANDALONE
# error Wrong build configuration
#endif

#include "extra/String.hpp"

#ifndef DISTRHO_OS_WINDOWS
# include <dlfcn.h>
#endif

#if defined(DISTRHO_OS_WINDOWS) && !DISTRHO_IS_STANDALONE
static HINSTANCE hInstance = nullptr;

DISTRHO_PLUGIN_EXPORT
BOOL WINAPI DllMain(HINSTANCE hInst, DWORD reason, LPVOID)
{
    if (reason == DLL_PROCESS_ATTACH)
        hInstance = hInst;
    return 1;
}
#endif

START_NAMESPACE_DISTRHO

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

const char* getBinaryFilename()
{
    static String filename;

    if (filename.isNotEmpty())
        return filename;

#ifdef DISTRHO_OS_WINDOWS
# if !DISTRHO_IS_STANDALONE
    constexpr const HINSTANCE hInstance = nullptr;
# endif
    CHAR filenameBuf[MAX_PATH];
    filenameBuf[0] = '\0';
    GetModuleFileName(hInstance, filenameBuf, sizeof(filenameBuf));
    filename = filenameBuf;
#else
    Dl_info info;
    dladdr((void*)getBinaryFilename, &info);
    filename = info.dli_fname;
#endif

    return filename;
}

const char* getPluginFormatName() noexcept
{
#if defined(DISTRHO_PLUGIN_TARGET_CARLA)
    return "Carla";
#elif defined(DISTRHO_PLUGIN_TARGET_JACK)
    return "JACK/Standalone";
#elif defined(DISTRHO_PLUGIN_TARGET_LADSPA)
    return "LADSPA";
#elif defined(DISTRHO_PLUGIN_TARGET_DSSI)
    return "DSSI";
#elif defined(DISTRHO_PLUGIN_TARGET_LV2)
    return "LV2";
#elif defined(DISTRHO_PLUGIN_TARGET_VST2)
    return "VST2";
#elif defined(DISTRHO_PLUGIN_TARGET_VST3)
    return "VST3";
#else
    return "Unknown";
#endif
}

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

END_NAMESPACE_DISTRHO
<|endoftext|>


<commit_before>#include "stdafx.h"
#include "MapObject.h"

MapObject::MapObject()
{

}

MapObject::~MapObject()
{
}
<commit_msg>[S]집감 커밋<commit_after>#include "stdafx.h"
#include "MapObject.h"
#include "GameManager.h"

MapObject::MapObject()
{
    m_PlayerID = 0;
    m_Hp = 10000;
    m_Damage = 100;
    m_Pos.x = 100;
    m_Pos.y = 100;

    b2BodyDef bodyDef;
    bodyDef.type = b2_dynamicBody;
    bodyDef.position.Set(m_Pos.x, m_Pos.y);
    m_Body = GGameManager->GetWolrd()->CreateBody(&bodyDef);

    b2CircleShape circle; //⼭  ؾ Ѵ
    circle.m_radius = REDUCE(DEF_SCALE);

    b2FixtureDef fixtureDef;
    fixtureDef.shape = &circle;
    fixtureDef.density = 1.0f;
    fixtureDef.friction = 0.3f;
    fixtureDef.restitution = 0.7f;

    m_Body->CreateFixture(&fixtureDef);
    m_Body->SetUserData(this);
}

MapObject::~MapObject()
{
}
<|endoftext|>


<commit_before>/*
 *  ssfpbands_main.cpp
 *
 *  Created by Tobias Wood on 14/03/2014.
 *  Copyright (c) 2014 Tobias Wood.
 *
 *  This Source Code Form is subject to the terms of the Mozilla Public
 *  License, v. 2.0. If a copy of the MPL was not distributed with this
 *  file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 */

#include <time.h>
#include <getopt.h>
#include <iostream>
#include <atomic>
#include "Eigen/Dense"

#include "Nifti/Nifti.h"
#include "QUIT/Volume.h"
#include "QUIT/ThreadPool.h"
#include "DESPOT.h"

#ifdef AGILENT
#include "procpar.h"
using namespace Agilent;
#endif

using namespace std;
using namespace Eigen;

//******************************************************************************
// Arguments / Usage
//******************************************************************************
const string usage {
"Usage is: ssfpbands [options] input1 [input2] \n\
\
Options:\n\
	--help, -h        : Print this message\n\
	--verbose, -v     : Print more information\n\
	--out, -o path    : Add a prefix to the output filenames\n\
	--mask, -m file   : Mask input with specified file\n\
	--type, -t p      : Input is magnitude and phase (default)\n\
	           i      : Input is real/imaginary\n\
			   c      : Input is complex\n"
};

enum class Type { Phase, Imag, Complex };
static bool verbose = false;
static string outPrefix;
static Type inputType = Type::Phase;
static struct option long_options[] =
{
	{"help", no_argument, 0, 'h'},
	{"verbose", no_argument, 0, 'v'},
	{"out", required_argument, 0, 'o'},
	{"mask", required_argument, 0, 'm'},
	{"type", required_argument, 0, 't'},
	{0, 0, 0, 0}
};
//******************************************************************************
// Main
//******************************************************************************
int main(int argc, char **argv)
{
	//**************************************************************************
	// Argument Processing
	//**************************************************************************
	cout << version << endl << credit_me << endl;
	Nifti maskFile;
	Volume<int8_t> maskVol;

	int indexptr = 0, c;
	while ((c = getopt_long(argc, argv, "hvo:m:t:", long_options, &indexptr)) != -1) {
		switch (c) {
			case 'v': verbose = true; break;
			case 'm':
				cout << "Reading mask file " << optarg << endl;
				maskFile.open(optarg, Nifti::Mode::Read);
				maskVol.readFrom(maskFile);
				break;
			case 'o':
				outPrefix = optarg;
				cout << "Output prefix will be: " << outPrefix << endl;
				break;
			case 't':
				switch (*optarg) {
					case 'p': inputType = Type::Phase;  cout << "Input is magnitude and phase." << endl; break;
					case 'i': inputType = Type::Imag; cout << "Input is real and imaginary." << endl; break;
					case 'c': inputType = Type::Complex; cout << "Input is complex." << endl; break;
					default:
						cout << "Unknown input type " << optarg << endl;
						exit(EXIT_FAILURE);
						break;
				} break;
			case 'h':
			case '?': // getopt will print an error message
				exit(EXIT_FAILURE);
		}
	}
	//**************************************************************************
	#pragma mark Gather data
	//**************************************************************************
	if ((argc - optind) < 1) {
		cout << "No input file specified." << endl << usage << endl;
		exit(EXIT_FAILURE);
	}
	cout << "Opening input file: " << argv[optind] << endl;
	Nifti inputFile;
	inputFile.open(argv[optind++], Nifti::Mode::Read);
	if (maskFile.isOpen() && !maskFile.matchesSpace(inputFile)) {
		cerr << "Mask does not match input file." << endl;
		exit(EXIT_FAILURE);
	}
	Nifti templateFile(inputFile, 1);
	if ((inputFile.rank() < 4) || ((inputFile.dim(4) % 4) != 0)) {
		cout << "Input must contain 4 phase-cycles (0, 90, 180, 270)." << endl;
		exit(EXIT_FAILURE);
	}
	size_t nFlip = inputFile.dim(4) / 4;

	Series<float> input1, input2;
	Series<complex<float>> inputC;
	if (inputType != Type::Complex) {
		input1.readFrom(inputFile);
		inputFile.close();
		inputFile.open(argv[optind++], Nifti::Mode::Read);
		if (!inputFile.matchesSpace(templateFile)) {
			cerr << "Input files do not match." << endl;
			exit(EXIT_FAILURE);
		}
		input2.readFrom(inputFile);
		inputFile.close();
	} else {
		inputC.readFrom(inputFile);
		inputFile.close();
	}
	if ((argc - optind) != 0) {
		cout << "Incorrect number of arguments." << endl << usage << endl;
		exit(EXIT_FAILURE);
	}
	// Results storage
	Series<float> outMag(input1.dims().head(3), nFlip);
	Series<float> outPhase(input1.dims().head(3), nFlip);
	//**************************************************************************
	// Do the fitting
	//**************************************************************************
	ThreadPool pool;
	for (size_t k = 0; k < templateFile.dim(3); k++) {
		clock_t loopStart;
		// Read in data
		if (verbose)
			cout << "Starting slice " << k << "..." << flush;
		loopStart = clock();
		atomic<int> voxCount{0};

		for (size_t j = 0; j < templateFile.dim(2); j++) {
			function<void (const size_t)> processVox = [&] (const size_t i) {
				const typename Volume<float>::Indx vox{i, j, k};
				if (!maskFile.isOpen() || (maskVol[vox])) {
					voxCount++;

					ArrayXcd I1(nFlip), I2(nFlip), I3(nFlip), I4(nFlip);
					switch (inputType) {
						case (Type::Phase): {
							ArrayXd mag = input1.line(vox).cast<double>();
							ArrayXd ph  = input2.line(vox).cast<double>();

							I1.real() = mag.head(nFlip) * ph.head(nFlip).cos();
							I1.imag() = mag.head(nFlip) * ph.head(nFlip).sin();
							I2.real() = mag.segment(nFlip, nFlip) * ph.segment(nFlip, nFlip).cos();
							I2.imag() = mag.segment(nFlip, nFlip) * ph.segment(nFlip, nFlip).sin();
							I3.real() = mag.segment(2*nFlip, nFlip) * ph.segment(2*nFlip, nFlip).cos();
							I3.imag() = mag.segment(2*nFlip, nFlip) * ph.segment(2*nFlip, nFlip).sin();
							I4.real() = mag.tail(nFlip) * ph.tail(nFlip).cos();
							I4.imag() = mag.tail(nFlip) * ph.tail(nFlip).sin();
						}	break;
						case (Type::Imag): {
							ArrayXd re = input1.line(vox).cast<double>();
							ArrayXd im = input2.line(vox).cast<double>();

							I1.real() = re.head(nFlip);
							I1.imag() = im.head(nFlip);
							I2.real() = re.segment(nFlip, nFlip);
							I2.imag() = im.segment(nFlip, nFlip);
							I3.real() = re.segment(2*nFlip, nFlip);
							I3.imag() = im.segment(2*nFlip, nFlip);
							I4.real() = re.tail(nFlip);
							I4.imag() = im.tail(nFlip);
						 }	break;
						case (Type::Complex): {
							ArrayXcd input = inputC.line(vox).cast<complex<double>>();
							I1 = input.head(nFlip);
							I2 = input.segment(nFlip, nFlip);
							I3 = input.segment(2*nFlip, nFlip);
							I4 = input.tail(nFlip);
						}	break;
					}

					ArrayXcd crossPoint = ((I1.real()*I3.imag() - I3.real()*I1.imag())*(I2 - I4) - (I2.real()*I4.imag() - I4.real()*I2.imag())*(I1 - I3)) /
					                      ((I1.real() - I3.real())*(I2.imag() - I4.imag()) + (I2.real() - I4.real())*(I3.imag() - I1.imag()));
					outMag.line(vox) = crossPoint.abs().cast<float>();
					outPhase.line(vox) = crossPoint.imag().binaryExpr(crossPoint.real(), ptr_fun<double,double,double>(atan2)).cast<float>();
				}
			};

			pool.for_loop(processVox, templateFile.dim(1));
		}

		if (verbose) {
			clock_t loopEnd = clock();
			if (voxCount > 0)
				cout << voxCount << " unmasked voxels, CPU time per voxel was "
				          << ((loopEnd - loopStart) / ((float)voxCount * CLOCKS_PER_SEC)) << " s, ";
			cout << "finished." << endl;
		}
	}

	if (verbose)
		cout << "Writing results." << endl;
	templateFile.setDim(4, nFlip);
	templateFile.open(outPrefix + "no_bands_mag.nii.gz", Nifti::Mode::Write);
	outMag.writeTo(templateFile);
	templateFile.close();
	templateFile.open(outPrefix + "no_bands_ph.nii.gz", Nifti::Mode::Write);
	outPhase.writeTo(templateFile);
	templateFile.close();
	cout << "All done." << endl;
	exit(EXIT_SUCCESS);
}
<commit_msg>Added extra input checks and output messages.<commit_after>/*
 *  ssfpbands_main.cpp
 *
 *  Created by Tobias Wood on 14/03/2014.
 *  Copyright (c) 2014 Tobias Wood.
 *
 *  This Source Code Form is subject to the terms of the Mozilla Public
 *  License, v. 2.0. If a copy of the MPL was not distributed with this
 *  file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 */

#include <time.h>
#include <getopt.h>
#include <iostream>
#include <atomic>
#include "Eigen/Dense"

#include "Nifti/Nifti.h"
#include "QUIT/Volume.h"
#include "QUIT/ThreadPool.h"
#include "DESPOT.h"

#ifdef AGILENT
#include "procpar.h"
using namespace Agilent;
#endif

using namespace std;
using namespace Eigen;

//******************************************************************************
// Arguments / Usage
//******************************************************************************
const string usage {
"Usage is: ssfpbands [options] input1 [input2] \n\
\
Options:\n\
	--help, -h        : Print this message\n\
	--verbose, -v     : Print more information\n\
	--out, -o path    : Add a prefix to the output filenames\n\
	--mask, -m file   : Mask input with specified file\n\
	--type, -t p      : Input is magnitude and phase (default)\n\
	           i      : Input is real/imaginary\n\
			   c      : Input is complex\n"
};

enum class Type { Phase, Imag, Complex };
static bool verbose = false;
static string outPrefix;
static Type inputType = Type::Phase;
static struct option long_options[] =
{
	{"help", no_argument, 0, 'h'},
	{"verbose", no_argument, 0, 'v'},
	{"out", required_argument, 0, 'o'},
	{"mask", required_argument, 0, 'm'},
	{"type", required_argument, 0, 't'},
	{0, 0, 0, 0}
};
//******************************************************************************
// Main
//******************************************************************************
int main(int argc, char **argv)
{
	//**************************************************************************
	// Argument Processing
	//**************************************************************************
	cout << version << endl << credit_me << endl;
	Nifti maskFile;
	Volume<int8_t> maskVol;

	int indexptr = 0, c;
	while ((c = getopt_long(argc, argv, "hvo:m:t:", long_options, &indexptr)) != -1) {
		switch (c) {
			case 'v': verbose = true; break;
			case 'm':
				cout << "Reading mask file " << optarg << endl;
				maskFile.open(optarg, Nifti::Mode::Read);
				maskVol.readFrom(maskFile);
				break;
			case 'o':
				outPrefix = optarg;
				cout << "Output prefix will be: " << outPrefix << endl;
				break;
			case 't':
				switch (*optarg) {
					case 'p': inputType = Type::Phase;  cout << "Input is magnitude and phase." << endl; break;
					case 'i': inputType = Type::Imag; cout << "Input is real and imaginary." << endl; break;
					case 'c': inputType = Type::Complex; cout << "Input is complex." << endl; break;
					default:
						cout << "Unknown input type " << optarg << endl;
						exit(EXIT_FAILURE);
						break;
				} break;
			case 'h':
			case '?': // getopt will print an error message
				exit(EXIT_FAILURE);
		}
	}
	//**************************************************************************
	#pragma mark Gather data
	//**************************************************************************
	if ((inputType == Type::Complex) && (argc - optind) != 1) {
		cout << "Must specify one complex input file." << endl << usage << endl;
		exit(EXIT_FAILURE);
	} else if ((argc - optind) != 2) {
		cout << "Must specify two input files (mag/phase or real/imaginary)." << endl << usage << endl;
		exit(EXIT_FAILURE);
	}

	cout << "Opening input file: " << argv[optind] << endl;
	Nifti inputFile;
	inputFile.open(argv[optind++], Nifti::Mode::Read);
	if (maskFile.isOpen() && !maskFile.matchesSpace(inputFile)) {
		cerr << "Mask does not match input file." << endl;
		exit(EXIT_FAILURE);
	}
	Nifti templateFile(inputFile, 1);
	if ((inputFile.rank() < 4) || ((inputFile.dim(4) % 4) != 0)) {
		cout << "Input must contain 4 phase-cycles (0, 90, 180, 270)." << endl;
		exit(EXIT_FAILURE);
	}
	size_t nFlip = inputFile.dim(4) / 4;

	Series<float> input1, input2;
	Series<complex<float>> inputC;
	if (inputType != Type::Complex) {
		input1.readFrom(inputFile);
		inputFile.close();
		cout << "Opening input file: " << argv[optind] << endl;
		inputFile.open(argv[optind++], Nifti::Mode::Read);
		if (!inputFile.matchesSpace(templateFile)) {
			cerr << "Input files do not match." << endl;
			exit(EXIT_FAILURE);
		}
		input2.readFrom(inputFile);
		inputFile.close();
	} else {
		inputC.readFrom(inputFile);
		inputFile.close();
	}
	if ((argc - optind) != 0) {
		cout << "Incorrect number of arguments." << endl << usage << endl;
		exit(EXIT_FAILURE);
	}
	// Results storage
	Series<float> outMag(input1.dims().head(3), nFlip);
	Series<float> outPhase(input1.dims().head(3), nFlip);
	//**************************************************************************
	// Do the fitting
	//**************************************************************************
	cout << "Starting processing." << endl;
	ThreadPool pool;
	for (size_t k = 0; k < templateFile.dim(3); k++) {
		clock_t loopStart;
		// Read in data
		if (verbose)
			cout << "Starting slice " << k << "..." << flush;
		loopStart = clock();
		atomic<int> voxCount{0};

		for (size_t j = 0; j < templateFile.dim(2); j++) {
			function<void (const size_t)> processVox = [&] (const size_t i) {
				const typename Volume<float>::Indx vox{i, j, k};
				if (!maskFile.isOpen() || (maskVol[vox])) {
					voxCount++;

					ArrayXcd I1(nFlip), I2(nFlip), I3(nFlip), I4(nFlip);
					switch (inputType) {
						case (Type::Phase): {
							ArrayXd mag = input1.line(vox).cast<double>();
							ArrayXd ph  = input2.line(vox).cast<double>();

							I1.real() = mag.head(nFlip) * ph.head(nFlip).cos();
							I1.imag() = mag.head(nFlip) * ph.head(nFlip).sin();
							I2.real() = mag.segment(nFlip, nFlip) * ph.segment(nFlip, nFlip).cos();
							I2.imag() = mag.segment(nFlip, nFlip) * ph.segment(nFlip, nFlip).sin();
							I3.real() = mag.segment(2*nFlip, nFlip) * ph.segment(2*nFlip, nFlip).cos();
							I3.imag() = mag.segment(2*nFlip, nFlip) * ph.segment(2*nFlip, nFlip).sin();
							I4.real() = mag.tail(nFlip) * ph.tail(nFlip).cos();
							I4.imag() = mag.tail(nFlip) * ph.tail(nFlip).sin();
						}	break;
						case (Type::Imag): {
							ArrayXd re = input1.line(vox).cast<double>();
							ArrayXd im = input2.line(vox).cast<double>();

							I1.real() = re.head(nFlip);
							I1.imag() = im.head(nFlip);
							I2.real() = re.segment(nFlip, nFlip);
							I2.imag() = im.segment(nFlip, nFlip);
							I3.real() = re.segment(2*nFlip, nFlip);
							I3.imag() = im.segment(2*nFlip, nFlip);
							I4.real() = re.tail(nFlip);
							I4.imag() = im.tail(nFlip);
						 }	break;
						case (Type::Complex): {
							ArrayXcd input = inputC.line(vox).cast<complex<double>>();
							I1 = input.head(nFlip);
							I2 = input.segment(nFlip, nFlip);
							I3 = input.segment(2*nFlip, nFlip);
							I4 = input.tail(nFlip);
						}	break;
					}

					ArrayXcd crossPoint = ((I1.real()*I3.imag() - I3.real()*I1.imag())*(I2 - I4) - (I2.real()*I4.imag() - I4.real()*I2.imag())*(I1 - I3)) /
					                      ((I1.real() - I3.real())*(I2.imag() - I4.imag()) + (I2.real() - I4.real())*(I3.imag() - I1.imag()));
					outMag.line(vox) = crossPoint.abs().cast<float>();
					outPhase.line(vox) = crossPoint.imag().binaryExpr(crossPoint.real(), ptr_fun<double,double,double>(atan2)).cast<float>();
				}
			};

			pool.for_loop(processVox, templateFile.dim(1));
		}

		if (verbose) {
			clock_t loopEnd = clock();
			if (voxCount > 0)
				cout << voxCount << " unmasked voxels, CPU time per voxel was "
				          << ((loopEnd - loopStart) / ((float)voxCount * CLOCKS_PER_SEC)) << " s, ";
			cout << "finished." << endl;
		}
	}

	if (verbose)
		cout << "Writing results." << endl;
	templateFile.setDim(4, nFlip);
	templateFile.open(outPrefix + "no_bands_mag.nii.gz", Nifti::Mode::Write);
	outMag.writeTo(templateFile);
	templateFile.close();
	templateFile.open(outPrefix + "no_bands_ph.nii.gz", Nifti::Mode::Write);
	outPhase.writeTo(templateFile);
	templateFile.close();
	cout << "All done." << endl;
	exit(EXIT_SUCCESS);
}
<|endoftext|>


<commit_before>#include "PropertiesManager.hpp"

#include <iostream>
#include <unordered_map>

#include "PropertiesValidator.hpp"
#include "../../Util/FileLoad.hpp"

using BufferType = std::vector<std::uint8_t>;

// --------------------------------------------------
// Forward declarations for static functions
// --------------------------------------------------
// Util to load files
static std::unique_ptr<BufferType> LoadFile(const std::string& filename);

// Util to load file data to containers
static void LoadFiledata(
    std::vector<const std::vector<PropertiesManager::LoadInput>*> input,
    std::vector<PropertiesLoader::InputContainer*> out,
    std::vector<std::unique_ptr<BufferType>>& dataBuf);

// Print validation results
static void PrintResult(const PropertiesValidator::Result& r);

// --------------------------------------------------
// Header function implementation
// --------------------------------------------------
Properties::SceneFile PropertiesManager::Load(
     const std::vector<PropertiesManager::LoadInput>& scenes,
     const std::vector<PropertiesManager::LoadInput>& materials,
     const std::vector<PropertiesManager::LoadInput>& models)
{
    // Output buffers
    SceneFileContainer sceneBuf;
    MaterialFileContainer materialBuf;
    ModelFileContainer modelBuf;

    // Merged properties buffer
    Properties::SceneFile merged = {};

    // Load Properties Pipeline
    ParseProperties(scenes, materials, models, sceneBuf, materialBuf, modelBuf)
    .ValidateProperties(sceneBuf, materialBuf, modelBuf)
    .MergeProperties(merged, sceneBuf, materialBuf, modelBuf)
    .ValidateMergedProperties(merged);

    return merged;
}

PropertiesManager& PropertiesManager::ParseProperties(
    const std::vector<LoadInput>& scenes,
    const std::vector<LoadInput>& materials,
    const std::vector<LoadInput>& models,
    SceneFileContainer& sceneBuf,
    MaterialFileContainer& materialBuf,
    ModelFileContainer& modelBuf)
{
    // Create containers
    std::vector<std::unique_ptr<BufferType>> filedata;
    PropertiesLoader::InputContainer sceneIn, materialIn, modelIn;

    // Load filedata
    LoadFiledata(
        {&scenes,  &materials,  &models},   // Input
        {&sceneIn, &materialIn, &modelIn},  // Input containers
        filedata);                          // Filedata buffer

    // Create the loader
    PropertiesLoader loader;

    // Parse properties
    loader.LoadBulk(
        sceneIn,    sceneBuf,
        materialIn, materialBuf,
        modelIn,    modelBuf);

    return *this;
}

PropertiesManager& PropertiesManager::ValidateProperties(
    const PropertiesManager::SceneFileContainer& scenes,
    const PropertiesManager::MaterialFileContainer& materials,
    const PropertiesManager::ModelFileContainer& models)
{
    // Validate properties
    PropertiesValidator validator;
    PropertiesValidator::Result r = validator.ValidateBulk(scenes, materials, models);

    // Print results
    PrintResult(r);

    return *this;
}

PropertiesManager& PropertiesManager::MergeProperties(
    Properties::SceneFile& mergedPropsBuffer,
    const SceneFileContainer& scenes,
    const MaterialFileContainer& materials,
    const ModelFileContainer& models)
{
    (void)mergedPropsBuffer;
    (void)scenes;
    (void)materials;
    (void)models;
    return *this;
}

void PropertiesManager::ValidateMergedProperties(Properties::SceneFile& mergedProps)
{
    (void)mergedProps;
}

// --------------------------------------------------
// Utilities
// --------------------------------------------------
static std::unique_ptr<BufferType> LoadFile(const std::string& filename)
{
    auto rVal = FileLoad<BufferType>(filename);
    if (!rVal)
        throw std::runtime_error("Couldn't load file (" + filename + ")");
    return rVal;
}

static void LoadFiledata(
    std::vector<const std::vector<PropertiesManager::LoadInput>*> input,
    std::vector<PropertiesLoader::InputContainer*> out,
    std::vector<std::unique_ptr<BufferType>>& dataBuf)
{
    size_t vecPos = 0;
    for (const auto& i : input)
    {
        for (const auto& j : *i)
        {
            dataBuf.push_back(LoadFile(j.filename));
            out[vecPos]->insert({j.id, *dataBuf[dataBuf.size() - 1]});
        }

        ++vecPos;
    }
}

static void PrintResult(const PropertiesValidator::Result& r)
{
    // Errors
    if (!r.errors.empty())
        std::cout << "Errors: " << std::endl;
    for (const auto& e : r.errors)
        std::cout << "\t" << e.id + ": " << PropertiesValidator::ErrorToString(e.code) << std::endl;

    // Warnings
    if (!r.warnings.empty())
        std::cout << "Warnings: " << std::endl;
    for (const auto& w : r.warnings)
        std::cout << "\t" << w.id + ": " << PropertiesValidator::WarnToString(w.code) << std::endl;

}
<commit_msg>Implemented properties merging<commit_after>#include "PropertiesManager.hpp"

#include <cstdlib>
#include <iostream>
#include <unordered_map>

#include "PropertiesValidator.hpp"
#include "../../Util/FileLoad.hpp"

using BufferType = std::vector<std::uint8_t>;

// --------------------------------------------------
// Forward declarations for static functions
// --------------------------------------------------
// Util to load files
static std::unique_ptr<BufferType> LoadFile(const std::string& filename);

// Util to load file data to containers
static void LoadFiledata(
    std::vector<const std::vector<PropertiesManager::LoadInput>*> input,
    std::vector<PropertiesLoader::InputContainer*> out,
    std::vector<std::unique_ptr<BufferType>>& dataBuf);

// Print validation results
static void PrintResult(const PropertiesValidator::Result& r);

// --------------------------------------------------
// Header function implementation
// --------------------------------------------------
Properties::SceneFile PropertiesManager::Load(
     const std::vector<PropertiesManager::LoadInput>& scenes,
     const std::vector<PropertiesManager::LoadInput>& materials,
     const std::vector<PropertiesManager::LoadInput>& models)
{
    // Output buffers
    SceneFileContainer sceneBuf;
    MaterialFileContainer materialBuf;
    ModelFileContainer modelBuf;

    // Merged properties buffer
    Properties::SceneFile merged = {};

    // Load Properties Pipeline
    ParseProperties(scenes, materials, models, sceneBuf, materialBuf, modelBuf)
    .ValidateProperties(sceneBuf, materialBuf, modelBuf)
    .MergeProperties(merged, sceneBuf, materialBuf, modelBuf)
    .ValidateMergedProperties(merged);

    return merged;
}

PropertiesManager& PropertiesManager::ParseProperties(
    const std::vector<LoadInput>& scenes,
    const std::vector<LoadInput>& materials,
    const std::vector<LoadInput>& models,
    SceneFileContainer& sceneBuf,
    MaterialFileContainer& materialBuf,
    ModelFileContainer& modelBuf)
{
    // Create containers
    std::vector<std::unique_ptr<BufferType>> filedata;
    PropertiesLoader::InputContainer sceneIn, materialIn, modelIn;

    // Load filedata
    LoadFiledata(
        {&scenes,  &materials,  &models},   // Input
        {&sceneIn, &materialIn, &modelIn},  // Input containers
        filedata);                          // Filedata buffer

    // Create the loader
    PropertiesLoader loader;

    // Parse properties
    loader.LoadBulk(
        sceneIn,    sceneBuf,
        materialIn, materialBuf,
        modelIn,    modelBuf);

    return *this;
}

PropertiesManager& PropertiesManager::ValidateProperties(
    const PropertiesManager::SceneFileContainer& scenes,
    const PropertiesManager::MaterialFileContainer& materials,
    const PropertiesManager::ModelFileContainer& models)
{
    // Validate properties
    PropertiesValidator validator;
    PropertiesValidator::Result r = validator.ValidateBulk(scenes, materials, models);

    // Print results
    PrintResult(r);

    return *this;
}

PropertiesManager& PropertiesManager::MergeProperties(
    Properties::SceneFile& mergedPropsBuffer,
    const SceneFileContainer& scenes,
    const MaterialFileContainer& materials,
    const ModelFileContainer& models)
{
    // Use std members for verbosity
    using std::move;
    using std::begin;
    using std::end;
    using std::back_inserter;
    using std::vector;

    // Create buffers to store properties in other files
    vector<Properties::Texture> texturesBuf;
    vector<Properties::Material> materialsBuf;
    vector<Properties::Geometry> geometriesBuf;
    vector<Properties::Model> modelsBuf;
    vector<Properties::SceneNode> sceneNodeBuf;

    auto addMaterialToBuf = [&texturesBuf, &materialsBuf](const Properties::MaterialFile& mf) -> void
    {
        texturesBuf.insert(end(texturesBuf), begin(mf.textures), end(mf.textures));
        materialsBuf.insert(end(materialsBuf), begin(mf.materials), end(mf.materials));
    };

    auto addModelToBuf = [&geometriesBuf, &modelsBuf](const Properties::ModelFile& mf) -> void
    {
        geometriesBuf.insert(end(geometriesBuf), begin(mf.geometries), end(mf.geometries));
        modelsBuf.insert(end(modelsBuf), begin(mf.models), end(mf.models));
    };

    // Scan material files
    for (const auto& p : materials)
        addMaterialToBuf(p.second);

    // Scan model files
    for (const auto& p : models)
        addModelToBuf(p.second);

    // Scan scene files
    for (const auto& p : scenes)
    {
        addMaterialToBuf(p.second.extraMaterials);
        addModelToBuf(p.second.extraModels);
        sceneNodeBuf.insert(
            end(sceneNodeBuf), begin(p.second.scene.nodes), end(p.second.scene.nodes));
    }

    // Merge everything into a single scene file
    Properties::MaterialFile& mergedMat = mergedPropsBuffer.extraMaterials;
    Properties::ModelFile& mergedMod = mergedPropsBuffer.extraModels;

    // Reserve space to move contents
    mergedMat.textures.reserve(texturesBuf.size() + mergedMat.textures.size());
    mergedMat.materials.reserve(materialsBuf.size() + mergedMat.materials.size());
    mergedMod.geometries.reserve(geometriesBuf.size() + mergedMod.geometries.size());
    mergedMod.models.reserve(modelsBuf.size() + mergedMod.models.size());
    mergedPropsBuffer.scene.nodes.reserve(sceneNodeBuf.size() + mergedPropsBuffer.scene.nodes.size());

    // Move contents
    move(begin(texturesBuf),   end(texturesBuf),   back_inserter(mergedMat.textures));
    move(begin(materialsBuf),  end(materialsBuf),  back_inserter(mergedMat.materials));
    move(begin(geometriesBuf), end(geometriesBuf), back_inserter(mergedMod.geometries));
    move(begin(modelsBuf),     end(modelsBuf),     back_inserter(mergedMod.models));
    move(begin(sceneNodeBuf),  end(sceneNodeBuf),  back_inserter(mergedPropsBuffer.scene.nodes));

    return *this;
}

void PropertiesManager::ValidateMergedProperties(Properties::SceneFile& mergedProps)
{
    (void)mergedProps;
}

// --------------------------------------------------
// Utilities
// --------------------------------------------------
static std::unique_ptr<BufferType> LoadFile(const std::string& filename)
{
    auto rVal = FileLoad<BufferType>(filename);
    if (!rVal)
        throw std::runtime_error("Couldn't load file (" + filename + ")");
    return rVal;
}

static void LoadFiledata(
    std::vector<const std::vector<PropertiesManager::LoadInput>*> input,
    std::vector<PropertiesLoader::InputContainer*> out,
    std::vector<std::unique_ptr<BufferType>>& dataBuf)
{
    size_t vecPos = 0;
    for (const auto& i : input)
    {
        for (const auto& j : *i)
        {
            dataBuf.push_back(LoadFile(j.filename));
            out[vecPos]->insert({j.id, *dataBuf[dataBuf.size() - 1]});
        }

        ++vecPos;
    }
}

static void PrintResult(const PropertiesValidator::Result& r)
{
    // Errors
    if (!r.errors.empty())
        std::cout << "Errors: " << std::endl;
    for (const auto& e : r.errors)
        std::cout << "\t" << e.id + ": " << PropertiesValidator::ErrorToString(e.code) << std::endl;

    // Warnings
    if (!r.warnings.empty())
        std::cout << "Warnings: " << std::endl;
    for (const auto& w : r.warnings)
        std::cout << "\t" << w.id + ": " << PropertiesValidator::WarnToString(w.code) << std::endl;

}
<|endoftext|>


<commit_before>#include <reactive/enumerate.hpp>
#include <reactive/for_each.hpp>
#include <reactive/ref.hpp>
#include <reactive/transform_if_initialized.hpp>
#include <reactive/file_system_watcher.hpp>
#ifdef _WIN32
#	include <reactive/win32/directory_changes.hpp>
#else
#	include <reactive/linux/inotify.hpp>
#endif
#include <boost/range/adaptor/filtered.hpp>
#include <boost/range/numeric.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/optional.hpp>
#include <iostream>

namespace
{
#ifndef _WIN32
	std::string inotify_mask_to_string(boost::uint32_t mask)
	{
		using flag_entry = std::pair<boost::uint32_t, std::string>;
		static std::array<flag_entry, 12> const flag_names
		{{
			{IN_ACCESS, "access"},
			{IN_MODIFY, "modify"},
			{IN_ATTRIB, "attrib"},
			{IN_CLOSE_WRITE, "close_write"},
			{IN_CLOSE_NOWRITE, "close_nowrite"},
			{IN_OPEN, "open"},
			{IN_MOVED_FROM, "moved_from"},
			{IN_MOVED_TO, "moved_to"},
			{IN_CREATE, "create"},
			{IN_DELETE, "delete"},
			{IN_DELETE_SELF, "delete_self"},
			{IN_MOVE_SELF, "move_self"}
		}};
		return boost::accumulate(flag_names | boost::adaptors::filtered([mask](flag_entry const &entry)
		{
			return (entry.first & mask) == entry.first;
		}), std::string(), [](std::string left, flag_entry const &flag)
		{
			if (!left.empty())
			{
				left += "|";
			}
			left += flag.second;
			return left;
		});
	}
#endif
}

int main()
{
	boost::asio::io_service io;

	auto const watched_dir = boost::filesystem::current_path();
	std::cerr << "Watching " << watched_dir << '\n';

#ifdef _WIN32
	rx::file_system_watcher notifier(watched_dir);
	auto all = rx::for_each(rx::ref(notifier), [](rx::file_notification const &event)
	{
		std::cerr << boost::underlying_cast<int>(event.type) << " " << event.name << '\n';
	});
	boost::asio::io_service::work keep_running(io);
#else
	rx::linux::inotify_observable notifier(io);
	auto w = notifier.watch(watched_dir, IN_ALL_EVENTS);
	auto all = rx::for_each(rx::enumerate(rx::ref(notifier)), [](rx::linux::file_notification const &event)
	{
		std::cerr << inotify_mask_to_string(event.mask) << " " << event.name << '\n';
	});
#endif
	all.start();

	io.run();
}
<commit_msg>remove unused include<commit_after>#include <reactive/enumerate.hpp>
#include <reactive/for_each.hpp>
#include <reactive/ref.hpp>
#include <reactive/transform_if_initialized.hpp>
#include <reactive/file_system_watcher.hpp>
#include <boost/range/adaptor/filtered.hpp>
#include <boost/range/numeric.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/optional.hpp>
#include <iostream>
#ifndef _WIN32
#	include <reactive/linux/inotify.hpp>
#endif

namespace
{
#ifndef _WIN32
	std::string inotify_mask_to_string(boost::uint32_t mask)
	{
		using flag_entry = std::pair<boost::uint32_t, std::string>;
		static std::array<flag_entry, 12> const flag_names
		{{
			{IN_ACCESS, "access"},
			{IN_MODIFY, "modify"},
			{IN_ATTRIB, "attrib"},
			{IN_CLOSE_WRITE, "close_write"},
			{IN_CLOSE_NOWRITE, "close_nowrite"},
			{IN_OPEN, "open"},
			{IN_MOVED_FROM, "moved_from"},
			{IN_MOVED_TO, "moved_to"},
			{IN_CREATE, "create"},
			{IN_DELETE, "delete"},
			{IN_DELETE_SELF, "delete_self"},
			{IN_MOVE_SELF, "move_self"}
		}};
		return boost::accumulate(flag_names | boost::adaptors::filtered([mask](flag_entry const &entry)
		{
			return (entry.first & mask) == entry.first;
		}), std::string(), [](std::string left, flag_entry const &flag)
		{
			if (!left.empty())
			{
				left += "|";
			}
			left += flag.second;
			return left;
		});
	}
#endif
}

int main()
{
	boost::asio::io_service io;

	auto const watched_dir = boost::filesystem::current_path();
	std::cerr << "Watching " << watched_dir << '\n';

#ifdef _WIN32
	rx::file_system_watcher notifier(watched_dir);
	auto all = rx::for_each(rx::ref(notifier), [](rx::file_notification const &event)
	{
		std::cerr << boost::underlying_cast<int>(event.type) << " " << event.name << '\n';
	});
	boost::asio::io_service::work keep_running(io);
#else
	rx::linux::inotify_observable notifier(io);
	auto w = notifier.watch(watched_dir, IN_ALL_EVENTS);
	auto all = rx::for_each(rx::enumerate(rx::ref(notifier)), [](rx::linux::file_notification const &event)
	{
		std::cerr << inotify_mask_to_string(event.mask) << " " << event.name << '\n';
	});
#endif
	all.start();

	io.run();
}
<|endoftext|>