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);
}
示例#3
0
文件: channel.c 项目: haproxy/haproxy
/* 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;
}
示例#6
0
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++;
      }
    }
  }
}
示例#7
0
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;
}
示例#9
0
/* 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;
 }
示例#12
0
        // ############################################################
    } 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