def handle_hello(self, hello): hello = json.loads(hello) self.remote_nodeid = zuuid(hello['nodeid']) if self.remote_nodeid == self.nodeid: print('Ignoring connection to myself.') self.transport.loseConnection() elif self.remote_nodeid.gcid == self.nodeid.gcid: print( 'Configuration error - local and remote nodes have the same GCID ({})' .format(self.nodeid.gcid_str)) self.transport.loseConnection() else: if self.state == 'GETHELLO': self.send_hello() else: print('Starting ping to {}'.format(self.remote_nodeid)) self.lc_ping.start(PING_INTERVAL) self.state = 'READY' self.factory.peers[self.remote_nodeid] = self if self.factory.bringup: self.factory.conn.do_UUID_IMPORT(self.remote_nodeid, UU.IS_FAM, None) else: self.factory.conn.do_UUID_IMPORT(self.remote_nodeid, 0, None) if self.factory.responder: self.send_mrregs() ###inform our new peer about us self.send_addr(mine=True) ###and ask them for more peers self.send_getaddr()
def handle_addr(self, addr): addr = json.loads(addr) for remote_ip, remote_nodeid_str in addr['peers']: remote_nodeid = zuuid(remote_nodeid_str) if (remote_nodeid not in self.factory.peers and remote_nodeid != self.nodeid): print('Connecting to new peer {}'.format(remote_nodeid_str)) host, port = remote_ip.split(':') point = TCP4ClientEndpoint(reactor, host, int(port)) d = connectProtocol( point, MyProtocol(self.factory, 'SENDHELLO', 'TO')) d.addCallback(gotProtocol)
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) 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 as err: if err.errno == errno.EBADRQC: exc = True else: raise if exc: if args.verbosity: print('do_INIT: got expected error on 2nd INIT') else: runtime_err('fail: no error on 2nd INIT') if args.overlap: feat = conn.do_FEATURE(zhpe.FEATURES.FEATURE_MR_OVERLAP_CHECKING) if args.verbosity: print('do_FEATURE: features={:#x}'.format(feat.features)) if args.loopback and modp.genz_loopback == 0: runtime_err('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 memory twice to force EEXIST exc = False try: bad = conn.do_MR_REG(v, l, MR.GPI) # req: GET/PUT, 4K except OSError as err: if err.errno == errno.EEXIST: exc = True else: raise if exc: if args.verbosity: print('do_MR_REG: got expected error on 2nd MR_REG') else: runtime_err('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') datasize = min(datasize, sz2M) mmdata = mmap.mmap(data.fileno(), datasize, access=mmap.ACCESS_READ) datasha256 = hashlib.sha256(mmdata[0:datasize]).hexdigest() if args.verbosity: print('datafile sha256={}'.format(datasha256)) mm2M = mmap.mmap(-1, sz2M, access=mmap.ACCESS_WRITE) mm2M[0:datasize] = mmdata[0:datasize] v2M, l2M = zhpe.mmap_vaddr_len(mm2M) mmdata.close() data.close() if args.huge: hugesize = sz1G mm1G = mmap.mmap(-1, sz1G, access=mmap.ACCESS_WRITE) mm1G[0:hugesize // 2] = os.urandom(hugesize // 2) v1G, l1G = zhpe.mmap_vaddr_len(mm1G) # GET_REM/PUT_REM, 2M-0x5000 rsp2M = conn.do_MR_REG(v2M + 0x1242, l2M - 0x5000, MR.GRPRI) rsp2M_l = conn.do_MR_REG(v2M, l2M, MR.GP) # GET/PUT, 2M lmr = rsp2M_l lmm = mm2M if args.responder or args.loopback: # rsp: GET_REM/PUT_REM, 2M rsp2M_b = conn.do_MR_REG(v2M, l2M, MR.GRPRI) 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) # If queue_test is set, allocate all the queues to check error handling qlist = [] while True: try: qlist.append(zhpe.XDM(conn, 256, 256, slice_mask=0x1)) except OSError as err: if err.errno != errno.ENOENT: raise break if not args.queue_test: break if args.verbosity: print('{} XDM queues allocated\n'.format(len(qlist))) if len(qlist) == 0: runtime_err('No XDM queues allocated\n') xdm = qlist.pop() while qlist: conn.do_XQUEUE_FREE(qlist.pop()) while True: try: qlist.append(zhpe.RDM(conn, 1024, slice_mask=0x2)) except OSError as err: if err.errno != errno.ENOENT: raise break if not args.queue_test: break if args.verbosity: print('{} RDM queues allocated\n'.format(len(qlist))) if len(qlist) == 0: runtime_err('No RDM queues allocated\n') rdm = qlist.pop() while qlist: conn.do_RQUEUE_FREE(qlist.pop()) 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.keyboard: set_trace() # invalidate rmm2 to read fresh data zhpe.invalidate(v_rmm2, len1, True) if args.verbosity: print('rmm2 (remote)="{}"'.format(rmm2[0:len1])) if mm2[0:len1] != rmm2[0:len1]: runtime_err('Error: mm2 "{}" != rmm2 "{}"'.format( mm2[0:len1], rmm2[0:len1])) rmm2[len1:len1_2] = str2 # commit rmm2 writes, so mm2 reads will see new data zhpe.commit(v_rmm2 + len1, len2, True) # invalidate mm2 to read fresh data zhpe.invalidate(v2, len1_2, False) if args.verbosity: print('mm2 after remote update="{}"'.format( mm2[0:len1_2].decode())) if mm2[0:len1_2] != rmm2[0:len1_2]: runtime_err('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: for i in range(3): save = open('mismatch.{}'.format(i), 'wb') save.write(mm2M[i * datasize:(i + 1) * datasize]) save.close() runtime_err('PUT sha mismatch: {} != {}'.format( datasha256, mm2Msha256p)) if args.keyboard: set_trace() # test GET+SYNC get_offset = 2 * datasize if modp.no_iommu: # Revisit: physaddr temporary local_addr = rsp2M_r.physaddr + get_offset 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: runtime_err('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: runtime_err(('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: runtime_err(('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: runtime_err(('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: runtime_err(('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: runtime_err( ('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: runtime_err( ('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: runtime_err(('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: runtime_err( ('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]: runtime_err('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)): 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]: runtime_err( '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)): 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]: runtime_err( '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 # commit writes, so reads will see new data zhpe.commit(fam_v, len1_2, True) 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: runtime_err('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) conn.do_RQUEUE_FREE(rdm) 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')
def main(): global args args = parse_args() if args.verbosity: print('pid={}'.format(os.getpid())) 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)) zuu = zuuid(gcid=gcid) conn.do_UUID_IMPORT(zuu, 0, None) mm = mmap.mmap(-1, args.len * 2) v, l = zhpe.mmap_vaddr_len(mm) rsp = conn.do_MR_REG(v, l, MR.GPGRPRI) mm[0:args.len] = os.urandom(args.len) # fill with random bytes rsp_rmr = conn.do_RMR_IMPORT(zuu, rsp.rsp_zaddr, args.len * 2, MR.GRPRI) if (args.xdmq_size & (args.xdmq_size - 1)) != 0: raise_err('-x option must specify a power of 2') qmask = args.xdmq_size - 1 if args.window == 0: args.window = qmask if args.window >= args.xdmq_size: raise_err('-w option must be <= queue size') queues = [] smask = 1 << args.slice smask |= 0x80 for q in range(args.queues): xdm = zhpe.XDM(conn, args.xdmq_size, args.xdmq_size, slice_mask=smask) if args.verbosity: print('XDM queue = {} slice = {}'.format( xdm.rsp_xqa.info.queue, xdm.rsp_xqa.info.slice)) queues.append(Queue(xdm, args.commands)) cmd = zhpe.xdm_cmd() cmd.opcode = args.op if args.fence: cmd.opcode = cmd.opcode | zhpe.XDM_CMD.FENCE if cmd.opcode == zhpe.XDM_CMD.PUT_IMM: args.len = min(args.len, 32) cmd.getput_imm.size = args.len cmd.getput_imm.rem_addr = rsp_rmr.req_addr + args.len cmd.getput_imm.payload[0:args.len] = mm[0:args.len] elif cmd.opcode == zhpe.XDM_CMD.GET_IMM: args.len = min(args.len, 32) cmd.getput_imm.size = args.len cmd.getput_imm.rem_addr = rsp_rmr.req_addr elif cmd.opcode == zhpe.XDM_CMD.PUT: cmd.getput.size = args.len cmd.getput.read_addr = v cmd.getput.write_addr = rsp_rmr.req_addr + args.len elif cmd.opcode == zhpe.XDM_CMD.GET: cmd.getput.size = args.len cmd.getput.read_addr = rsp_rmr.req_addr cmd.getput.write_addr = v + args.len if args.verbosity: print("cmd: {}".format(cmd)) # Fill the queue with the commands for i in range(args.xdmq_size): for q in queues: q.xdm.queue_cmd(cmd, False) if args.keyboard: set_trace() working = queues.copy() while working: for q in working: cmps = 0 while True: cmpl = q.xdm.get_cmpl(wait=False) if cmpl == None: break cmps += 1 if cmps != 0: q.cmps -= cmps if q.cmps == 0: working.remove(q) if args.verbosity: print("queue {} completed {}".format( q.xdm.rsp_xqa.info.queue, cmps)) qavail = qmask - (q.cmps - q.cmds) qavail = min(qavail, q.cmds, args.window) if qavail != 0 and (qavail == args.window or qavail == q.cmds): q.xdm.ring2(qavail) q.cmds -= qavail if args.verbosity: print("queue {} started {}".format( q.xdm.rsp_xqa.info.queue, qavail)) if args.keyboard: set_trace()
def main(): global args args = parse_args() if args.verbosity: print('pid={}'.format(os.getpid())) 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)) zuu = zuuid(gcid=gcid) conn.do_UUID_IMPORT(zuu, 0, None) sz4K = 4096 mm = mmap.mmap(-1, sz4K) v, l = zhpe.mmap_vaddr_len(mm) rsp = conn.do_MR_REG(v, l, MR.GPGRPRI) # req: GET/PUT/GETREM/PUTREM, 4K rsp_rmr = conn.do_RMR_IMPORT(zuu, rsp.rsp_zaddr, sz4K, MR.GPGRPRIC) rmm = mmap.mmap(f.fileno(), sz4K, offset=rsp_rmr.offset) v_rmm, l_rmm = zhpe.mmap_vaddr_len(rmm) str1 = b'12345678' len1 = len(str1) off1 = 0x9A0 str2 = b'abcdefgh' len2 = len(str2) off2 = off1 + len2 len1_2 = len1 + len2 mm[off1:off1 + len1] = str1 if args.verbosity: print('mm (initial)="{}"'.format(mm[off1:off1 + len1])) if args.keyboard: set_trace() # invalidate rmm to read fresh data zhpe.invalidate(v_rmm + off1, len1, True) if args.verbosity: print('rmm (remote)="{}"'.format(rmm[off1:off1 + len1])) if mm[off1:off1 + len1] != rmm[off1:off1 + len1]: runtime_err('Error: mm "{}" != rmm "{}"'.format( mm[off1:off1 + len1], rmm[off1:off1 + len1])) rmm[off2:off2 + len2] = str2 # commit rmm writes, so mm reads will see new data zhpe.commit(v_rmm + off2, len2, True) # invalidate mm reads to see new data. zhpe.invalidate(v + off1, len1_2, True) if args.verbosity: print('mm after remote update="{}"'.format(mm[off1:off1 + len1_2])) if mm[off1:off1 + len1_2] != rmm[off1:off1 + len1_2]: runtime_err('Error: mm "{}" != rmm "{}"'.format( mm[off1:off1 + len1_2], rmm[off1:off1 + len1_2])) rmm.close() conn.do_RMR_FREE(zuu, rsp.rsp_zaddr, sz4K, MR.GPGRPRIC, rsp_rmr.req_addr) conn.do_MR_FREE(v, l, MR.GPGRPRI, rsp.rsp_zaddr) mm.close() f.close()