cartesian_communicator::cartesian_communicator(const communicator& comm, const cartesian_topology& topology, bool reorder ) : communicator(MPI_COMM_NULL, comm_attach) { std::vector<int> dims(topology.size()); std::vector<int> periodic(topology.size()); int tsz = topology.size(); for(int i = 0; i < tsz; ++i) { dims[i] = topology[i].size; periodic[i] = topology[i].periodic; } // Fill the gaps, if any if (std::count(dims.begin(), dims.end(), 0) > 0) { cartesian_dimensions(comm, dims); } MPI_Comm newcomm; BOOST_MPI_CHECK_RESULT(MPI_Cart_create, ((MPI_Comm)comm, dims.size(), c_data(dims), c_data(periodic), int(reorder), &newcomm)); if(newcomm != MPI_COMM_NULL) { comm_ptr.reset(new MPI_Comm(newcomm), comm_free()); } }
void cartesian_communicator::topology( cartesian_topology& topo, std::vector<int>& coords ) const { int ndims = this->ndims(); topo.resize(ndims); coords.resize(ndims); std::vector<int> cdims(ndims); std::vector<int> cperiods(ndims); BOOST_MPI_CHECK_RESULT(MPI_Cart_get, (MPI_Comm(*this), ndims, c_data(cdims), c_data(cperiods), c_data(coords))); cartesian_topology res(cdims.begin(), cperiods.begin(), ndims); topo.swap(res); }
/* Tries to copy block <blk> at once into the channel's buffer after length * controls. The chn->o and to_forward pointers are updated. If the channel * input is closed, -2 is returned. If the block is too large for this buffer, * -3 is returned. If there is not enough room left in the buffer, -1 is * returned. Otherwise the number of bytes copied is returned (0 being a valid * number). Channel flag READ_PARTIAL is updated if some data can be * transferred. */ int ci_putblk(struct channel *chn, const char *blk, int len) { int max; if (unlikely(channel_input_closed(chn))) return -2; if (len < 0) return -3; max = channel_recv_limit(chn); if (unlikely(len > max - c_data(chn))) { /* we can't write this chunk right now because the buffer is * almost full or because the block is too large. Return the * available space or -2 if impossible. */ if (len > max) return -3; return -1; } if (unlikely(len == 0)) return 0; /* OK so the data fits in the buffer in one or two blocks */ max = b_contig_space(&chn->buf); memcpy(ci_tail(chn), blk, MIN(len, max)); if (len > max) memcpy(c_orig(chn), blk + max, len - max); b_add(&chn->buf, len); channel_add_input(chn, len); return len; }
std::vector<int> cartesian_communicator::coordinates(int rk) const { std::vector<int> cbuf(ndims()); BOOST_MPI_CHECK_RESULT(MPI_Cart_coords, (MPI_Comm(*this), rk, cbuf.size(), c_data(cbuf) )); return cbuf; }
int cartesian_communicator::rank(const std::vector<int>& coords ) const { int r = -1; assert(int(coords.size()) == ndims()); BOOST_MPI_CHECK_RESULT(MPI_Cart_rank, (MPI_Comm(*this), c_data(const_cast<std::vector<int>&>(coords)), &r)); return r; }
void all_gather_impl(const communicator& comm, const T* in_values, int n, T* out_values, int const* sizes, int const* skips, mpl::false_) { int nproc = comm.size(); // first, gather all size, these size can be different for // each process packed_oarchive oa(comm); for (int i = 0; i < n; ++i) { oa << in_values[i]; } std::vector<int> oasizes(nproc); int oasize = oa.size(); BOOST_MPI_CHECK_RESULT(MPI_Allgather, (&oasize, 1, MPI_INTEGER, c_data(oasizes), 1, MPI_INTEGER, MPI_Comm(comm))); // Gather the archives, which can be of different sizes, so // we need to use allgatherv. // Every thing is contiguous, so the offsets can be // deduced from the collected sizes. std::vector<int> offsets(nproc); sizes2offsets(oasizes, offsets); packed_iarchive::buffer_type recv_buffer(std::accumulate(oasizes.begin(), oasizes.end(), 0)); BOOST_MPI_CHECK_RESULT(MPI_Allgatherv, (const_cast<void*>(oa.address()), int(oa.size()), MPI_BYTE, c_data(recv_buffer), c_data(oasizes), c_data(offsets), MPI_BYTE, MPI_Comm(comm))); for (int src = 0; src < nproc; ++src) { int nb = sizes ? sizes[src] : n; int skip = skips ? skips[src] : 0; std::advance(out_values, skip); if (src == comm.rank()) { // this is our local data for (int i = 0; i < nb; ++i) { *out_values++ = *in_values++; } } else { packed_iarchive ia(comm, recv_buffer, boost::archive::no_header, offsets[src]); for (int i = 0; i < nb; ++i) { ia >> *out_values++; } } } }
void scatterv_impl(const communicator& comm, const T* in_values, T* out_values, int out_size, int const* sizes, int const* displs, int root, mpl::false_) { packed_oarchive::buffer_type sendbuf; bool is_root = comm.rank() == root; int nproc = comm.size(); std::vector<int> archsizes; if (is_root) { assert(out_size == sizes[comm.rank()]); archsizes.resize(nproc); std::vector<int> skipped; if (displs) { skipped.resize(nproc); offsets2skipped(sizes, displs, c_data(skipped), nproc); displs = c_data(skipped); } fill_scatter_sendbuf(comm, in_values, sizes, (int const*)0, sendbuf, archsizes); } dispatch_scatter_sendbuf(comm, sendbuf, archsizes, (T const*)0, out_values, out_size, root); }
std::vector<int>& cartesian_dimensions(int sz, std::vector<int>& dims) { int min = 1; int const dimsz = dims.size(); for(int i = 0; i < dimsz; ++i) { if (dims[i] > 0) { min *= dims[i]; } } int leftover = sz % min; BOOST_MPI_CHECK_RESULT(MPI_Dims_create, (sz-leftover, dims.size(), c_data(dims))); return dims; }
/* Tries to copy block <blk> at once into the channel's buffer after length * controls. The chn->o and to_forward pointers are updated. If the channel * input is closed, -2 is returned. If the block is too large for this buffer, * -3 is returned. If there is not enough room left in the buffer, -1 is * returned. Otherwise the number of bytes copied is returned (0 being a valid * number). Channel flag READ_PARTIAL is updated if some data can be * transferred. */ int ci_putblk(struct channel *chn, const char *blk, int len) { int max; if (unlikely(channel_input_closed(chn))) return -2; if (len < 0) return -3; max = channel_recv_limit(chn); if (unlikely(len > max - c_data(chn))) { /* we can't write this chunk right now because the buffer is * almost full or because the block is too large. Return the * available space or -2 if impossible. */ if (len > max) return -3; return -1; } if (unlikely(len == 0)) return 0; /* OK so the data fits in the buffer in one or two blocks */ max = b_contig_space(&chn->buf); memcpy(ci_tail(chn), blk, MIN(len, max)); if (len > max) memcpy(c_orig(chn), blk + max, len - max); b_add(&chn->buf, len); chn->total += len; if (chn->to_forward) { unsigned long fwd = len; if (chn->to_forward != CHN_INFINITE_FORWARD) { if (fwd > chn->to_forward) fwd = chn->to_forward; chn->to_forward -= fwd; } c_adv(chn, fwd); } /* notify that some data was read from the SI into the buffer */ chn->flags |= CF_READ_PARTIAL; return len; }
cartesian_communicator::cartesian_communicator(const cartesian_communicator& comm, const std::vector<int>& keep ) : communicator(MPI_COMM_NULL, comm_attach) { int const max_dims = comm.ndims(); int const nbkept = keep.size(); assert(nbkept <= max_dims); std::vector<int> bitset(max_dims, int(false)); for(int i = 0; i < nbkept; ++i) { assert(keep[i] < max_dims); bitset[keep[i]] = true; } MPI_Comm newcomm; BOOST_MPI_CHECK_RESULT(MPI_Cart_sub, ((MPI_Comm)comm, c_data(bitset), &newcomm)); if(newcomm != MPI_COMM_NULL) { comm_ptr.reset(new MPI_Comm(newcomm), comm_free()); } }
bool OSExchangeDataProviderWin::GetPickledData(CLIPFORMAT format, Pickle* data) const { DCHECK(data); FORMATETC format_etc = { format, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; bool success = false; STGMEDIUM medium; if(SUCCEEDED(source_object_->GetData(&format_etc, &medium))) { if(medium.tymed & TYMED_HGLOBAL) { base::win::ScopedHGlobal<char> c_data(medium.hGlobal); DCHECK_GT(c_data.Size(), 0u); // Need to subtract 1 as SetPickledData adds an extra byte to the end. *data = Pickle(c_data.get(), static_cast<int>(c_data.Size()-1)); success = true; } ReleaseStgMedium(&medium); } return success; }
// ############################################################ } END_PIE BEGIN_PIE(TPCC_PAYMENT, // txn TPCC_PAYMENT_4, // piece 4, R & W customer DF_REAL) { // ############################################################ verify(input_size == 6); Log::debug("TPCC_PAYMENT, piece: %d", TPCC_PAYMENT_4); i32 output_index = 0; // ############################################################ mdb::Row *r = NULL; std::vector<Value> buf; mdb::MultiBlob mb(3); //cell_locator_t cl(TPCC_TB_CUSTOMER, 3); mb[0] = input[0].get_blob(); mb[1] = input[2].get_blob(); mb[2] = input[1].get_blob(); // R customer if (!(IS_MODE_RCC || IS_MODE_RO6) || ((IS_MODE_RCC || IS_MODE_RO6) && IN_PHASE_1)) { // non-rcc || rcc start request r = dtxn->query(dtxn->get_table(TPCC_TB_CUSTOMER), mb, output_size, header.pid).next(); } ALock::type_t lock_20_type = ALock::RLOCK; if (input[0].get_i32() % 10 == 0) lock_20_type = ALock::WLOCK; // ############################################################ TPL_KISS( mdb::column_lock_t(r, 3, ALock::RLOCK), mdb::column_lock_t(r, 4, ALock::RLOCK), mdb::column_lock_t(r, 5, ALock::RLOCK), mdb::column_lock_t(r, 6, ALock::RLOCK), mdb::column_lock_t(r, 7, ALock::RLOCK), mdb::column_lock_t(r, 8, ALock::RLOCK), mdb::column_lock_t(r, 9, ALock::RLOCK), mdb::column_lock_t(r, 10, ALock::RLOCK), mdb::column_lock_t(r, 11, ALock::RLOCK), mdb::column_lock_t(r, 12, ALock::RLOCK), mdb::column_lock_t(r, 13, ALock::RLOCK), mdb::column_lock_t(r, 14, ALock::RLOCK), mdb::column_lock_t(r, 15, ALock::RLOCK), mdb::column_lock_t(r, 16, ALock::WLOCK), mdb::column_lock_t(r, 17, ALock::WLOCK), mdb::column_lock_t(r, 20, lock_20_type) ) // ############################################################ RCC_KISS(r, 16, false); RCC_KISS(r, 17, false); RCC_KISS(r, 20, false); RCC_SAVE_ROW(r, TPCC_PAYMENT_4); RCC_PHASE1_RET; RCC_LOAD_ROW(r, TPCC_PAYMENT_4); if (!dtxn->read_columns(r, std::vector<mdb::column_id_t>({ 3, // c_first buf[0] 4, // c_middle buf[1] 5, // c_last buf[2] 6, // c_street_1 buf[3] 7, // c_street_2 buf[4] 8, // c_city buf[5] 9, // c_state buf[6] 10, // c_zip buf[7] 11, // c_phone buf[8] 12, // c_since buf[9] 13, // c_credit buf[10] 14, // c_credit_lim buf[11] 15, // c_discount buf[12] 16, // c_balance buf[13] 17, // c_ytd_payment buf[14] 20 // c_data buf[15] }), &buf)) { *res = REJECT; *output_size = output_index; return; } // if c_credit == "BC" (bad) 10% // here we use c_id to pick up 10% instead of c_credit if (input[0].get_i32() % 10 == 0) { Value c_data(( to_string(input[0]) + to_string(input[2]) + to_string(input[1]) + to_string(input[5]) + to_string(input[4]) + to_string(input[3]) + buf[15].get_str() ).substr(0, 500)); std::vector<mdb::column_id_t> col_ids({ 16, // c_balance 17, // c_ytd_payment 20 // c_data }); std::vector<Value> col_data({ Value(buf[13].get_double() - input[3].get_double()), Value(buf[14].get_double() + input[3].get_double()), c_data }); dtxn->write_columns(r, col_ids, col_data); } else { std::vector<mdb::column_id_t> col_ids({ 16, // c_balance 17 // c_ytd_payment }); std::vector<Value> col_data({ Value(buf[13].get_double() - input[3].get_double()), Value(buf[14].get_double() + input[3].get_double()) }); dtxn->write_columns(r, col_ids, col_data); } output[output_index++] = input[0]; // output[0] => c_id output[output_index++] = buf[0]; // output[1] => c_first output[output_index++] = buf[1]; // output[2] => c_middle output[output_index++] = buf[2]; // output[3] => c_last output[output_index++] = buf[3]; // output[4] => c_street_1 output[output_index++] = buf[4]; // output[5] => c_street_2 output[output_index++] = buf[5]; // output[6] => c_city output[output_index++] = buf[6]; // output[7] => c_state output[output_index++] = buf[7]; // output[8] => c_zip output[output_index++] = buf[8]; // output[9] => c_phone output[output_index++] = buf[9]; // output[10] => c_since output[output_index++] = buf[10]; // output[11] => c_credit output[output_index++] = buf[11]; // output[12] => c_credit_lim output[output_index++] = buf[12]; // output[13] => c_discount output[output_index++] = Value(buf[13].get_double() - input[3].get_double()); // output[14] => c_balance // ############################################################ verify(*output_size >= output_index); *res = SUCCESS; Log::debug("TPCC_PAYMENT, piece: %d end", TPCC_PAYMENT_4); // ############################################################ *output_size = output_index; } END_PIE