brintos

brintos / llvm-project-archived public Read only

0
0
Text · 19.2 KiB · fcd8956 Raw
531 lines · cpp
1#include "InternalEvent.h"2#include <omp-tools.h>3#include <sstream>4 5#include "gtest/gtest.h"6 7using namespace omptest;8 9TEST(InternalEvent_toString, AssertionSyncPoint) {10  internal::AssertionSyncPoint SP{/*Name=*/"Test Sync Point"};11 12  EXPECT_EQ(SP.toString(), "Assertion SyncPoint: 'Test Sync Point'");13}14 15TEST(InternalEvent_toString, ThreadBegin) {16  internal::ThreadBegin TB{/*ThreadType=*/ompt_thread_t::ompt_thread_initial};17 18  EXPECT_EQ(TB.toString(), "OMPT Callback ThreadBegin: ThreadType=1");19}20 21TEST(InternalEvent_toString, ThreadEnd) {22  internal::ThreadEnd TE{};23 24  EXPECT_EQ(TE.toString(), "OMPT Callback ThreadEnd");25}26 27TEST(InternalEvent_toString, ParallelBegin) {28  internal::ParallelBegin PB{/*NumThreads=*/31};29 30  EXPECT_EQ(PB.toString(), "OMPT Callback ParallelBegin: NumThreads=31");31}32 33TEST(InternalEvent_toString, ParallelEnd) {34  internal::ParallelEnd PE{/*ParallelData=*/(ompt_data_t *)0x11,35                           /*EncounteringTaskData=*/(ompt_data_t *)0x22,36                           /*Flags=*/31,37                           /*CodeptrRA=*/(const void *)0x33};38 39  EXPECT_EQ(PE.toString(), "OMPT Callback ParallelEnd");40}41 42TEST(InternalEvent_toString, Work) {43  internal::Work WK{/*WorkType=*/ompt_work_t::ompt_work_loop_dynamic,44                    /*Endpoint=*/ompt_scope_endpoint_t::ompt_scope_beginend,45                    /*ParallelData=*/(ompt_data_t *)0x11,46                    /*TaskData=*/(ompt_data_t *)0x22,47                    /*Count=*/31,48                    /*CodeptrRA=*/(const void *)0x33};49 50  EXPECT_EQ(WK.toString(),51            "OMPT Callback Work: work_type=11 endpoint=3 parallel_data=0x11 "52            "task_data=0x22 count=31 codeptr=0x33");53}54 55TEST(InternalEvent_toString, Dispatch_iteration) {56  ompt_data_t DI{.value = 31};57  internal::Dispatch D{/*ParallelData=*/(ompt_data_t *)0x11,58                       /*TaskData=*/(ompt_data_t *)0x22,59                       /*Kind=*/ompt_dispatch_t::ompt_dispatch_iteration,60                       /*Instance=*/DI};61 62  EXPECT_EQ(D.toString(), "OMPT Callback Dispatch: parallel_data=0x11 "63                          "task_data=0x22 kind=1 instance=[it=31]");64}65 66TEST(InternalEvent_toString, Dispatch_section) {67  ompt_data_t DI{.ptr = (void *)0x33};68  internal::Dispatch D{/*ParallelData=*/(ompt_data_t *)0x11,69                       /*TaskData=*/(ompt_data_t *)0x22,70                       /*Kind=*/ompt_dispatch_t::ompt_dispatch_section,71                       /*Instance=*/DI};72 73  EXPECT_EQ(D.toString(), "OMPT Callback Dispatch: parallel_data=0x11 "74                          "task_data=0x22 kind=2 instance=[ptr=0x33]");75}76 77TEST(InternalEvent_toString, Dispatch_chunks) {78  ompt_dispatch_chunk_t DC{.start = 7, .iterations = 31};79  ompt_data_t DI{.ptr = (void *)&DC};80 81  internal::Dispatch DLoop{82      /*ParallelData=*/(ompt_data_t *)0x11,83      /*TaskData=*/(ompt_data_t *)0x22,84      /*Kind=*/ompt_dispatch_t::ompt_dispatch_ws_loop_chunk,85      /*Instance=*/DI};86 87  internal::Dispatch DTask{88      /*ParallelData=*/(ompt_data_t *)0x11,89      /*TaskData=*/(ompt_data_t *)0x22,90      /*Kind=*/ompt_dispatch_t::ompt_dispatch_taskloop_chunk,91      /*Instance=*/DI};92 93  internal::Dispatch DDist{94      /*ParallelData=*/(ompt_data_t *)0x11,95      /*TaskData=*/(ompt_data_t *)0x22,96      /*Kind=*/ompt_dispatch_t::ompt_dispatch_distribute_chunk,97      /*Instance=*/DI};98 99  ompt_data_t DINull{.ptr = nullptr};100  internal::Dispatch DDistNull{101      /*ParallelData=*/(ompt_data_t *)0x11,102      /*TaskData=*/(ompt_data_t *)0x22,103      /*Kind=*/ompt_dispatch_t::ompt_dispatch_distribute_chunk,104      /*Instance=*/DINull};105 106  EXPECT_EQ(DLoop.toString(),107            "OMPT Callback Dispatch: parallel_data=0x11 "108            "task_data=0x22 kind=3 instance=[chunk=(start=7, iterations=31)]");109 110  EXPECT_EQ(DTask.toString(),111            "OMPT Callback Dispatch: parallel_data=0x11 "112            "task_data=0x22 kind=4 instance=[chunk=(start=7, iterations=31)]");113 114  EXPECT_EQ(DDist.toString(),115            "OMPT Callback Dispatch: parallel_data=0x11 "116            "task_data=0x22 kind=5 instance=[chunk=(start=7, iterations=31)]");117 118  EXPECT_EQ(DDistNull.toString(), "OMPT Callback Dispatch: parallel_data=0x11 "119                                  "task_data=0x22 kind=5");120}121 122TEST(InternalEvent_toString, TaskCreate) {123  internal::TaskCreate TC{/*EncounteringTaskData=*/(ompt_data_t *)0x11,124                          /*EncounteringTaskFrame=*/(const ompt_frame_t *)0x22,125                          /*NewTaskData=*/(ompt_data_t *)0x33,126                          /*Flags=*/7,127                          /*HasDependences=*/31,128                          /*CodeptrRA=*/(const void *)0x44};129 130  EXPECT_EQ(TC.toString(),131            "OMPT Callback TaskCreate: encountering_task_data=0x11 "132            "encountering_task_frame=0x22 new_task_data=0x33 flags=7 "133            "has_dependences=31 codeptr=0x44");134}135 136TEST(InternalEvent_toString, ImplicitTask) {137  internal::ImplicitTask IT{138      /*Endpoint=*/ompt_scope_endpoint_t::ompt_scope_begin,139      /*ParallelData=*/(ompt_data_t *)0x11,140      /*TaskData=*/(ompt_data_t *)0x22,141      /*ActualParallelism=*/7,142      /*Index=*/31,143      /*Flags=*/127};144 145  EXPECT_EQ(IT.toString(),146            "OMPT Callback ImplicitTask: endpoint=1 parallel_data=0x11 "147            "task_data=0x22 actual_parallelism=7 index=31 flags=127");148}149 150TEST(InternalEvent_toString, SyncRegion) {151  internal::SyncRegion SR{152      /*Kind=*/ompt_sync_region_t::ompt_sync_region_taskwait,153      /*Endpoint=*/ompt_scope_endpoint_t::ompt_scope_end,154      /*ParallelData=*/(ompt_data_t *)0x11,155      /*TaskData=*/(ompt_data_t *)0x22,156      /*CodeptrRA=*/(const void *)0x33};157 158  EXPECT_EQ(SR.toString(), "OMPT Callback SyncRegion: kind=5 endpoint=2 "159                           "parallel_data=0x11 task_data=0x22 codeptr=0x33");160}161 162TEST(InternalEvent_toString, Target) {163  internal::Target T{/*Kind=*/ompt_target_t::ompt_target_enter_data_nowait,164                     /*Endpoint=*/ompt_scope_endpoint_t::ompt_scope_end,165                     /*DeviceNum=*/7,166                     /*TaskData=*/(ompt_data_t *)0x11,167                     /*TargetId=*/(ompt_id_t)31,168                     /*CodeptrRA=*/(const void *)0x22};169 170  EXPECT_EQ(T.toString(), "Callback Target: target_id=31 kind=10 "171                          "endpoint=2 device_num=7 code=0x22");172}173 174TEST(InternalEvent_toString, TargetEmi) {175  ompt_data_t TaskData{.value = 31};176  ompt_data_t TargetTaskData{.value = 127};177  ompt_data_t TargetData{.value = 8191};178 179  internal::TargetEmi T{/*Kind=*/ompt_target_t::ompt_target_update,180                        /*Endpoint=*/ompt_scope_endpoint_t::ompt_scope_begin,181                        /*DeviceNum=*/7,182                        /*TaskData=*/(ompt_data_t *)&TaskData,183                        /*TargetTaskData=*/(ompt_data_t *)&TargetTaskData,184                        /*TargetData=*/(ompt_data_t *)&TargetData,185                        /*CodeptrRA=*/(const void *)0x11};186 187  internal::TargetEmi TDataNull{188      /*Kind=*/ompt_target_t::ompt_target_update,189      /*Endpoint=*/ompt_scope_endpoint_t::ompt_scope_begin,190      /*DeviceNum=*/7,191      /*TaskData=*/(ompt_data_t *)&TaskData,192      /*TargetTaskData=*/(ompt_data_t *)nullptr,193      /*TargetData=*/(ompt_data_t *)&TargetData,194      /*CodeptrRA=*/(const void *)0x11};195 196  std::ostringstream StreamT1;197  std::ostringstream StreamT2;198  std::string CallBackPrefix{199      "Callback Target EMI: kind=4 endpoint=1 device_num=7"};200  StreamT1 << CallBackPrefix << std::showbase << std::hex;201  StreamT1 << " task_data=" << &TaskData << " (0x1f)";202  StreamT1 << " target_task_data=" << &TargetTaskData << " (0x7f)";203  StreamT1 << " target_data=" << &TargetData << " (0x1fff)";204  StreamT1 << " code=0x11";205 206  StreamT2 << CallBackPrefix << std::showbase << std::hex;207  StreamT2 << " task_data=" << &TaskData << " (0x1f)";208  StreamT2 << " target_task_data=(nil) (0x0)";209  StreamT2 << " target_data=" << &TargetData << " (0x1fff)";210  StreamT2 << " code=0x11";211 212  EXPECT_EQ(T.toString(), StreamT1.str());213  EXPECT_EQ(TDataNull.toString(), StreamT2.str());214}215 216TEST(InternalEvent_toString, TargetDataOp) {217  internal::TargetDataOp TDO{218      /*TargetId=*/7,219      /*HostOpId=*/31,220      /*OpType=*/ompt_target_data_op_t::ompt_target_data_associate,221      /*SrcAddr=*/(void *)0x11,222      /*SrcDeviceNum=*/127,223      /*DstAddr=*/(void *)0x22,224      /*DstDeviceNum=*/8191,225      /*Bytes=*/4096,226      /*CodeptrRA=*/(const void *)0x33};227 228  EXPECT_EQ(229      TDO.toString(),230      "  Callback DataOp: target_id=7 host_op_id=31 optype=5 src=0x11 "231      "src_device_num=127 dest=0x22 dest_device_num=8191 bytes=4096 code=0x33");232}233 234TEST(InternalEvent_toString, TargetDataOpEmi) {235  ompt_data_t TargetTaskData{.value = 31};236  ompt_data_t TargetData{.value = 127};237  ompt_id_t HostOpId = 8191;238 239  internal::TargetDataOpEmi TDO{240      /*Endpoint=*/ompt_scope_endpoint_t::ompt_scope_begin,241      /*TargetTaskData=*/(ompt_data_t *)&TargetTaskData,242      /*TargetData=*/(ompt_data_t *)&TargetData,243      /*HostOpId=*/(ompt_id_t *)&HostOpId,244      /*OpType=*/ompt_target_data_op_t::ompt_target_data_disassociate,245      /*SrcAddr=*/(void *)0x11,246      /*SrcDeviceNum=*/1,247      /*DstAddr=*/(void *)0x22,248      /*DstDeviceNum=*/2,249      /*Bytes=*/4096,250      /*CodeptrRA=*/(const void *)0x33};251 252  // Set HostOpId=nullptr253  internal::TargetDataOpEmi TDO_HostOpIdNull{254      /*Endpoint=*/ompt_scope_endpoint_t::ompt_scope_begin,255      /*TargetTaskData=*/(ompt_data_t *)&TargetTaskData,256      /*TargetData=*/(ompt_data_t *)&TargetData,257      /*HostOpId=*/(ompt_id_t *)nullptr,258      /*OpType=*/ompt_target_data_op_t::ompt_target_data_disassociate,259      /*SrcAddr=*/(void *)0x11,260      /*SrcDeviceNum=*/1,261      /*DstAddr=*/(void *)0x22,262      /*DstDeviceNum=*/2,263      /*Bytes=*/4096,264      /*CodeptrRA=*/(const void *)0x33};265 266  std::ostringstream StreamTDO1;267  std::ostringstream StreamTDO2;268  std::string CallBackPrefix{"  Callback DataOp EMI: endpoint=1 optype=6"};269  std::string CallBackSuffix{270      " src=0x11 src_device_num=1 dest=0x22 dest_device_num=2 "271      "bytes=4096 code=0x33"};272  StreamTDO1 << CallBackPrefix << std::showbase << std::hex;273  StreamTDO1 << " target_task_data=" << &TargetTaskData << " (0x1f)";274  StreamTDO1 << " target_data=" << &TargetData << " (0x7f)";275  StreamTDO1 << " host_op_id=" << &HostOpId << " (0x1fff)";276  StreamTDO1 << CallBackSuffix;277 278  StreamTDO2 << CallBackPrefix << std::showbase << std::hex;279  StreamTDO2 << " target_task_data=" << &TargetTaskData << " (0x1f)";280  StreamTDO2 << " target_data=" << &TargetData << " (0x7f)";281  StreamTDO2 << " host_op_id=(nil) (0x0)";282  StreamTDO2 << CallBackSuffix;283 284  EXPECT_EQ(TDO.toString(), StreamTDO1.str());285  EXPECT_EQ(TDO_HostOpIdNull.toString(), StreamTDO2.str());286}287 288TEST(InternalEvent_toString, TargetSubmit) {289  internal::TargetSubmit TS{/*TargetId=*/7,290                            /*HostOpId=*/31,291                            /*RequestedNumTeams=*/127};292 293  EXPECT_EQ(TS.toString(),294            "  Callback Submit: target_id=7 host_op_id=31 req_num_teams=127");295}296 297TEST(InternalEvent_toString, TargetSubmitEmi) {298  ompt_data_t TargetData{.value = 127};299  ompt_id_t HostOpId = 8191;300  internal::TargetSubmitEmi TS{301      /*Endpoint=*/ompt_scope_endpoint_t::ompt_scope_begin,302      /*TargetData=*/(ompt_data_t *)&TargetData,303      /*HostOpId=*/(ompt_id_t *)&HostOpId,304      /*RequestedNumTeams=*/7};305 306  std::ostringstream StreamTS;307  std::string CallBackPrefix{308      "  Callback Submit EMI: endpoint=1 req_num_teams=7"};309  StreamTS << CallBackPrefix << std::showbase << std::hex;310  StreamTS << " target_data=" << &TargetData << " (0x7f)";311  StreamTS << " host_op_id=" << &HostOpId << " (0x1fff)";312 313  EXPECT_EQ(TS.toString(), StreamTS.str());314}315 316TEST(InternalEvent_toString, DeviceInitialize) {317  const char *Type = "DeviceType";318  const char *DocStr = "DocumentationString";319 320  internal::DeviceInitialize DI{/*DeviceNum=*/7,321                                /*Type=*/Type,322                                /*Device=*/(ompt_device_t *)0x11,323                                /*LookupFn=*/(ompt_function_lookup_t)0x22,324                                /*DocStr=*/DocStr};325 326  internal::DeviceInitialize DINull{/*DeviceNum=*/0,327                                    /*Type=*/nullptr,328                                    /*Device=*/nullptr,329                                    /*LookupFn=*/(ompt_function_lookup_t)0x0,330                                    /*DocStr=*/nullptr};331 332  std::ostringstream StreamDI;333  std::string CallBackPrefix{"Callback Init: device_num=7 type=DeviceType "334                             "device=0x11 lookup=0x22 doc="};335  StreamDI << CallBackPrefix << std::showbase << std::hex;336  StreamDI << (uint64_t)DocStr;337  EXPECT_EQ(DI.toString(), StreamDI.str());338 339  // TODO This looks inconsistent: (null) vs. (nil)340  EXPECT_EQ(DINull.toString(), "Callback Init: device_num=0 type=(null) "341                               "device=(nil) lookup=(nil) doc=(nil)");342}343 344TEST(InternalEvent_toString, DeviceFinalize) {345  internal::DeviceFinalize DF{/*DeviceNum=*/7};346 347  EXPECT_EQ(DF.toString(), "Callback Fini: device_num=7");348}349 350TEST(InternalEvent_toString, DeviceLoad) {351  const char *Filename = "FilenameToLoad";352 353  internal::DeviceLoad DL{/*DeviceNum=*/7,354                          /*Filename=*/Filename,355                          /*OffsetInFile=*/31,356                          /*VmaInFile=*/(void *)0x11,357                          /*Bytes=*/127,358                          /*HostAddr=*/(void *)0x22,359                          /*DeviceAddr=*/(void *)0x33,360                          /*ModuleId=*/8191};361 362  internal::DeviceLoad DLNull{/*DeviceNum=*/0,363                              /*Filename=*/nullptr,364                              /*OffsetInFile=*/0,365                              /*VmaInFile=*/nullptr,366                              /*Bytes=*/0,367                              /*HostAddr=*/nullptr,368                              /*DeviceAddr=*/nullptr,369                              /*ModuleId=*/0};370 371  EXPECT_EQ(372      DL.toString(),373      "Callback Load: device_num:7 module_id:8191 "374      "filename:FilenameToLoad host_addr:0x22 device_addr:0x33 bytes:127");375 376  // TODO This looks inconsistent: (null) vs. (nil) and ':' instead of '='377  EXPECT_EQ(DLNull.toString(),378            "Callback Load: device_num:0 module_id:0 filename:(null) "379            "host_addr:(nil) device_addr:(nil) bytes:0");380}381 382TEST(InternalEvent_toString, BufferRequest) {383  size_t Bytes = 7;384  ompt_buffer_t *Buffer = (void *)0x11;385 386  internal::BufferRequest BR{/*DeviceNum=*/31,387                             /*Buffer=*/&Buffer,388                             /*Bytes=*/&Bytes};389 390  internal::BufferRequest BRNull{/*DeviceNum=*/127,391                                 /*Buffer=*/nullptr,392                                 /*Bytes=*/nullptr};393 394  EXPECT_EQ(BR.toString(),395            "Allocated 7 bytes at 0x11 in buffer request callback");396  EXPECT_EQ(BRNull.toString(),397            "Allocated 0 bytes at (nil) in buffer request callback");398}399 400TEST(InternalEvent_toString, BufferComplete) {401  ompt_buffer_t *Buffer = (void *)0x11;402 403  internal::BufferComplete BC{/*DeviceNum=*/7,404                              /*Buffer=*/Buffer,405                              /*Bytes=*/127,406                              /*Begin=*/8191,407                              /*BufferOwned=*/1};408 409  internal::BufferComplete BCNull{/*DeviceNum=*/0,410                                  /*Buffer=*/nullptr,411                                  /*Bytes=*/0,412                                  /*Begin=*/0,413                                  /*BufferOwned=*/0};414 415  EXPECT_EQ(BC.toString(),416            "Executing buffer complete callback: 7 0x11 127 0x1fff 1");417  EXPECT_EQ(BCNull.toString(),418            "Executing buffer complete callback: 0 (nil) 0 (nil) 0");419}420 421TEST(InternalEvent_toString, BufferRecordInvalid) {422  ompt_record_ompt_t InvalidRecord{423      /*type=*/ompt_callbacks_t::ompt_callback_parallel_begin,424      /*time=*/7,425      /*thread_id=*/31,426      /*target_id=*/127,427      /*record=*/{.parallel_begin = {}}};428 429  internal::BufferRecord BRNull{/*RecordPtr=*/nullptr};430  internal::BufferRecord BRInvalid{/*RecordPtr=*/&InvalidRecord};431 432  std::ostringstream StreamBRInvalid;433  StreamBRInvalid << "rec=" << std::showbase << std::hex << &InvalidRecord;434  StreamBRInvalid << " type=3 (unsupported record type)";435 436  EXPECT_EQ(BRNull.toString(), "rec=(nil) type=0 (unsupported record type)");437  EXPECT_EQ(BRInvalid.toString(), StreamBRInvalid.str());438}439 440TEST(InternalEvent_toString, BufferRecordTarget) {441  ompt_record_target_t SubRecordTarget{442      /*kind=*/ompt_target_t::ompt_target_update,443      /*endpoint=*/ompt_scope_endpoint_t::ompt_scope_begin,444      /*device_num=*/2,445      /*task_id=*/127,446      /*target_id=*/31,447      /*codeptr_ra=*/(const void *)0x11};448 449  ompt_record_ompt_t TargetRecord{450      /*type=*/ompt_callbacks_t::ompt_callback_target,451      /*time=*/7,452      /*thread_id=*/29,453      /*target_id=*/31,454      /*record*/ {.target = SubRecordTarget}};455 456  internal::BufferRecord BR{/*RecordPtr=*/&TargetRecord};457 458  std::ostringstream StreamBR;459  StreamBR << "rec=" << std::showbase << std::hex << &TargetRecord;460  StreamBR << " type=8 (Target task) time=7 thread_id=29 target_id=31 kind=4";461  StreamBR << " endpoint=1 device=2 task_id=127 codeptr=0x11";462 463  EXPECT_EQ(BR.toString(), StreamBR.str());464}465 466TEST(InternalEvent_toString, BufferRecordDataOp) {467  ompt_record_target_data_op_t SubRecordTargetDataOp{468      /*host_op_id=*/7,469      /*optype=*/ompt_target_data_op_t::ompt_target_data_alloc_async,470      /*src_addr=*/(void *)0x11,471      /*src_device_num=*/1,472      /*dest_addr=*/(void *)0x22,473      /*dest_device_num=*/2,474      /*bytes=*/127,475      /*end_time=*/128,476      /*codeptr_ra=*/(const void *)0x33,477  };478 479  ompt_record_ompt_t DataOpRecord{480      /*type=*/ompt_callbacks_t::ompt_callback_target_data_op_emi,481      /*time=*/8,482      /*thread_id=*/3,483      /*target_id=*/5,484      /*record=*/{.target_data_op = SubRecordTargetDataOp}};485 486  internal::BufferRecord BR{/*RecordPtr=*/&DataOpRecord};487 488  std::ostringstream StreamBR;489  StreamBR << "rec=" << std::showbase << std::hex << &DataOpRecord;490  StreamBR << " type=34 (Target data op) time=8 thread_id=3 target_id=5";491  StreamBR << " host_op_id=7 optype=17 src_addr=0x11 src_device=1";492  StreamBR << " dest_addr=0x22 dest_device=2 bytes=127 end_time=128";493  StreamBR << " duration=120 ns codeptr=0x33";494 495  EXPECT_EQ(BR.toString(), StreamBR.str());496}497 498TEST(InternalEvent_toString, BufferRecordKernel) {499  ompt_record_target_kernel_t SubRecordTargetKernel{500      /*host_op_id=*/11,501      /*requested_num_teams=*/127,502      /*granted_num_teams=*/63,503      /*end_time=*/8191,504  };505 506  ompt_record_ompt_t KernelRecord{507      /*type=*/ompt_callbacks_t::ompt_callback_target_submit_emi,508      /*time=*/9,509      /*thread_id=*/19,510      /*target_id=*/33,511      /*record=*/{.target_kernel = SubRecordTargetKernel}};512 513  internal::BufferRecord BR{/*RecordPtr=*/&KernelRecord};514 515  std::ostringstream StreamBR;516  StreamBR << "rec=" << std::showbase << std::hex << &KernelRecord;517  StreamBR << " type=35 (Target kernel) time=9 thread_id=19 target_id=33";518  StreamBR << " host_op_id=11 requested_num_teams=127 granted_num_teams=63";519  StreamBR << " end_time=8191 duration=8182 ns";520 521  EXPECT_EQ(BR.toString(), StreamBR.str());522}523 524TEST(InternalEvent_toString, BufferRecordDeallocation) {525  internal::BufferRecordDeallocation BRD{/*Buffer=*/(ompt_record_ompt_t *)0x11};526  internal::BufferRecordDeallocation BRDNull{/*Buffer=*/nullptr};527 528  EXPECT_EQ(BRD.toString(), "Deallocated 0x11");529  EXPECT_EQ(BRDNull.toString(), "Deallocated (nil)");530}531