static errval_t cow_init(size_t bufsize, size_t granularity, struct cnoderef *cow_cn, size_t *frame_count) { assert(cow_cn); assert(frame_count); errval_t err; struct capref frame, cncap; struct cnoderef cnode; // get RAM cap bufsize = (bufsize / granularity + 1) * granularity; err = slot_alloc(&frame); assert(err_is_ok(err)); size_t rambits = log2floor(bufsize); debug_printf("bits = %zu\n", rambits); err = ram_alloc(&frame, rambits); assert(err_is_ok(err)); // calculate #slots cslot_t cap_count = bufsize / granularity; cslot_t slots; // get CNode err = cnode_create(&cncap, &cnode, cap_count, &slots); assert(err_is_ok(err)); assert(slots >= cap_count); // retype RAM into Frames struct capref first_frame = (struct capref) { .cnode = cnode, .slot = 0 }; err = cap_retype(first_frame, frame, ObjType_Frame, log2floor(granularity)); assert(err_is_ok(err)); err = cap_destroy(frame); assert(err_is_ok(err)); *frame_count = slots; *cow_cn = cnode; return SYS_ERR_OK; } // create cow-enabled vregion & backing // Can copy-on-write in granularity-sized chunks static errval_t vspace_map_one_frame_cow(void **buf, size_t size, struct capref frame, vregion_flags_t flags, struct memobj **memobj, struct vregion **vregion, size_t granularity) { errval_t err; if (!memobj) { memobj = malloc(sizeof(*memobj)); } assert(memobj); if (!vregion) { vregion = malloc(sizeof(*vregion)); } assert(vregion); err = vspace_map_anon_attr(buf, memobj, vregion, size, &size, flags); assert(err_is_ok(err)); size_t chunks = size / granularity; cslot_t slots; struct capref cncap; struct cnoderef cnode; err = cnode_create(&cncap, &cnode, chunks, &slots); assert(err_is_ok(err)); assert(slots >= chunks); struct capref fc = (struct capref) { .cnode = cnode, .slot = 0 }; for (int i = 0; i < chunks; i++) { err = cap_copy(fc, frame); assert(err_is_ok(err)); err = (*memobj)->f.fill_foff(*memobj, i * granularity, fc, granularity, i*granularity); assert(err_is_ok(err)); err = (*memobj)->f.pagefault(*memobj, *vregion, i * granularity, 0); assert(err_is_ok(err)); fc.slot++; } return SYS_ERR_OK; } int main(int argc, char *argv[]) { errval_t err; struct capref frame; size_t retsize; void *vbuf; struct vregion *vregion; uint8_t *buf; debug_printf("%s:%d\n", __FUNCTION__, __LINE__); err = frame_alloc(&frame, BUFSIZE, &retsize); assert(retsize >= BUFSIZE); if (err_is_fail(err)) { debug_printf("frame_alloc: %s\n", err_getstring(err)); return 1; } debug_printf("%s:%d: %zu\n", __FUNCTION__, __LINE__, retsize); // setup region err = vspace_map_one_frame_attr(&vbuf, retsize, frame, VREGION_FLAGS_READ_WRITE, NULL, &vregion); if (err_is_fail(err)) { debug_printf("vspace_map: %s\n", err_getstring(err)); return 1; } debug_printf("vaddr: %p\n", vbuf); // write stuff to region buf = vbuf; debug_printf("%s:%d: %p, %lu pages\n", __FUNCTION__, __LINE__, buf, BUFSIZE / BASE_PAGE_SIZE); memset(buf, 0xAA, BUFSIZE); debug_printf("%s:%d\n", __FUNCTION__, __LINE__); // create cow copy // setup exception handler thread_set_exception_handler(handler, NULL, ex_stack, ex_stack+EX_STACK_SIZE, NULL, NULL); assert(err_is_ok(err)); debug_printf("%s:%d\n", __FUNCTION__, __LINE__); err = cow_init(BUFSIZE, BASE_PAGE_SIZE, &cow_frames, &cow_frame_count); assert(err_is_ok(err)); // create r/o copy of region and tell exception handler bounds debug_printf("%s:%d\n", __FUNCTION__, __LINE__); err = vspace_map_one_frame_cow(&cow_vbuf, retsize, frame, VREGION_FLAGS_READ, NULL, &cow_vregion, BASE_PAGE_SIZE); if (err_is_fail(err)) { debug_printf("vspace_map: %s\n", err_getstring(err)); return 1; } debug_printf("cow_vaddr: %p\n", cow_vbuf); // do stuff cow copy uint8_t *cbuf = cow_vbuf; for (int i = 0; i < BUFSIZE / BASE_PAGE_SIZE; i+=2) { cbuf[i * BASE_PAGE_SIZE + 1] = 0x55; } // verify results for (int i = 0; i < BUFSIZE / BASE_PAGE_SIZE; i++) { printf("page %d\n", i); printf("buf[0] = %d; cbuf[0] = %d\n", buf[i*BASE_PAGE_SIZE], cbuf[i*BASE_PAGE_SIZE]); printf("buf[1] = %d; cbuf[1] = %d\n", buf[i*BASE_PAGE_SIZE+1], cbuf[i*BASE_PAGE_SIZE+1]); } debug_dump_hw_ptables(); return EXIT_SUCCESS; }
int main(int argc, char **argv) { int modes = 0; int collective = GETENVINT("COW_HDF5_COLLECTIVE", 0); int chunk = GETENVINT("COW_HDF5_CHUNK", 1); modes |= GETENVINT("COW_NOREOPEN_STDOUT", 0) ? COW_NOREOPEN_STDOUT : 0; modes |= GETENVINT("COW_DISABLE_MPI", 0) ? COW_DISABLE_MPI : 0; cow_init(argc, argv, modes); if (argc == 3) { printf("running on input file %s\n", argv[1]); } else { printf("usage: $> mhdstats infile.h5 outfile.h5\n"); cow_finalize(); return 0; } printf("COW_HDF5_COLLECTIVE: %d\n", collective); char *finp = argv[1]; char *fout = argv[2]; int derivfields = 0; int energies = 1; cow_domain *domain = cow_domain_new(); cow_domain_readsize(domain, finp, "prim/vx"); cow_domain_setguard(domain, 2); cow_domain_commit(domain); cow_domain_setchunk(domain, chunk); cow_domain_setcollective(domain, collective); cow_domain_setalign(domain, 4*KILOBYTES, 4*MEGABYTES); cow_dfield *vel = cow_dfield_new2(domain, "prim"); cow_dfield *mag = cow_dfield_new2(domain, "prim"); cow_dfield *rho = cow_dfield_new2(domain, "prim"); cow_dfield *pre = cow_dfield_new2(domain, "prim"); cow_dfield_addmember(vel, "vx"); cow_dfield_addmember(vel, "vy"); cow_dfield_addmember(vel, "vz"); cow_dfield_addmember(mag, "Bx"); cow_dfield_addmember(mag, "By"); cow_dfield_addmember(mag, "Bz"); cow_dfield_addmember(rho, "rho"); cow_dfield_addmember(pre, "pre"); // really the internal energy here cow_dfield_commit(vel); cow_dfield_commit(mag); cow_dfield_commit(rho); cow_dfield_commit(pre); cow_dfield_read(vel, finp); cow_dfield_read(mag, finp); cow_dfield_read(rho, finp); cow_dfield_read(pre, finp); if (derivfields) { cow_dfield *divB = cow_scalarfield(domain, "divB"); cow_dfield *divV = cow_scalarfield(domain, "divV"); cow_dfield *curlB = cow_vectorfield(domain, "curlB"); cow_dfield *curlV = cow_vectorfield(domain, "curlV"); cow_dfield *vcrossB = cow_vectorfield(domain, "vcrossB"); cow_dfield *curlBdotvcrossB = cow_scalarfield(domain, "curlBdotvcrossB"); cow_dfield *curlBdotB = cow_scalarfield(domain, "curlBdotB"); cow_dfield *vcrossBcrossB = cow_vectorfield(domain, "vcrossBcrossB"); cow_dfield *divvcrossBcrossB = cow_scalarfield(domain, "divvcrossBcrossB"); cow_dfield_transform(divB, &mag, 1, divcorner, NULL); cow_dfield_transform(divV, &vel, 1, div5, NULL); cow_dfield_transform(curlB, &mag, 1, curl, NULL); cow_dfield_transform(curlV, &vel, 1, curl, NULL); struct cow_dfield *vcrossBargs[2] = { vel, mag }; struct cow_dfield *vcrossBcrossBargs[2] = { vel, vcrossB }; struct cow_dfield *curlBdotBargs[2] = { curlB, mag }; struct cow_dfield *curlBdotvcrossBargs[2] = { curlB, vcrossB }; cow_dfield_transform(vcrossB, vcrossBargs, 2, crossprod, NULL); cow_dfield_transform(vcrossBcrossB, vcrossBcrossBargs, 2, crossprod, NULL); cow_dfield_transform(curlBdotvcrossB, curlBdotvcrossBargs, 2, dotprod, NULL); cow_dfield_transform(curlBdotB, curlBdotBargs, 2, dotprod, NULL); cow_dfield_transform(divvcrossBcrossB, &vcrossBcrossB, 1, div5, NULL); make_hist(divB, take_elem0, fout, NULL); make_hist(divV, take_elem0, fout, NULL); make_hist(mag, take_sqr3, fout, "B2"); make_hist(curlB, take_mag3, fout, NULL); make_hist(curlV, take_mag3, fout, NULL); make_hist(curlBdotvcrossB, take_elem0, fout, NULL); make_hist(curlBdotB, take_elem0, fout, NULL); make_hist(divvcrossBcrossB, take_elem0, fout, NULL); cow_dfield_del(divB); cow_dfield_del(divV); cow_dfield_del(curlB); cow_dfield_del(curlV); cow_dfield_del(vcrossB); cow_dfield_del(curlBdotvcrossB); cow_dfield_del(curlBdotB); cow_dfield_del(vcrossBcrossB); cow_dfield_del(divvcrossBcrossB); } if (energies) { cow_dfield *kinE = cow_scalarfield(domain, "kinE"); cow_dfield *magE = cow_scalarfield(domain, "magE"); cow_dfield *intE = cow_scalarfield(domain, "intE"); struct cow_dfield *kinEargs[2] = { rho, vel }; cow_dfield_transform(kinE, kinEargs, 2, kinEtrans, NULL); cow_dfield_transform(magE, &mag, 1, magEtrans, NULL); cow_dfield_transform(intE, &pre, 1, take_elem0, NULL); make_hist(kinE, take_elem0, fout, NULL); make_hist(magE, take_elem0, fout, NULL); make_hist(intE, take_elem0, fout, NULL); cow_dfield_del(kinE); cow_dfield_del(magE); cow_dfield_del(intE); } cow_dfield_del(rho); cow_dfield_del(pre); cow_dfield_del(vel); cow_dfield_del(mag); cow_domain_del(domain); cow_finalize(); return 0; }
int main(int argc, char **argv) { int modes = 0; int collective = GETENVINT("COW_HDF5_COLLECTIVE", 0); int chunk = GETENVINT("COW_HDF5_CHUNK", 1); modes |= GETENVINT("COW_NOREOPEN_STDOUT", 0) ? COW_NOREOPEN_STDOUT : 0; modes |= GETENVINT("COW_DISABLE_MPI", 0) ? COW_DISABLE_MPI : 0; cow_init(argc, argv, modes); if (argc == 3) { printf("running on input file %s\n", argv[1]); } else { printf("usage: $> srhdhist infile.h5 outfile.h5\n"); cow_finalize(); return 0; } printf("COW_HDF5_COLLECTIVE: %d\n", collective); char *finp = argv[1]; char *fout = argv[2]; cow_domain *domain = cow_domain_new(); cow_dfield *vel = cow_dfield_new2(domain, "prim"); cow_domain_setndim(domain, 3); cow_domain_setguard(domain, 2); cow_domain_setsize(domain, 0, 16); cow_domain_setsize(domain, 1, 16); cow_domain_setsize(domain, 2, 16); cow_domain_commit(domain); cow_domain_setchunk(domain, chunk); cow_domain_setcollective(domain, collective); cow_domain_setalign(domain, 4*KILOBYTES, 4*MEGABYTES); cow_dfield_addmember(vel, "vx"); cow_dfield_addmember(vel, "vy"); cow_dfield_addmember(vel, "vz"); cow_dfield_commit(vel); cow_dfield_read(vel, finp); cow_fft_pspecvecfield2(vel, fout, "pspec"); cow_dfield *dil = cow_dfield_dup(vel); cow_dfield *sol = cow_dfield_dup(vel); cow_dfield_setname(dil, "dil"); cow_dfield_setname(sol, "sol"); cow_fft_helmholtzdecomp(sol, COW_PROJECT_OUT_DIV); cow_fft_helmholtzdecomp(dil, COW_PROJECT_OUT_CURL); cow_dfield_write(dil, fout); cow_dfield_write(sol, fout); cow_dfield_write(vel, fout); cow_dfield_del(dil); cow_dfield_del(sol); cow_dfield_del(vel); cow_domain_del(domain); cow_finalize(); return 0; }