/* * test_client_obj.c: Client side of H5O routines */ #include #include #include #include #include "mpi.h" #include "hdf5.h" int main(int argc, char **argv) { char file_name[50]; hid_t file_id; hid_t gid; hid_t did, map; hid_t sid, dtid; hid_t tid1, tid2, rc_id, rid1, rid2; hid_t fapl_id, dxpl_id; hid_t e_stack; hbool_t exists = -1; const unsigned int nelem=60; hsize_t dims[1]; uint64_t version; uint64_t trans_num; int my_rank, my_size; int provided; MPI_Request mpi_req; int32_t *wdata1 = NULL, *rdata1 = NULL; int key, value, i; H5ES_status_t status; size_t num_events = 0; herr_t ret; sprintf(file_name, "%s_%s", getenv("USER"), "eff_file_evdt.h5"); MPI_Init_thread(&argc, &argv, MPI_THREAD_MULTIPLE, &provided); if(MPI_THREAD_MULTIPLE != provided) { fprintf(stderr, "MPI does not have MPI_THREAD_MULTIPLE support\n"); exit(1); } /* Call EFF_init to initialize the EFF stack. As a result of this call, the Function Shipper client is started, and HDF5 VOL calls are registered with the function shipper. An "IOD init" call is forwarded from the FS client to the FS server which should already be running. */ EFF_init(MPI_COMM_WORLD, MPI_INFO_NULL); MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); MPI_Comm_size(MPI_COMM_WORLD, &my_size); fprintf(stderr, "APP processes = %d, my rank is %d\n", my_size, my_rank); wdata1 = malloc (sizeof(int32_t)*nelem); rdata1 = malloc (sizeof(int32_t)*nelem); for(i=0;i 0); /* create 1-D dataspace with 60 elements */ dims [0] = nelem; sid = H5Screate_simple(1, dims, NULL); dtid = H5Tcopy(H5T_STD_I32LE); /* acquire container version 1 - EXACT. This can be asynchronous, but here we need the acquired ID right after the call to start the transaction so we make synchronous. */ if(0 == my_rank) { version = 1; rid1 = H5RCacquire(file_id, &version, H5P_DEFAULT, H5_EVENT_STACK_NULL); } MPI_Bcast(&version, 1, MPI_UINT64_T, 0, MPI_COMM_WORLD); assert(1 == version); if (my_rank != 0) rid1 = H5RCcreate(file_id, version); /* start transaction 1 with default Leader/Delegate model. Leader which is rank 0 here starts the transaction. It can be asynchronous, but we make it synchronous here so that the Leader can tell its delegates that the transaction is started. */ if(0 == my_rank) { hid_t rid_temp; /* create transaction object */ tid1 = H5TRcreate(file_id, rid1, (uint64_t)2); assert(tid1); ret = H5TRstart(tid1, H5P_DEFAULT, e_stack); assert(0 == ret); /* create objects */ gid = H5Gcreate_ff(file_id, "G1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT, tid1, e_stack); assert(gid >= 0); did = H5Dcreate_ff(gid, "D1", dtid, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT, tid1, e_stack); assert(did >= 0); ret = H5Dwrite_ff(did, dtid, H5S_ALL, H5S_ALL, H5P_DEFAULT, wdata1, tid1, e_stack); assert(ret == 0); ret = H5Tcommit_ff(file_id, "DT1", dtid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT, tid1, e_stack); assert(ret == 0); map = H5Mcreate_ff(file_id, "MAP1", H5T_STD_I32LE, H5T_STD_I32LE, H5P_DEFAULT,H5P_DEFAULT,H5P_DEFAULT, tid1, e_stack); assert(map >= 0); /* write some KV pairs to each map object. */ { key = 1; value = 1000; ret = H5Mset_ff(map, H5T_STD_I32LE, &key, H5T_STD_I32LE, &value, H5P_DEFAULT, tid1, e_stack); assert(ret == 0); } ret = H5TRfinish(tid1, H5P_DEFAULT, &rid_temp, e_stack); assert(0 == ret); /* wait on all requests and print completion status */ H5ESget_count(e_stack, &num_events); H5ESwait_all(e_stack, &status); H5ESclear(e_stack); printf("%d events in event stack. Completion status = %d\n", num_events, status); /* Close transaction object. Local op */ ret = H5TRclose(tid1); assert(0 == ret); /* create transaction object */ tid2 = H5TRcreate(file_id, rid_temp, (uint64_t)3); assert(tid2); ret = H5TRstart(tid2, H5P_DEFAULT, e_stack); assert(0 == ret); ret = H5Oset_comment_ff(gid, "Testing Object Comment", tid2, e_stack); assert(ret == 0); ret = H5TRfinish(tid2, H5P_DEFAULT, &rid2, e_stack); assert(0 == ret); assert(H5Gclose_ff(gid, e_stack) == 0); assert(H5Mclose_ff(map, e_stack) == 0); assert(H5Tclose_ff(dtid, e_stack) == 0); assert(H5Dclose_ff(did, e_stack) == 0); /* release container version 2. */ ret = H5RCrelease(rid_temp, e_stack); assert(0 == ret); ret = H5RCclose(rid_temp); assert(0 == ret); version = 3; } /* release container version 1. */ if(0 == my_rank) { ret = H5RCrelease(rid1, e_stack); assert(0 == ret); } /* wait on all requests and print completion status */ H5ESget_count(e_stack, &num_events); H5ESwait_all(e_stack, &status); H5ESclear(e_stack); printf("%d events in event stack. Completion status = %d\n", num_events, status); if(0 == my_rank) { /* Close transaction object. Local op */ ret = H5TRclose(tid2); assert(0 == ret); } MPI_Barrier(MPI_COMM_WORLD); /* Process 0 tells other procs that container version 2 is acquired */ MPI_Bcast(&version, 1, MPI_UINT64_T, 0, MPI_COMM_WORLD); assert(3 == version); /* other processes just create a read context object; no need to acquire it */ if(0 != my_rank) { rid2 = H5RCcreate(file_id, version); assert(rid2 > 0); } gid = H5Oopen_ff(file_id, "G1", H5P_DEFAULT, rid2); assert(gid); dtid = H5Oopen_ff(file_id, "DT1", H5P_DEFAULT, rid2); assert(dtid); did = H5Oopen_ff(gid,"D1", H5P_DEFAULT, rid2); assert(did); map = H5Oopen_ff(file_id,"MAP1", H5P_DEFAULT, rid2); assert(map); if(0 == my_rank) { ret = H5RCpersist(rid2, H5_EVENT_STACK_NULL); assert(ret == 0); } MPI_Barrier(MPI_COMM_WORLD); if((my_size > 1 && 1 == my_rank) || (my_size == 1 && 0 == my_rank)) { ret = H5Tevict_ff(dtid, 3, H5P_DEFAULT, H5_EVENT_STACK_NULL); assert(0 == ret); ret = H5Devict_ff(did, 3, H5P_DEFAULT, H5_EVENT_STACK_NULL); assert(0 == ret); ret = H5Mevict_ff(map, 3, H5P_DEFAULT, H5_EVENT_STACK_NULL); assert(0 == ret); ret = H5Gevict_ff(gid, 3, H5P_DEFAULT, H5_EVENT_STACK_NULL); assert(0 == ret); /* see if we can read after evicting */ ret = H5Dread_ff(did, dtid, H5S_ALL, H5S_ALL, H5P_DEFAULT, rdata1, rid2, H5_EVENT_STACK_NULL); assert(ret == 0); printf("Read Data1: "); for(i=0;i= 0); MPI_Finalize(); return 0; }