static void *SCCUnpackFun(void *buf) { c4snet_data_t *result = SNetMemAlloc(sizeof(c4snet_data_t)); SNetDistribUnpack(result, buf, false, sizeof(c4snet_data_t)); result->ref_count = 1; if (result->vtype == VTYPE_array) { SNetDistribUnpack(&result->data.ptr, buf, true); } return result; }
static c4snet_data_t *MPIUnpackFun(void *buf) { void *tmp; c4snet_data_t *result; int vtype, type, count; SNetDistribUnpack(&vtype, buf, MPI_INT, 1); SNetDistribUnpack(&count, buf, MPI_INT, 1); SNetDistribUnpack(&type, buf, MPI_INT, 1); if (vtype == VTYPE_array) { result = C4SNetAlloc(type, count, &tmp); SNetDistribUnpack(tmp, buf, TypeToMPIType(type), count); } else { result = C4SNetCreate(type, 1, &tmp); SNetDistribUnpack(tmp, buf, TypeToMPIType(type), 1); } return result; }
snet_msg_t SNetDistribRecvMsg(void) { int count; snet_msg_t result; MPI_Status status; static mpi_buf_t recvBuf = {0, 0, NULL}; MPI_Probe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status); MPI_Get_count(&status, MPI_PACKED, &count); MPI_Pack_size(count, MPI_PACKED, MPI_COMM_WORLD, &recvBuf.offset); if (recvBuf.offset > recvBuf.size) { recvBuf.data = SNetMemResize(recvBuf.data, recvBuf.offset); recvBuf.size = recvBuf.offset; } MPI_Recv(recvBuf.data, count, MPI_PACKED, status.MPI_SOURCE, status.MPI_TAG, MPI_COMM_WORLD, &status); recvBuf.offset = 0; result.type = status.MPI_TAG; switch (status.MPI_TAG) { case snet_rec: result.rec = SNetRecDeserialise(&recvBuf); case snet_block: case snet_unblock: result.dest = SNetDestDeserialise(&recvBuf); result.dest.node = status.MPI_SOURCE; break; case snet_ref_set: result.ref = SNetRefDeserialise(&recvBuf); result.data = (uintptr_t) SNetInterfaceGet(SNetRefInterface(result.ref))->unpackfun(&recvBuf); break; case snet_ref_fetch: result.ref = SNetRefDeserialise(&recvBuf); result.data = status.MPI_SOURCE; break; case snet_ref_update: result.ref = SNetRefDeserialise(&recvBuf); SNetDistribUnpack(&recvBuf, &result.val, sizeof(result.val)); break; case snet_update: break; case snet_stop: break; default: SNetUtilDebugFatal("[%s]: Unexpected MPI TAG %d\n", __func__, result.type); break; } return result; }
static void *SAC4SNetMPIUnpackFun(void *buf) { int *shape; SACarg *result = NULL; void *contents = NULL; int type, dims, num_elems = 1; SNetDistribUnpack(buf, &type, sizeof(type)); SNetDistribUnpack(buf, &dims, sizeof(dims)); shape = SNetMemAlloc(dims * sizeof(int)); SNetDistribUnpack(buf, shape, dims * sizeof(int)); for (int i = 0; i < dims; i++) { num_elems *= shape[i]; } contents = SNetMemAlloc(num_elems * sizeOfType(type)); SNetDistribUnpack(buf, contents, num_elems * sizeOfType(type)); switch (type) { case SACint: result = SACARGconvertFromIntPointerVect(contents, dims, shape); break; case SACflt: result = SACARGconvertFromFloatPointerVect(contents, dims, shape); break; case SACdbl: result = SACARGconvertFromDoublePointerVect(contents, dims, shape); break; default: Error( "Unsupported basetype in unpack function."); break; } SNetMemFree(shape); return result; }