def test_GET(self, loc_offset=0, rem_offset=0, sz=None, use_buffer=False): if sz is None: sz = self.maxsz // 2 if self.physaddr: # Revisit: physaddr temporary local_addr = self.lmr.physaddr else: local_addr = self.lmm_v local_addr += loc_offset rem_addr = self.rmr.req_addr + rem_offset get = zhpe.xdm_cmd() get.opcode = zhpe.XDM_CMD.GET | zhpe.XDM_CMD.FENCE get.getput.size = sz get.getput.read_addr = rem_addr get.getput.write_addr = local_addr if self.verbosity: print('test_GET: local_addr={:#x}, sz={}, rem_addr={:#x}'.format( local_addr, sz, rem_addr)) start = time.monotonic() if use_buffer == True: self.xdm.buffer_cmd(get) else: self.xdm.queue_cmd(get) try: cmpl = self.xdm.get_cmpl() end = time.monotonic() if self.verbosity: print('GET cmpl: {}'.format(cmpl)) except XDMcompletionError as e: print('GET cmpl error: {} {:#x} request_id {:#x}'.format( e, e.status, e.request_id)) # Revisit: need fence/sync/flush to ensure visibility? if self.rmm: rmm_off = self.pg_off + rem_offset lmm_sha256 = hashlib.sha256(self.lmm[loc_offset:loc_offset + sz]).hexdigest() if self.verbosity: print('lmm sha256 after GET="{}"'.format(lmm_sha256)) rmm_sha256 = hashlib.sha256(self.rmm[rmm_off:rmm_off + sz]).hexdigest() if self.verbosity: print('rmm[{}:{}] sha256="{}"'.format(rmm_off, rmm_off + sz, rmm_sha256)) if lmm_sha256 != rmm_sha256: print('GET sha mismatch: {} != {}'.format( lmm_sha256, rmm_sha256)) # Revisit: temporary debug print('lmm[{}:{}]="{}"'.format( loc_offset, loc_offset + 100, self.lmm[loc_offset:loc_offset + 100])) print('rmm[{}:{}]="{}"'.format( rmm_off, rmm_off + 100, self.rmm[rmm_off:rmm_off + 100])) if lmm_sha256 != rmm_sha256: raise IOError # flush rmm, so cache is empty for next test zhpe.pmem_flush(self.rmm_v + rmm_off, sz) # end if self.rmm secs = end - start if self.verbosity: print('GET of {} bytes in {} seconds = {} GiB/s'.format( get.getput.size, secs, get.getput.size / (secs * self.sz1G)))
def test_GET_IMM(self, offset=0, sz=len1_2, use_buffer=False): if sz < 1 or sz > 32: raise ValueError rem_addr = self.rmr.req_addr + offset get_imm = zhpe.xdm_cmd() get_imm.opcode = zhpe.XDM_CMD.GET_IMM get_imm.getput_imm.size = sz get_imm.getput_imm.rem_addr = rem_addr if self.verbosity: print('test_GET_IMM: sz={}, offset={}, rem_addr={:#x}'.format( sz, offset, rem_addr)) if use_buffer == True: self.xdm.buffer_cmd(get_imm) else: self.xdm.queue_cmd(get_imm) try: cmpl = self.xdm.get_cmpl() if self.verbosity: print('GET_IMM cmpl: {}'.format(cmpl.getimm)) except XDMcompletionError as e: print('GET_IMM cmpl error: {} {:#x} request_id {:#x}'.format( e, e.status, e.request_id)) if self.rmm is not None: rmm_off = self.pg_off + offset if bytes(cmpl.getimm.payload[0:sz]) != self.rmm[rmm_off:rmm_off + sz]: raise IOError # Revisit: check that payload bytes beyond sz are 0 # flush rmm, so cache is empty for next test zhpe.pmem_flush(self.rmm_v + rmm_off, sz)
def test_PUT_IMM(self, data=str3, offset=len1_2 + 1, use_buffer=False): sz = len(data) if sz < 1 or sz > 32: raise ValueError rem_addr = self.rmr.req_addr + offset put_imm = zhpe.xdm_cmd() put_imm.opcode = zhpe.XDM_CMD.PUT_IMM put_imm.getput_imm.size = sz put_imm.getput_imm.rem_addr = rem_addr put_imm.getput_imm.payload[0:sz] = data if self.verbosity: print('test_PUT_IMM: data={}, sz={}, offset={}, rem_addr={:#x}'. format(data, sz, offset, rem_addr)) if use_buffer == True: self.xdm.buffer_cmd(put_imm) else: self.xdm.queue_cmd(put_imm) try: cmpl = self.xdm.get_cmpl() if self.verbosity: print('PUT_IMM cmpl: {}'.format(cmpl)) except XDMcompletionError as e: print('PUT_IMM cmpl error: {} {:#x} request_id {:#x}'.format( e, e.status, e.request_id)) # Revisit: need fence/sync to ensure visibility? if self.rmm is not None: rmm_off = self.pg_off + offset if self.verbosity: print('rmm[{}:{}] after PUT_IMM="{}"'.format( rmm_off, rmm_off + sz, self.rmm[rmm_off:rmm_off + sz].decode())) if self.rmm[rmm_off:rmm_off + sz] != data: raise IOError # flush rmm, so cache is empty for next test zhpe.pmem_flush(self.rmm_v + rmm_off, sz)
def FAM_tests(self, gcid=0x40, size=2 << 20): # default CID for Carbon is 0x40 and create a ZUUID fam_zuu = zuuid(gcid) if args.verbosity: print('FAM zuuid={}'.format(fam_zuu)) # Do a UUID_IMPORT with the ZHPE_IS_FAM flag set conn.do_UUID_IMPORT(fam_zuu, 1, None) # RMR_IMPORT the FAM at address 0 and size 2M sz2M = 2 << 20 FAMaccess = (zhpe.MR.GET_REMOTE | zhpe.MR.PUT_REMOTE | zhpe.MR.INDIVIDUAL | zhpe.MR.REQ_CPU) self.fam_rmr = conn.do_RMR_IMPORT(fam_zuu, 0, size, FAMaccess) # Do load/store to FAM at address 0 self.fam_rmm = mmap.mmap(f.fileno(), size, offset=fam_rmr.offset) self.fam_v, self.fam_l = zhpe.mmap_vaddr_len(self.fam_rmm) for off in range(0, 64, 7): self.test.load_store(offset=off, use_fam=True) if args.fam: fam_zuu = zuuid(gcid=args.fam_gcid) print('FAM zuuid={}'.format(fam_zuu)) # Do a UUID_IMPORT with the ZHPE_IS_FAM flag set conn.do_UUID_IMPORT(fam_zuu, UU.IS_FAM, None) # RMR_IMPORT the FAM at address 0 and size 2M if args.load_store: fam_rmr = conn.do_RMR_IMPORT(fam_zuu, 0, sz2M, MR.GRPRIC) # Do load/store to FAM fam_rmm = mmap.mmap(f.fileno(), sz2M, offset=fam_rmr.offset) fam_v, fam_l = zhpe.mmap_vaddr_len(fam_rmm) fam_rmm[0:len1] = str1 fam_rmm[len1:len1_2] = str2 # flush writes, so reads will see new data zhpe.pmem_flush(fam_v, len1_2) else: fam_rmr = conn.do_RMR_IMPORT(fam_zuu, 0, sz2M, MR.GRPRI) # do an XDM command to get the data back and check it get_imm = zhpe.xdm_cmd() get_imm.opcode = zhpe.XDM_CMD.GET_IMM get_imm.getput_imm.size = len1_2 get_imm.getput_imm.rem_addr = fam_rmr.req_addr xdm.queue_cmd(get_imm) try: get_imm_cmpl = xdm.get_cmpl() if args.verbosity: print('GET_IMM cmpl: {}'.format(get_imm_cmpl.getimm)) # Verify the payload is what we expect if args.load_store: retstr = bytearray(get_imm_cmpl.getimm.payload[0:len1_2]) if retstr == str1 + str2: if args.verbosity: print('FAM comparision PASS') else: print('FAM comparision FAIL') except XDMcompletionError as e: print('GET_IMM cmpl error: {} {:#x} request_id {:#x}'.format( e, e.status, e.request_id))
def test_load_store(self, offset=0): if self.rmm is None: if self.verbosity: print('test_load_store: skipping - no load/store rmm') return # Revisit: this assumes rmm is mapped writable rmm_off = self.pg_off + offset if self.verbosity: print('test_load_store: offset={}, rmm_off={}, rmm_v={:#x}'.format( offset, rmm_off, self.rmm_v)) self.rmm[rmm_off:rmm_off + Tests.len1] = Tests.str1 self.rmm[rmm_off + Tests.len1:rmm_off + Tests.len1_2] = Tests.str2 # flush rmm writes, so rmm reads will generate new Gen-Z packets zhpe.pmem_flush(self.rmm_v + rmm_off, Tests.len1_2) expected = Tests.str1 + Tests.str2 if self.verbosity: print('rmm[{}:{}] after load/store="{}"'.format( rmm_off, rmm_off + Tests.len1_2, self.rmm[rmm_off:rmm_off + Tests.len1_2].decode())) if self.rmm[rmm_off:rmm_off + Tests.len1_2] != expected: raise IOError # flush rmm again, so cache is empty for next test zhpe.pmem_flush(self.rmm_v + rmm_off, Tests.len1_2)
def main(): '''summary of MR_REG regions: name | access | args | mmap | v | sz | -----------+----------+----------+-------+-----------+-----+ rsp |GPI |requester | mm | v | 4K rsp2 |GRPRI |responder | mm2 | v2 | 4K rsp2M |GRPRI |always | mm2M | v2M+0x1242| 2M-0x5000 rsp2M_l |GP |always | mm2M | v2M | 2M rsp2M_b |GRPRI |responder | mm2M | v2M | 2M rsp2M_r |GPGRPRI |loopback | mm2M | v2M | 2M summary of RMR_IMPORT regions: name | access | args |memreg | mmap | rmr sz | mmap sz | -----------+----------+----------+-------+-------+--------+---------+ rsp_rmr |GRPRI |loopback |rsp2M_b|--- | 4K | -- | rsp_rmr_c |GRPRIC |load_store|rsp2M_b|rmm | 2M | 4K | rsp_rmr2 |GRPRIC |load_store|rsp2 |rmm2 | 4K | 4K | rsp_rmr2 |GRPRI |else |rsp2 |--- | 4K | -- | rsp_rmr_ro |GRIC |load_store|rsp2 |rmm2_ro| 4K | 4K | rsp_rmr2M |GRPRIC |load_store|rsp2M_r|rmm2M | 2M | 2M | rsp_rmr2M |GRPRI |else |rsp2M_r|--- | 2M | -- | fam_rmr |GRPRIC |fam+ld_st | --- |fam_rmm| 2M | 2M | ''' global args args = parse_args() if args.verbosity: print('pid={}'.format(os.getpid())) nodes = [item for item in args.nodes.split(',')] if args.nodes else [] datasize = os.path.getsize(args.datafile) bigsize = os.path.getsize(args.bigfile) hugesize = os.path.getsize(args.hugefile) if 3 * datasize > bigsize: print('3*datafile size (3*{}) > bigfile size ({})'.format( datasize, bigsize)) sys.exit(1) modp = ModuleParams() with open(args.devfile, 'rb+', buffering=0) as f: conn = zhpe.Connection(f, args.verbosity) init = conn.do_INIT() gcid = init.uuid.gcid if args.verbosity: print('do_INIT: uuid={}, gcid={}'.format(init.uuid, init.uuid.gcid_str)) # doing a 2nd INIT should fail exc = False try: bad = conn.do_INIT() except OSError: exc = True if exc: if args.verbosity: print('do_INIT: got expected error on 2nd INIT') else: print('fail: no error on 2nd INIT') if args.loopback and modp.genz_loopback == 0: print( 'Configuration error - loopback test requested but driver has genz_loopback=0' ) if args.loopback and modp.genz_loopback: zuu = zuuid(gcid=gcid) if args.bringup: conn.do_UUID_IMPORT(zuu, UU.IS_FAM, None) else: conn.do_UUID_IMPORT(zuu, 0, None) sz4K = 4096 sz2M = 2 << 20 sz1G = 1 << 30 if args.requester: mm = mmap.mmap(-1, sz4K) v, l = zhpe.mmap_vaddr_len(mm) rsp = conn.do_MR_REG(v, l, MR.GPI) # req: GET/PUT, 4K # register the same thing memory twice to force EEXIST try: bad = conn.do_MR_REG(v, l, MR.GPI) # req: GET/PUT, 4K except OSError: exc = True if exc: if args.verbosity: print('do_MR_REG: got expected error on 2nd MR_REG') else: print('fail: no error on 2nd MR_REG') if args.responder or args.loopback: mm2 = mmap.mmap(-1, sz4K) mm2[0:sz4K] = os.urandom(sz4K) # fill with random bytes v2, l2 = zhpe.mmap_vaddr_len(mm2) rsp2 = conn.do_MR_REG(v2, l2, MR.GRPRI) # rsp: GET_REM/PUT_REM, 4K data = open(args.datafile, 'rb') mmdata = mmap.mmap(data.fileno(), 0, access=mmap.ACCESS_READ) datasha256 = hashlib.sha256(mmdata[0:datasize]).hexdigest() if args.verbosity: print('datafile sha256={}'.format(datasha256)) # Revisit: using a hugepage file to guarantee a physically contiguous # region until the IOMMU works in the sim f2M = open(args.bigfile, 'rb+') mm2M = mmap.mmap(f2M.fileno(), 0, access=mmap.ACCESS_WRITE) mm2M[0:datasize] = mmdata[0:datasize] if args.huge: print('opening hugefile "{}"'.format(args.hugefile)) f1G = open(args.hugefile, 'rb+') print('mmapping hugefile') mm1G = mmap.mmap(f1G.fileno(), 0, access=mmap.ACCESS_WRITE) print('initializing hugefile with random data') mm1G[0:hugesize // 2] = os.urandom(hugesize // 2) v1G, l1G = zhpe.mmap_vaddr_len(mm1G) mmdata.close() data.close() v2M, l2M = zhpe.mmap_vaddr_len(mm2M) rsp2M = conn.do_MR_REG(v2M + 0x1242, l2M - 0x5000, MR.GRPRI) # GET_REM/PUT_REM, 2M-0x5000 rsp2M_l = conn.do_MR_REG(v2M, l2M, MR.GP) # GET/PUT, 2M lmr = rsp2M_l lmm = mm2M if args.responder or args.loopback: rsp2M_b = conn.do_MR_REG(v2M, l2M, MR.GRPRI) # rsp: GET_REM/PUT_REM, 2M if args.loopback and modp.genz_loopback: rsp_rmr = conn.do_RMR_IMPORT(zuu, rsp2M_b.rsp_zaddr, sz4K, MR.GRPRI) # individual, cpu-visible, 2M mapping allowing # GET/PUT/GET_REMOTE/PUT_REMOTE rsp2M_r = conn.do_MR_REG(v2M, sz2M, MR.GPGRPRI) # loop: ALL, 2M if args.load_store: rsp_rmr_c = conn.do_RMR_IMPORT(zuu, rsp2M_b.rsp_zaddr, sz4K, MR.GRPRIC) rmm = mmap.mmap(f.fileno(), sz4K, offset=rsp_rmr_c.offset) rsp_rmr2 = conn.do_RMR_IMPORT(zuu, rsp2.rsp_zaddr, sz4K, MR.GRPRIC) rmm2 = mmap.mmap(f.fileno(), sz4K, offset=rsp_rmr2.offset) v_rmm2, l_rmm2 = zhpe.mmap_vaddr_len(rmm2) rsp_rmr_ro = conn.do_RMR_IMPORT(zuu, rsp2.rsp_zaddr, sz4K, MR.GRIC) rmm2_ro = mmap.mmap(f.fileno(), sz4K, offset=rsp_rmr_ro.offset) v_rmm2_ro, l_rmm2_ro = zhpe.mmap_vaddr_len(rmm2_ro) # Revisit: why does trying to write rmm2_ro (to test that it's # really RO) cause a python3 segfault? # rmm2_ro[0:3] = b'Joe' rsp_rmr2M = conn.do_RMR_IMPORT(zuu, rsp2M_r.rsp_zaddr, sz2M, MR.GRPRIC) rmm2M = mmap.mmap(f.fileno(), sz2M, offset=rsp_rmr2M.offset) else: rsp_rmr2 = conn.do_RMR_IMPORT(zuu, rsp2.rsp_zaddr, sz4K, MR.GRPRI) rsp_rmr2M = conn.do_RMR_IMPORT(zuu, rsp2M_r.rsp_zaddr, sz2M, MR.GRPRI) xdm = zhpe.XDM(conn, 256, 256, slice_mask=0x1) rdm = zhpe.RDM(conn, 1024, slice_mask=0x2) nop = zhpe.xdm_cmd() nop.opcode = zhpe.XDM_CMD.NOP | zhpe.XDM_CMD.FENCE if args.huge: # individual, 1G mapping allowing # GET/PUT/GET_REMOTE/PUT_REMOTE (not cpu-visible) mm1Gsha256h = hashlib.sha256(mm1G[0:hugesize // 2]).hexdigest() rsp1G = conn.do_MR_REG(v1G, sz1G, MR.GPGRPRI) # huge: ALL, 1G lmr = rsp1G lmm = mm1G if args.net: if args.verbosity: print('Starting networking - this is very slow in sim') import network as net factory = net.MyFactory(conn, lmr, lmm, xdm, args.verbosity, args.bringup, args.load_store, args.requester, args.responder, modp.no_iommu) try: factory.setup(args.port, nodes) except net.CannotListenError: print('Error: Address in use') # str1+str2 & str3 must fit in a 32-byte GET_IMM/PUT_IMM str1 = b'J/B/S ' str2 = b'making PFS awesome!' str3 = b'PF Slice is awesome too!' # str4 & str5 must fit in a 52-byte ENQA str4 = b'But sometimes, madness is the only path forward.' str5 = b'Interrupts are distractions.' len1 = len(str1) len2 = len(str2) len3 = len(str3) len4 = len(str4) len5 = len(str5) len1_2 = len1 + len2 mm2[0:len1] = str1 if args.verbosity: print('mm2 (initial)="{}"'.format(mm2[0:len1].decode())) if args.loopback and modp.genz_loopback: if args.load_store: if args.verbosity: print('rmm2 (remote)="{}"'.format(rmm2[0:len1].decode())) if mm2[0:len1] != rmm2[0:len1]: print('Error: mm2 "{}" != rmm2 "{}"'.format( mm2[0:len1].decode(), rmm2[0:len1].decode())) rmm2[len1:len1_2] = str2 # flush rmm2 writes, so mm2 reads will see new data zhpe.pmem_flush(v_rmm2 + len1, len2) if args.verbosity: print('mm2 after remote update="{}"'.format( mm2[0:len1_2].decode())) if mm2[0:len1_2] != rmm2[0:len1_2]: print('Error: mm2 "{}" != rmm2 "{}"'.format( mm2[0:len1_2].decode(), rmm2[0:len1_2].decode())) else: # just write mm2 directly, so it has the right stuff mm2[len1:len1_2] = str2 sync = zhpe.xdm_cmd() sync.opcode = zhpe.XDM_CMD.SYNC | zhpe.XDM_CMD.FENCE xdm.buffer_cmd(nop) nop_cmpl = xdm.get_cmpl() if args.verbosity: print('NOP cmpl: {}'.format(nop_cmpl)) if args.keyboard: set_trace() if args.loopback and modp.genz_loopback: # test PUT_IMM put_imm_offset = len1_2 + 1 rem_addr = rsp_rmr2.req_addr + put_imm_offset put_imm = zhpe.xdm_cmd() put_imm.opcode = zhpe.XDM_CMD.PUT_IMM put_imm.getput_imm.size = len3 put_imm.getput_imm.rem_addr = rem_addr put_imm.getput_imm.payload[0:len3] = str3 if args.keyboard: set_trace() xdm.queue_cmd(put_imm) try: put_imm_cmpl = xdm.get_cmpl() if args.verbosity: print('PUT_IMM cmpl: {}'.format(put_imm_cmpl)) except XDMcompletionError as e: print('PUT_IMM cmpl error: {} {:#x} request_id {:#x}'.format( e, e.status, e.request_id)) if args.keyboard: set_trace() # Revisit: need fence/sync to ensure visibility if args.verbosity: print('mm2 after PUT_IMM="{}"'.format( mm2[put_imm_offset:put_imm_offset + len3].decode())) # Revisit: check that mm2 got str3 # test GET_IMM get_imm = zhpe.xdm_cmd() get_imm.opcode = zhpe.XDM_CMD.GET_IMM get_imm.getput_imm.size = len1_2 get_imm.getput_imm.rem_addr = rsp_rmr2.req_addr xdm.queue_cmd(get_imm) try: get_imm_cmpl = xdm.get_cmpl() if args.verbosity: print('GET_IMM cmpl: {}'.format(get_imm_cmpl.getimm)) except XDMcompletionError as e: print('GET_IMM cmpl error: {} {:#x} request_id {:#x}'.format( e, e.status, e.request_id)) if args.keyboard: set_trace() # test PUT put_offset = datasize if modp.no_iommu: local_addr = rsp2M_r.physaddr # Revisit: physaddr temporary else: local_addr = v2M rem_addr = rsp_rmr2M.req_addr + put_offset put = zhpe.xdm_cmd() put.opcode = zhpe.XDM_CMD.PUT | zhpe.XDM_CMD.FENCE put.getput.size = datasize put.getput.read_addr = local_addr put.getput.write_addr = rem_addr xdm.queue_cmd(put) try: put_cmpl = xdm.get_cmpl() if args.verbosity: print('PUT cmpl: {}'.format(put_cmpl)) except XDMcompletionError as e: print('PUT cmpl error: {} {:#x} request_id {:#x}'.format( e, e.status, e.request_id)) # Revisit: need fence/sync to ensure visibility mm2Msha256p = hashlib.sha256(mm2M[put_offset:put_offset + datasize]).hexdigest() if args.verbosity: print('mm2M sha256 after PUT="{}"'.format(mm2Msha256p)) if mm2Msha256p != datasha256: print('PUT sha mismatch: {} != {}'.format( datasha256, mm2Msha256p)) if args.keyboard: set_trace() # test GET+SYNC get_offset = 2 * datasize if modp.no_iommu: local_addr = rsp2M_r.physaddr + get_offset # Revisit: physaddr temporary else: local_addr = v2M + get_offset rem_addr = rsp_rmr2M.req_addr + put_offset get = zhpe.xdm_cmd() get.opcode = zhpe.XDM_CMD.GET | zhpe.XDM_CMD.FENCE get.getput.size = datasize get.getput.read_addr = rem_addr get.getput.write_addr = local_addr xdm.queue_cmds([get, sync]) try: get_cmpl = xdm.get_cmpl() if args.verbosity: print('GET cmpl: {}'.format(get_cmpl)) except XDMcompletionError as e: print('GET cmpl error: {} {:#x} request_id {:#x}'.format( e, e.status, e.request_id)) try: sync_cmpl = xdm.get_cmpl() if args.verbosity: print('SYNC cmpl: {}'.format(sync_cmpl)) except XDMcompletionError as e: print('SYNC cmpl error: {} {:#x} request_id {:#x}'.format( e, e.status, e.request_id)) mm2Msha256g = hashlib.sha256(mm2M[get_offset:get_offset + datasize]).hexdigest() if args.verbosity: print('mm2M sha256 after GET="{}"'.format(mm2Msha256g)) if mm2Msha256g != datasha256: print('GET sha mismatch: {} != {}'.format( datasha256, mm2Msha256g)) # Do the atomic tests at the 1M point in the 2M region atomic_offset = rsp_rmr2M.req_addr + 1048576 # test atomic 32 bit SWAP swap32 = zhpe.xdm_cmd() swap32.opcode = zhpe.XDM_CMD.ATM_SWAP swap32.atomic_one_op32.r = 1 # return a value swap32.atomic_one_op32.size = zhpe.ATOMIC_SIZE.SIZE_32BIT swap32.atomic_one_op32.rem_addr = atomic_offset swap32.atomic_one_op32.operand = 0x12345678 xdm.queue_cmd(swap32) try: swap32_cmpl = xdm.get_cmpl() if args.verbosity: print('SWAP32 cmpl: {}'.format(swap32_cmpl)) except XDMcompletionError as e: print('SWAP32 cmpl error: {} {:#x} request_id {:#x}'.format( e, e.status, e.request_id)) if args.verbosity: print('SWAP32 return value: {}'.format(swap32_cmpl.atomic32)) if args.keyboard: set_trace() # test the same atomic 32 bit SWAP to see if the prev val is now 0x12345678 swap32 = zhpe.xdm_cmd() swap32.opcode = zhpe.XDM_CMD.ATM_SWAP swap32.atomic_one_op32.r = 1 # return a value swap32.atomic_one_op32.size = zhpe.ATOMIC_SIZE.SIZE_32BIT swap32.atomic_one_op32.rem_addr = atomic_offset swap32.atomic_one_op32.operand = 0xDEADBEEF xdm.queue_cmd(swap32) try: swap32_cmpl = xdm.get_cmpl() if args.verbosity: print('SWAP32 cmpl: {}'.format(swap32_cmpl)) except XDMcompletionError as e: print('SWAP32 cmpl error: {} {:#x} request_id {:#x}'.format( e, e.status, e.request_id)) if args.verbosity: print('SWAP32 return value: {}'.format(swap32_cmpl.atomic32)) if swap32_cmpl.atomic32.retval != 0x12345678: print('FAIL: SWAP32: retval is {:#x} and should be 0x12345678'. format(swap32_cmpl.atomic32.retval)) if args.keyboard: set_trace() # test atomic 32 bit COMPARE AND SWAP - val is now 0xDEADBEEF cas32 = zhpe.xdm_cmd() cas32.opcode = zhpe.XDM_CMD.ATM_CAS cas32.atomic_two_op32.r = 1 # return a value cas32.atomic_two_op32.size = zhpe.ATOMIC_SIZE.SIZE_32BIT cas32.atomic_two_op32.rem_addr = atomic_offset cas32.atomic_two_op32.operand1 = 0xDEADBEEF cas32.atomic_two_op32.operand2 = 0xBDA11FED xdm.queue_cmd(cas32) try: cas32_cmpl = xdm.get_cmpl() if args.verbosity: print('CAS32 cmpl: {}'.format(cas32_cmpl)) except XDMcompletionError as e: print('CAS32 cmpl error: {} {:#x} request_id {:#x}'.format( e, e.status, e.request_id)) if args.verbosity: print('CAS32 return value: {}'.format(cas32_cmpl.atomic32)) if cas32_cmpl.atomic32.retval != 0xDEADBEEF: print('FAIL: CAS32: retval is {:#x} and should be 0xDEADBEEF'. format(cas32_cmpl.atomic32.retval)) if args.keyboard: set_trace() # test atomic 32 bit FETCH AND ADD - val is now 0xBDA11FED add32 = zhpe.xdm_cmd() add32.opcode = zhpe.XDM_CMD.ATM_ADD add32.atomic_one_op32.r = 1 # return a value add32.atomic_one_op32.size = zhpe.ATOMIC_SIZE.SIZE_32BIT add32.atomic_one_op32.rem_addr = atomic_offset add32.atomic_one_op32.operand = 0x12345678 xdm.queue_cmd(add32) try: add32_cmpl = xdm.get_cmpl() if args.verbosity: print('ADD32 cmpl: {}'.format(add32_cmpl)) except XDMcompletionError as e: print('ADD32 cmpl error: {} {:#x} request_id {:#x}'.format( e, e.status, e.request_id)) if args.verbosity: print('ADD32 return value: {}'.format(add32_cmpl.atomic32)) if add32_cmpl.atomic32.retval != 0xBDA11FED: print('FAIL: ADD32: retval is {:#x} and should be 0xBDA11FED'. format(add32_cmpl.atomic32.retval)) if args.keyboard: set_trace() # use SWAP to get the sum from the previous ADD32 swap32 = zhpe.xdm_cmd() swap32.opcode = zhpe.XDM_CMD.ATM_SWAP swap32.atomic_one_op32.r = 1 # return a value swap32.atomic_one_op32.size = zhpe.ATOMIC_SIZE.SIZE_32BIT swap32.atomic_one_op32.rem_addr = atomic_offset swap32.atomic_one_op32.operand = 0x0 xdm.queue_cmd(swap32) try: swap32_cmpl = xdm.get_cmpl() except XDMcompletionError as e: print('SWAP32 cmpl error: {} {:#x} request_id {:#x}'.format( e, e.status, e.request_id)) if swap32_cmpl.atomic32.retval != 0xCFD57665: print('FAIL: ADD32: retval is {:#x} and should be 0xCFD57665'. format(swap32_cmpl.atomic32.retval)) else: if args.verbosity: print('ADD32: PASS: sum is {:#x}'.format( swap32_cmpl.atomic32.retval)) # test atomic 64 bit SWAP swap64 = zhpe.xdm_cmd() swap64.opcode = zhpe.XDM_CMD.ATM_SWAP swap64.atomic_one_op64.r = 1 # return a value swap64.atomic_one_op64.size = zhpe.ATOMIC_SIZE.SIZE_64BIT swap64.atomic_one_op64.rem_addr = atomic_offset swap64.atomic_one_op64.operand = 0xDEADBEEFEDA11AB xdm.queue_cmd(swap64) try: swap64_cmpl = xdm.get_cmpl() if args.verbosity: print('SWAP64 cmpl: {}'.format(swap64_cmpl)) except XDMcompletionError as e: print('SWAP64 cmpl error: {} {:#x} request_id {:#x}'.format( e, e.status, e.request_id)) if args.verbosity: print('SWAP64 return value: {}'.format(swap64_cmpl.atomic64)) if args.keyboard: set_trace() # second test atomic 64 bit SWAP - val is now 0xDEADBEEFEDA11AB swap64 = zhpe.xdm_cmd() swap64.opcode = zhpe.XDM_CMD.ATM_SWAP swap64.atomic_one_op64.r = 1 # return a value swap64.atomic_one_op64.size = zhpe.ATOMIC_SIZE.SIZE_64BIT swap64.atomic_one_op64.rem_addr = atomic_offset swap64.atomic_one_op64.operand = 0x123456789ABCDEF1 xdm.queue_cmd(swap64) try: swap64_cmpl = xdm.get_cmpl() if args.verbosity: print('SWAP64 cmpl: {}'.format(swap64_cmpl)) except XDMcompletionError as e: print('SWAP64 cmpl error: {} {:#x} request_id {:#x}'.format( e, e.status, e.request_id)) if args.verbosity: print('SWAP64 return value: {}'.format(swap64_cmpl.atomic64)) if swap64_cmpl.atomic64.retval != 0xDEADBEEFEDA11AB: print( 'FAIL: SWAP64: retval is {:#x} and should be 0xDEADBEEFEDA11AB' .format(swap64_cmpl.atomic64.retval)) if args.keyboard: set_trace() # test atomic 64 bit COMPARE AND SWAP - val is now 0x12356789ABCDEF1 cas64 = zhpe.xdm_cmd() cas64.opcode = zhpe.XDM_CMD.ATM_CAS cas64.atomic_two_op64.r = 1 # return a value cas64.atomic_two_op64.size = zhpe.ATOMIC_SIZE.SIZE_64BIT cas64.atomic_two_op64.rem_addr = atomic_offset cas64.atomic_two_op64.operand1 = 0x12356789ABCDEF12 cas64.atomic_two_op64.operand2 = 0xBADDECAFBADDECAF xdm.queue_cmd(cas64) try: cas64_cmpl = xdm.get_cmpl() if args.verbosity: print('CAS64 cmpl: {}'.format(cas64_cmpl)) except XDMcompletionError as e: print('CAS64 cmpl error: {} {:#x} request_id {:#x}'.format( e, e.status, e.request_id)) if args.verbosity: print('CAS64 return value: {}'.format(cas64_cmpl.atomic64)) if cas64_cmpl.atomic64.retval != 0x123456789ABCDEF1: print( 'FAIL: CAS64: retval is {:#x} and should be 0x123456789ABCDEF1' .format(cas64_cmpl.atomic64.retval)) if args.keyboard: set_trace() # test atomic 64 bit FETCH AND ADD - val is now 0x123456789ABCDEF1 add64 = zhpe.xdm_cmd() add64.opcode = zhpe.XDM_CMD.ATM_ADD add64.atomic_one_op64.r = 1 # return a value add64.atomic_one_op64.size = zhpe.ATOMIC_SIZE.SIZE_64BIT add64.atomic_one_op64.rem_addr = atomic_offset add64.atomic_one_op64.operand = 0x1111111111111111 xdm.queue_cmd(add64) try: add64_cmpl = xdm.get_cmpl() if args.verbosity: print('ADD64 cmpl: {}'.format(add64_cmpl)) except XDMcompletionError as e: print('ADD64 cmpl error: {} {:#x} request_id {:#x}'.format( e, e.status, e.request_id)) if args.verbosity: print('ADD64 return value: {}'.format(add64_cmpl.atomic64)) if add64_cmpl.atomic64.retval != 0x123456789abcdef1: print( 'FAIL: ADD64: retval is {:#x} and should be 0x0x123456789abcdef1' .format(add64_cmpl.atomic64.retval)) # use atomic 64 bit SWAP to get the sum from previous ADD swap64 = zhpe.xdm_cmd() swap64.opcode = zhpe.XDM_CMD.ATM_SWAP swap64.atomic_one_op64.r = 1 # return a value swap64.atomic_one_op64.size = zhpe.ATOMIC_SIZE.SIZE_64BIT swap64.atomic_one_op64.rem_addr = atomic_offset swap64.atomic_one_op64.operand = 0x0 xdm.queue_cmd(swap64) try: swap64_cmpl = xdm.get_cmpl() except XDMcompletionError as e: print('SWAP64 cmpl error: {} {:#x} request_id {:#x}'.format( e, e.status, e.request_id)) if swap64_cmpl.atomic64.retval != 0x23456789ABCDF002: print( 'FAIL: ADD64: retval is {:#x} and should be 0x23456789ABCDF002' .format(swap64_cmpl.atomic64.retval)) else: if args.verbosity: print('ADD64: PASS: sum is {:#x}'.format( swap64_cmpl.atomic64.retval)) if args.keyboard: set_trace() # test EnqA/RDM enqa = zhpe.xdm_cmd() enqa.opcode = zhpe.XDM_CMD.ENQA enqa.enqa.dgcid = zuu.gcid enqa.enqa.rspctxid = rdm.rsp_rqa.info.rspctxid enqa.enqa.payload[0:len4] = str4 xdm.queue_cmd(enqa) try: enqa_cmpl = xdm.get_cmpl() if args.verbosity: print('ENQA cmpl: {}'.format(enqa_cmpl)) except XDMcompletionError as e: print('ENQA cmpl error: {} {:#x} request_id {:#x}'.format( e, e.status, e.request_id)) rdm_cmpl = rdm.get_cmpl() if args.verbosity: print('RDM cmpl: {}'.format(rdm_cmpl.enqa)) if enqa.enqa.payload[0:52] != rdm_cmpl.enqa.payload[0:52]: print('FAIL: RDM: payload is {} and should be {}'.format( rdm_cmpl.enqa.payload[0:52], enqa.enqa.payload[0:52])) # Revisit: check other cmpl fields if args.keyboard: set_trace() # test EnqA/RDM with poll enqa = zhpe.xdm_cmd() enqa.opcode = zhpe.XDM_CMD.ENQA enqa.enqa.dgcid = zuu.gcid enqa.enqa.rspctxid = rdm.rsp_rqa.info.rspctxid enqa.enqa.payload[0:len4] = str4 xdm.queue_cmd(enqa) try: enqa_cmpl = xdm.get_cmpl() if args.verbosity: print('ENQA cmpl: {}'.format(enqa_cmpl)) except XDMcompletionError as e: print('ENQA cmpl error: {} {:#x} request_id {:#x}'.format( e, e.status, e.request_id)) rdm_cmpls = rdm.get_poll(verbosity=args.verbosity) if args.verbosity: for c in range(len(rdm_cmpls)): if c != None: print('RDM cmpl: {}'.format(rdm_cmpls[c].enqa)) for c in range(len(rdm_cmpls)): if enqa.enqa.payload[0:52] != rdm_cmpls[c].enqa.payload[0:52]: print('FAIL: RDM: payload is {} and should be {}'.format( rdm_cmpls[c].enqa.payload[0:52], enqa.enqa.payload[0:52])) if args.keyboard: set_trace() # second test EnqA/RDM with poll if args.verbosity: print('SECOND EnqA/RDM poll test') enqa2 = zhpe.xdm_cmd() enqa2.opcode = zhpe.XDM_CMD.ENQA enqa2.enqa.dgcid = zuu.gcid enqa2.enqa.rspctxid = rdm.rsp_rqa.info.rspctxid enqa2.enqa.payload[0:len5] = str5 xdm.queue_cmd(enqa2) try: enqa_cmpl2 = xdm.get_cmpl() if args.verbosity: print('ENQA cmpl: {}'.format(enqa_cmpl2)) except XDMcompletionError as e: print('ENQA cmpl error: {} {:#x} request_id {:#x}'.format( e, e.status, e.request_id)) rdm_cmpls2 = rdm.get_poll(verbosity=args.verbosity) if args.verbosity: for c in range(len(rdm_cmpls2)): if c != None: print('RDM cmpl: {}'.format(rdm_cmpls2[c].enqa)) for c in range(len(rdm_cmpls2)): if enqa2.enqa.payload[0:52] != rdm_cmpls2[c].enqa.payload[0:52]: print('FAIL: RDM: payload is {} and should be {}'.format( rdm_cmpls[c].enqa.payload[0:52], enqa.enqa.payload[0:52])) if args.keyboard: set_trace() # test FAM if args.fam: fam_zuu = zuuid(gcid=args.fam_gcid) if args.verbosity: print('FAM zuuid={}'.format(fam_zuu)) # Do a UUID_IMPORT with the ZHPE_IS_FAM flag set conn.do_UUID_IMPORT(fam_zuu, UU.IS_FAM, None) # RMR_IMPORT the FAM at address 0 and size 2M if args.load_store: fam_rmr = conn.do_RMR_IMPORT(fam_zuu, 0, sz2M, MR.GRPRIC) # Do load/store to FAM fam_rmm = mmap.mmap(f.fileno(), sz2M, offset=fam_rmr.offset) fam_v, fam_l = zhpe.mmap_vaddr_len(fam_rmm) fam_rmm[0:len1] = str1 fam_rmm[len1:len1_2] = str2 # flush writes, so reads will see new data zhpe.pmem_flush(fam_v, len1_2) else: fam_rmr = conn.do_RMR_IMPORT(fam_zuu, 0, sz2M, MR.GRPRI) # do an XDM command to get the data back and check it get_imm = zhpe.xdm_cmd() get_imm.opcode = zhpe.XDM_CMD.GET_IMM get_imm.getput_imm.size = len1_2 get_imm.getput_imm.rem_addr = fam_rmr.req_addr if args.keyboard: set_trace() xdm.queue_cmd(get_imm) try: get_imm_cmpl = xdm.get_cmpl() if args.verbosity: print('GET_IMM cmpl: {}'.format(get_imm_cmpl.getimm)) # Verify the payload is what we expect if args.load_store: retstr = bytearray( get_imm_cmpl.getimm.payload[0:len1_2]) if retstr == str1 + str2: if args.verbosity: print('FAM comparision PASS') else: print('FAM comparision FAIL') except XDMcompletionError as e: print( 'GET_IMM cmpl error: {} {:#x} request_id {:#x}'.format( e, e.status, e.request_id)) # Revisit: check that we got str1+str2 if args.keyboard: set_trace() # end if FAM # Test a huge PUT if args.huge: rsp_rmr1G = conn.do_RMR_IMPORT(zuu, rsp1G.rsp_zaddr, sz1G, MR.GRPRI) put_offset = hugesize // 2 local_addr = v1G rem_addr = rsp_rmr1G.req_addr + put_offset put = zhpe.xdm_cmd() put.opcode = zhpe.XDM_CMD.PUT | zhpe.XDM_CMD.FENCE put.getput.size = hugesize // 2 put.getput.read_addr = local_addr put.getput.write_addr = rem_addr if args.keyboard: set_trace() start = time.monotonic() xdm.queue_cmd(put) try: put_cmpl = xdm.get_cmpl() end = time.monotonic() if args.verbosity: print('huge PUT cmpl: {}'.format(put_cmpl)) except XDMcompletionError as e: print('huge PUT cmpl error: {} {:#x} request_id {:#x}'. format(e, e.status, e.request_id)) # Revisit: need fence/sync to ensure visibility mm1Gsha256p = hashlib.sha256(mm1G[put_offset:put_offset + hugesize // 2]).hexdigest() if args.verbosity: print('mm1G sha256 after PUT="{}"'.format(mm1Gsha256p)) if mm1Gsha256p != mm1Gsha256h: print('huge PUT sha mismatch: {} != {}'.format( mm1Gsha256h, mm1Gsha256h)) secs = end - start if args.verbosity: print( 'huge PUT of {} bytes in {} seconds = {} GiB/s'.format( put.getput.size, secs, put.getput.size / (secs * sz1G))) # end if huge # end if loopback if args.net: if args.verbosity: print('Waiting for network connections') net.reactor.run() if args.keyboard: set_trace() conn.do_XQUEUE_FREE(xdm.rsp_xqa.info) conn.do_RQUEUE_FREE(rdm.rsp_rqa.info) if args.requester: conn.do_MR_FREE(v, l, MR.GPI, rsp.rsp_zaddr) conn.do_MR_FREE(v2M, l2M, MR.GP, rsp2M_l.rsp_zaddr) conn.do_MR_FREE(v2M + 0x1242, l2M - 0x5000, MR.GRPRI, rsp2M.rsp_zaddr) # we do not MR_FREE rsp2M_b, to see if it is cleaned up at close # same for RMR_FREE of rsp_rmr if args.loopback and modp.genz_loopback: if args.load_store: conn.do_RMR_FREE(zuu, rsp2M_b.rsp_zaddr, sz4K, MR.GRPRIC, rsp_rmr_c.req_addr) exc = False try: conn.do_UUID_FREE(zuu) except OSError: exc = True if exc: if args.verbosity: print('do_UUID_FREE of zuu: got expected error') else: print('fail: no error on UUID_FREE of zuu') exc = False try: conn.do_UUID_FREE(init.uuid) except OSError: exc = True if exc: if args.verbosity: print('do_UUID_FREE of init.uuid: got expected error') else: print('fail: no error on UUID_FREE of init.uuid')