Пример #1
0
size_t SymbolTable::map_operand(bh_instruction& instr, size_t operand_idx)
{
    size_t arg_idx = ++(nsymbols_); // Candidate arg_idx if not reused

    if (bh_is_constant(&instr.operand[operand_idx])) {  // Constants
        if (BH_R123 != instr.constant.type) {           // Regular constants
            table_[arg_idx].const_data   = &(instr.constant.value);
            table_[arg_idx].etype        = bhtype_to_etype(instr.constant.type);
        } else {                                        // "Special" for BH_R123
            table_[arg_idx].etype        = UINT64;
            if (1 == operand_idx) {
                table_[arg_idx].const_data  = &(instr.constant.value.r123.start);
            } else if (2 == operand_idx) {
                table_[arg_idx].const_data  = &(instr.constant.value.r123.key);
            } else {
                throw runtime_error("THIS SHOULD NEVER HAPPEN!");
            }
        }
        table_[arg_idx].data         = &table_[arg_idx].const_data;
        table_[arg_idx].nelem        = 1;
        table_[arg_idx].ndim         = 1;
        table_[arg_idx].start        = 0;
        table_[arg_idx].shape        = instr.operand[operand_idx].shape;
        table_[arg_idx].shape[0]     = 1;
        table_[arg_idx].stride       = instr.operand[operand_idx].shape;
        table_[arg_idx].stride[0]    = 0;
        table_[arg_idx].layout       = SCALAR_CONST;
        table_[arg_idx].base         = NULL;
    } else {
        table_[arg_idx].const_data= NULL;
        table_[arg_idx].data     = &(bh_base_array(&instr.operand[operand_idx])->data);
        table_[arg_idx].etype    = bhtype_to_etype(bh_base_array(&instr.operand[operand_idx])->type);
        table_[arg_idx].nelem    = bh_base_array(&instr.operand[operand_idx])->nelem;
        table_[arg_idx].ndim     = instr.operand[operand_idx].ndim;
        table_[arg_idx].start    = instr.operand[operand_idx].start;
        table_[arg_idx].shape    = instr.operand[operand_idx].shape;
        table_[arg_idx].stride   = instr.operand[operand_idx].stride;

        table_[arg_idx].layout   = determine_layout(table_[arg_idx]);
        table_[arg_idx].base     = instr.operand[operand_idx].base;
    }

    //
    // Reuse operand identifiers: Detect if we have seen it before and reuse the name.
    // This is done by comparing the currently investigated operand (arg_idx)
    // with all other operands in the current scope [1,arg_idx[
    // Do remember that 0 is is not a valid operand and we therefore index from 1.
    // Also we do not want to compare with selv, that is when i == arg_idx.
    for(size_t i=1; i<arg_idx; ++i) {
        if (!equivalent(table_[i], table_[arg_idx])) {
            continue; // Not equivalent, continue search.
        }
        // Found one! Use it instead of the incremented identifier.
        --nsymbols_;
        arg_idx = i;
        break;
    }
    return arg_idx;
}
Пример #2
0
static inline bool is_constant(const bh_instruction& instr)
{
    for(int i = 0; i < bh_noperands(instr.opcode); ++i) {
        if (bh_is_constant(&(instr.operand[i]))) {
            return true;
        }
    }

    return false;
}
Пример #3
0
void Contracter::contract_stupidmath(bh_ir &bhir)
{
    for(size_t pc = 0; pc < bhir.instr_list.size(); ++pc) {
        bh_instruction& instr = bhir.instr_list[pc];

        if (is_doing_stupid_math(instr)) {
            verbose_print("[Stupid math] Is doing stupid math with a " + std::string(bh_opcode_text(instr.opcode)));

            // We could have the following:
            //   BH_ADD B A 0
            //   BH_FREE A
            //   BH_SYNC B
            // We want to find the add and replace A in all above with B, if A is created in this flush.
            // Then remove the free of A.

            // Output operand
            bh_view* B = &(instr.operand[0]);

            // The one operand, that isn't constant
            bh_view* A;
            if (bh_is_constant(&(instr.operand[1]))) {
                A = &(instr.operand[2]);
            } else {
                A = &(instr.operand[1]);
            }

            if (bh_view_same(A, B)) continue;

            bool freed = false;
            for (size_t pc_chain = 0; pc_chain < bhir.instr_list.size(); ++pc_chain) {
                bh_instruction& other_instr = bhir.instr_list[pc_chain];

                // Look for matching FREE for B
                if (other_instr.opcode == BH_FREE and bh_view_same(&(other_instr.operand[0]), B)) {
                    freed = true;
                    break;
                }
            }

            if (!freed) {
                verbose_print("[Stupid math] \tCan't rectify as it isn't freeing in same flush.");
                continue;
            }

            // Check that A is created by us.
            bool created_before = false;

            for (size_t pc_chain = 0; pc_chain < pc; ++pc_chain) {
                bh_instruction& other_instr = bhir.instr_list[pc_chain];

                if (bh_view_same(&(other_instr.operand[0]), A)) {
                    created_before = true;
                    break;
                }
            }

            // Only if we have created A in this flush, are we allowed to change it.
            if (!created_before) {
                verbose_print("[Stupid math] \tCan't rectify as other view isn't created in same flush.");
                continue;
            }

            for (size_t pc_chain = 0; pc_chain < bhir.instr_list.size(); ++pc_chain) {
                if (pc == pc_chain) continue;

                bh_instruction& other_instr = bhir.instr_list[pc_chain];

                // Look for matching FREE for A
                if (other_instr.opcode == BH_FREE and bh_view_same(&(other_instr.operand[0]), A)) {
                    verbose_print("[Stupid math] \tFound and removed FREE.");
                    other_instr.opcode = BH_NONE; // Remove instruction
                } else {
                    // Rewrite all uses of A to B
                    for (int idx = 0; idx < bh_noperands(other_instr.opcode); ++idx) {
                        if (bh_view_same(&(other_instr.operand[idx]), A)) {
                            verbose_print("[Stupid math] \tRewriting A to B.");
                            other_instr.operand[idx] = *B;
                        }
                    }
                }
            }

            // Remove self
            verbose_print("[Stupid math] \tRemoving " + std::string(bh_opcode_text(instr.opcode)));
            instr.opcode = BH_NONE;
        }
    }
}
Пример #4
0
int main()
{
    dispatch_msg *msg;

    timing_init();

    //Initiate the process grid
    pgrid_init();

    while(1)
    {
        //Receive the dispatch message from the master-process
        dispatch_reset();
        dispatch_recv(&msg);

        //Handle the message
        switch(msg->type)
        {
            case BH_CLUSTER_DISPATCH_INIT:
            {
                char *name = msg->payload;
                check_error(exec_init(name),__FILE__,__LINE__);
                break;
            }
            case BH_CLUSTER_DISPATCH_SHUTDOWN:
            {
                check_error(exec_shutdown(),__FILE__,__LINE__);
                return 0;
            }
            case BH_CLUSTER_DISPATCH_EXTMETHOD:
            {
                bh_opcode opcode = *((bh_opcode *)msg->payload);
                char *name = msg->payload+sizeof(bh_opcode);
                check_error(exec_extmethod(name, opcode),__FILE__,__LINE__);
                break;
            }
            case BH_CLUSTER_DISPATCH_EXEC:
            {
                //Get the size of the the serialized BhIR
                bh_intp bhir_size = *((bh_intp*) msg->payload);

                //Deserialize the BhIR
                bh_ir bhir = bh_ir(((char*)msg->payload)+sizeof(bh_intp), bhir_size);

                //The number of new arrays
                bh_intp *noa = (bh_intp *)(((char*)msg->payload)+sizeof(bh_intp)+bhir_size);
                //The list of new arrays
                dispatch_array *darys = (dispatch_array*)(noa+1); //number of new arrays

                //Insert the new array into the array store and the array maps
                std::stack<bh_base*> base_darys;
                for(bh_intp i=0; i < *noa; ++i)
                {
                    bh_base *ary = dispatch_new_slave_array(&darys[i].ary, darys[i].id);
                    base_darys.push(ary);
                }

                //Receive the dispatched array-data from the master-process
                dispatch_array_data(base_darys);

                //Update all instruction to reference local arrays
                for(uint64_t i=0; i < bhir.instr_list.size(); ++i)
                {
                    bh_instruction *inst = &bhir.instr_list[i];
                    int nop = bh_noperands(inst->opcode);
                    bh_view *ops = bh_inst_operands(inst);

                    //Convert all instructon operands
                    for(bh_intp j=0; j<nop; ++j)
                    {
                        if(bh_is_constant(&ops[j]))
                            continue;
                        bh_base *base = bh_base_array(&ops[j]);
                        assert(dispatch_slave_exist((bh_intp)base));
                        bh_base_array(&ops[j]) = dispatch_master2slave((bh_intp)base);
                    }
                }
                check_error(exec_execute(&bhir),__FILE__,__LINE__);
                break;
            }
            default:
                fprintf(stderr, "[VEM-CLUSTER] Slave (rank %d) "
                        "received unknown message type\n", pgrid_myrank);
                MPI_Abort(MPI_COMM_WORLD,BH_ERROR);
        }
    }

    timing_finalize();
    return BH_SUCCESS;
}
Пример #5
0
void Contracter::contract_muladd(bh_ir &bhir)
{
    bool rewritten = false;

    vector<bh_view*> temp_results;
    vector<bh_instruction*> instruction_chain;

    for(size_t pc = 0; pc < bhir.instr_list.size(); ++pc) {
        if (rewritten) {
            // We might catch more rewrites if we found one
            // so we loop back to the beginning
            pc        = 0;
            rewritten = false;
            temp_results.clear();
            instruction_chain.clear();
        }

        bh_instruction& instr = bhir.instr_list[pc];
        bh_view* multiplying_view;

        if (instr.opcode == BH_MULTIPLY) {
            if (bh_is_constant(&(instr.operand[1]))) {
                multiplying_view = &(instr.operand[2]);
            } else if (bh_is_constant(&(instr.operand[2]))) {
                multiplying_view = &(instr.operand[1]);
            } else {
                continue;
            }

            instruction_chain.push_back(&instr); // First BH_MULTIPLY found
            temp_results.push_back(&(instr.operand[0]));

            for(size_t sub_pc = pc+1; sub_pc < bhir.instr_list.size(); ++sub_pc) {
                if (rewritten) break;

                bh_instruction& other_instr = bhir.instr_list[sub_pc];

                if (other_instr.opcode == BH_MULTIPLY) {
                    if (!((bh_is_constant(&(other_instr.operand[1])) and *multiplying_view == other_instr.operand[2]) or
                          (bh_is_constant(&(other_instr.operand[2])) and *multiplying_view == other_instr.operand[1]))) {
                        continue;
                    }

                    instruction_chain.push_back(&other_instr); // Second BH_MULTIPLY found
                    temp_results.push_back(&(other_instr.operand[0]));

                    for(size_t sub_sub_pc = sub_pc+1; sub_sub_pc < bhir.instr_list.size(); ++sub_sub_pc) {
                        if (rewritten) break;

                        bh_instruction& yet_another_instr = bhir.instr_list[sub_sub_pc];

                        if (yet_another_instr.opcode == BH_ADD or yet_another_instr.opcode == BH_SUBTRACT) {
                            uint found = 0;
                            for(auto it : temp_results) {
                                if (*it == yet_another_instr.operand[1] or *it == yet_another_instr.operand[2]) {
                                    found += 1;
                                }
                            }

                            if (found >= 2) {
                                instruction_chain.push_back(&yet_another_instr);
                                verbose_print("[Muladd] Rewriting chain of length " + std::to_string(instruction_chain.size()));
                                rewritten = rewrite_chain(bhir, instruction_chain, temp_results);
                            }
                        }
                    }

                    instruction_chain.pop_back();
                    temp_results.pop_back();
                }
            }
        }
    }
}