83 const char * yo =
"Zoltan2_Directory::allocate";
85 if (debug_level > 4) {
90 size_t array[3], max_array[3], min_array[3];
91 array[0] =
sizeof(lid_t);
92 array[1] =
sizeof(gid_t);
94 Teuchos::reduceAll<int,size_t>(
95 *comm, Teuchos::REDUCE_MAX, 3, array, max_array);
96 Teuchos::reduceAll<int,size_t>(
97 *comm, Teuchos::REDUCE_MIN, 3, array, min_array);
98 if (max_array[0] != min_array[0] || max_array[1] != min_array[1]
99 || max_array[2] != min_array[2]) {
100 throw std::invalid_argument(
101 "Zoltan2_Directory() LID, GID, USER data lengths differ globally");
108 size_t user_base_size = is_Zoltan2_Directory_Vector() ?
sizeof(size_t) :
109 size_of_value_type();
112 size_t size =
sizeof(gid_t) + (use_lid?
sizeof(lid_t):0) + user_base_size;
115 update_msg_size = size +
sizeof(Zoltan2_DD_Update_Msg<gid_t,lid_t>);
118 size =
sizeof(gid_t);
119 remove_msg_size = size +
sizeof(Zoltan2_DD_Remove_Msg<gid_t,lid_t>);
135 max_id_size = std::max(
sizeof(gid_t),
sizeof(lid_t));
137 size = max_id_size + user_base_size;
138 find_msg_size = size +
sizeof(Zoltan2_DD_Find_Msg<gid_t,lid_t>);
149 if (debug_level > 4) {
164 size_t count,
const gid_t * gid,
const lid_t * lid,
165 const user_t * user,
const int * partition,
170 this->mode = update_mode;
172 const char * yo =
"Zoltan2_Directory::update";
174 if (debug_level > 4) {
181 for(
size_t n = 0; n < node_map.size(); ++n) {
182 node_map.value_at(n).errcheck = -1;
186 if (debug_level > 6) {
193 Teuchos::ArrayRCP<int> procs;
195 procs = Teuchos::arcp(
new int[count], 0, count,
true);
199 Teuchos::ArrayRCP<int> msg_sizes;
200 int sum_msg_size = 0;
201 if(is_Zoltan2_Directory_Vector() && count > 0) {
202 msg_sizes = Teuchos::arcp(
new int[count], 0, count,
true);
203 for (
size_t i = 0; i < count; i++) {
204 size_t msg_size = get_update_msg_size(user[i]);
205 sum_msg_size += msg_size;
206 msg_sizes[i] = msg_size;
210 sum_msg_size = update_msg_size * count;
213 Teuchos::ArrayRCP<char> sbuff;
215 sbuff = Teuchos::arcp(
new char[sum_msg_size], 0, sum_msg_size,
true);
218 typedef Zoltan2_DD_Update_Msg<gid_t,lid_t> msg_t;
221 int track_offset = 0;
222 char * trackptr = sbuff.getRawPtr();
223 for (
size_t i = 0; i < count; i++) {
225 procs[i] = hash_proc(gid[i]);
229 msg_t *ptr =
reinterpret_cast<msg_t*
>(trackptr);
232 ptr->lid_flag = lid ? 1 : 0;
233 ptr->user_flag = user ? 1 : 0;
234 ptr->partition_flag = partition ? 1 : 0;
235 ptr->partition = partition ? partition[i] : -1;
236 ptr->owner = comm->getRank();
239 gid_t * pgid = ptr->adjData;
245 throw std::logic_error(
246 "Did not pass lid values but directory was created to use them!");
248 lid_t * plid =
reinterpret_cast<lid_t*
>(ptr->adjData + 1);
253 throw std::logic_error(
254 "Passed lid values but directory was created not to use them!");
260 reinterpret_cast<char*
>(ptr->adjData) +
sizeof(gid_t) +
261 (use_lid?
sizeof(lid_t):0));
267 user_to_raw(user[i], puser);
277 size_t new_update_msg_size =
278 is_Zoltan2_Directory_Vector() ? msg_sizes[i] : update_msg_size;
279 track_offset += new_update_msg_size;
280 trackptr += new_update_msg_size;
285 if(track_offset != sum_msg_size) {
286 throw std::logic_error(
"Bad summing!");
289 if (debug_level > 6) {
298 int nrec = directoryComm.getNRec();
301 throw std::logic_error(
"Zoltan2_Directory::update() Comm_Create error");
304 if (debug_level > 6) {
308 int sum_recv_sizes = 0;
309 if(is_Zoltan2_Directory_Vector()) {
311 err = directoryComm.resize(msg_sizes,
315 sum_recv_sizes = update_msg_size * nrec;
319 throw std::logic_error(
"directoryComm.execute_resize error");
326 if(nrec &&
static_cast<int>(node_map.size()) < nrec) {
332 rehash_node_map(nrec);
336 Teuchos::ArrayRCP<char> rbuff;
337 if(sum_recv_sizes > 0) {
338 rbuff = Teuchos::arcp(
339 new char[sum_recv_sizes], 0, sum_recv_sizes,
true);
344 const int nbytes = is_Zoltan2_Directory_Vector() ? 1 : update_msg_size;
347 sbuff, nbytes, rbuff);
350 throw std::logic_error(
"Zoltan2_Directory::update() Comm_Do error");
353 if (debug_level > 6) {
361 trackptr = rbuff.getRawPtr();
362 for (
int i = 0; i < nrec; i++) {
363 msg_t *ptr =
reinterpret_cast<msg_t*
>(trackptr);
365 user_t * puser = (ptr->user_flag) ?
366 (
user_t*)(
reinterpret_cast<char*
>(ptr->adjData) +
367 sizeof(gid_t) + (use_lid?
sizeof(lid_t):0)) : NULL;
369 err = update_local(ptr->adjData,
370 (ptr->lid_flag) ?
reinterpret_cast<lid_t*
>(ptr->adjData + 1) : NULL,
372 (ptr->partition_flag) ? (ptr->partition) : -1,
381 size_t delta_msg_size = get_update_msg_size(puser);
382 trackptr += delta_msg_size;
383 track_offset += delta_msg_size;
388 if(track_offset != sum_recv_sizes) {
389 throw std::logic_error(
"Did not sum!");
392 if (debug_level > 6) {
399 err = (errcount) ? 1 : 0;
404 sprintf (str,
"Processed %lu GIDs (%d local), %d GID errors", count,
405 directoryComm.getNRec(),
410 if (debug_level > 4) {
425 const char * yo =
"Zoltan2_Directory::update_local";
429 throw std::logic_error(
430 "Zoltan2_Directory::update_local() owner < 0");
432 if (owner >= comm->getSize()) {
433 throw std::logic_error(
434 "Zoltan2_Directory::update_local() owner >= comm->getSize()");
437 throw std::logic_error(
438 "Zoltan2_Directory::update_local() gid == NULL");
441 if (debug_level > 5) {
446 size_t node_index = node_map.find(*gid);
447 if(node_map.valid_at(node_index)) {
448 Zoltan2_Directory_Node<gid_t,lid_t,user_t> & node =
449 node_map.value_at(node_index);
456 update_local_user(user, node.userData);
460 if (partition != -1) {
461 node.partition = partition;
474 if(node.errcheck != -1 && mode ==
Replace) {
511 node.errcheck = owner;
513 if (debug_level > 5) {
523 Zoltan2_Directory_Node<gid_t,lid_t,user_t> node;
525 node.lid = lid ? (*lid) : lid_t();
531 raw_to_user(user, node.userData);
537 node.partition = partition;
539 node.errcheck = owner;
541 if(node_map.insert(*gid, node).failed()) {
548 size_t new_guess_size = (node_map.size() < 10) ? 10 :
549 ( node_map.size() + node_map.size()/10);
550 rehash_node_map(new_guess_size);
551 if(node_map.insert(*gid, node).failed()) {
552 throw std::logic_error(
"Hash insert failed. Mem sufficient?....");
556 if (debug_level > 6) {
560 if (debug_level > 5) {
575 bool throw_if_missing)
577 const char * yo =
"Zoltan2_Directory::find";
579 if (debug_level > 4) {
586 Teuchos::ArrayRCP<int> procs;
588 procs = Teuchos::arcp(
589 new int[count], 0, count,
true);
593 for (
size_t i = 0; i < count; i++) {
594 procs[i] = hash_proc(gid[i]);
600 int nrec = directoryComm.getNRec();
602 if (debug_level > 6) {
607 throw std::logic_error(
"Zoltan2_Directory::find() error");
610 Teuchos::ArrayRCP<char> sbuff;
612 sbuff = Teuchos::arcp(
new char[find_msg_size*count],
613 0, find_msg_size*count,
true);
616 typedef Zoltan2_DD_Find_Msg<gid_t,lid_t> msg_t;
619 char *trackptr = sbuff.getRawPtr();
620 for (
size_t i = 0; i < count; i++) {
621 msg_t *ptr =
reinterpret_cast<msg_t*
>(trackptr);
623 ptr->proc = procs[i];
624 *(ptr->adjData) = gid[i];
625 trackptr += find_msg_size;
628 if (debug_level > 6) {
633 throw std::logic_error(
"directoryComm.execute_resize error");
637 Teuchos::ArrayRCP<char> rbuff;
639 rbuff = Teuchos::arcp(
new char[nrec * find_msg_size],
640 0, nrec * find_msg_size,
true);
643 const int nbytes = find_msg_size;
649 throw std::logic_error(
"Zoltan2_Directory::find() error");
652 if (debug_level > 6) {
658 Teuchos::ArrayRCP<int> rmsg_sizes_resized;
660 rmsg_sizes_resized = Teuchos::arcp(
new int[nrec], 0, nrec,
true);
662 Teuchos::ArrayRCP<int>::size_type sum_rmsg_sizes_resized = 0;
664 char *track_ptr = rbuff.getRawPtr();
665 for (
int i = 0; i < nrec; i++) {
666 msg_t *msg =
reinterpret_cast<msg_t*
>(track_ptr);
667 track_ptr += find_msg_size;
668 size_t find_rmsg_size_resized = get_local_find_msg_size(msg->adjData,
670 rmsg_sizes_resized[i] = find_rmsg_size_resized;
671 sum_rmsg_sizes_resized += find_rmsg_size_resized;
674 Teuchos::ArrayRCP<char>::size_type track_offset_resized = 0;
676 Teuchos::ArrayRCP<char> rbuff_resized_build;
678 if(is_Zoltan2_Directory_Vector()) {
680 if(sum_rmsg_sizes_resized > 0) {
681 rbuff_resized_build = Teuchos::arcp(
new char[sum_rmsg_sizes_resized],
682 0, sum_rmsg_sizes_resized,
true);
685 track_ptr = rbuff.getRawPtr();
686 char * track_ptr_resized = rbuff_resized_build.getRawPtr();
687 for (
int i = 0; i < nrec; i++) {
688 memcpy(track_ptr_resized, track_ptr, find_msg_size);
689 track_ptr += find_msg_size;
690 track_ptr_resized += rmsg_sizes_resized[i];
696 Teuchos::ArrayRCP<char> rbuff_resized = is_Zoltan2_Directory_Vector() ?
697 rbuff_resized_build : rbuff;
700 track_offset_resized = 0;
701 track_ptr = rbuff_resized.getRawPtr();
702 for (
int i = 0; i < nrec; i++) {
703 typedef Zoltan2_DD_Find_Msg<gid_t,lid_t> find_msg_t;
704 find_msg_t *ptr =
reinterpret_cast<find_msg_t*
>(track_ptr);
706 reinterpret_cast<char*
>(ptr->adjData) + max_id_size);
712 err = find_local(ptr->adjData, (lid_t*)ptr->adjData,
713 puser, &ptr->partition, &ptr->proc, throw_if_missing);
715 const size_t & size_shift = rmsg_sizes_resized[i];
716 track_offset_resized += size_shift;
717 track_ptr += size_shift;
720 if(track_offset_resized != sum_rmsg_sizes_resized) {
721 throw std::logic_error(
"Bad sum!");
725 size_t size_scale = is_Zoltan2_Directory_Vector() ? 1 : find_msg_size;
727 Teuchos::ArrayRCP<char> sbuff_resized;
728 if(!is_Zoltan2_Directory_Vector()) {
729 sbuff_resized = sbuff;
732 if(is_Zoltan2_Directory_Vector()) {
734 rbuff_resized, size_scale, rmsg_sizes_resized, sbuff_resized);
738 rbuff_resized, size_scale, Teuchos::null, sbuff_resized);
742 throw std::logic_error(
"Zoltan2_Directory::find() do reverse failed");
745 if (debug_level > 6) {
750 track_offset_resized = 0;
753 char * trackptr_resized = sbuff_resized.getRawPtr();
754 for (
size_t i = 0; i < count; i++) {
756 if(track_offset_resized >= sbuff_resized.size()) {
758 "%d has gid.size() %d track_offset_resized: %d sbuff_resized: %d\n",
760 (
int) count, (
int) track_offset_resized, (
int) sbuff_resized.size());
761 throw std::logic_error(
"Bad buffer overflow! Internal error.");
764 msg_t *ptr =
reinterpret_cast<msg_t*
>(trackptr_resized);
767 owner[ptr->index] = ptr->proc;
769 partition[ptr->index] = ptr->partition ;
771 memcpy (&lid[ptr->index], ptr->adjData,
sizeof(lid_t));
775 reinterpret_cast<char*
>(ptr->adjData) + max_id_size);
783 if(ptr->proc != -1 && user) {
784 raw_to_user(pRead, user[ptr->index]);
789 size_t incoming_size = get_incoming_find_msg_size(ptr);
790 trackptr_resized += incoming_size;
791 track_offset_resized += incoming_size;
794 if(track_offset_resized != sbuff_resized.size()) {
795 throw std::logic_error(
"Bad buffer sum!");
798 if (debug_level > 6) {
803 Teuchos::reduceAll<int>(*comm, Teuchos::REDUCE_SUM, 1, &errcount, &err);
807 if (debug_level > 0) {
809 sprintf(str,
"Processed %lu GIDs, GIDs not found: %d", count, errcount);
813 if (debug_level > 4) {
827 bool throw_if_missing)
const
829 const char * yo =
"Zoltan2_Directory::find_local";
832 if (owner == NULL || gid == NULL) {
833 throw std::logic_error(
"Zoltan2_Directory::find_local() Invalid input");
836 if (debug_level > 5) {
845 size_t node_index = node_map.find(*gid);
846 if(node_map.valid_at(node_index))
848 const Zoltan2_Directory_Node<gid_t,lid_t,user_t> & node =
849 node_map.value_at(node_index);
856 user_to_raw(node.userData, user);
859 if (owner) *owner = node.owner;
860 if (partition) *partition = node.partition;
862 if (debug_level > 5) {
872 if (debug_level > 5) {
876 if(throw_if_missing) {
879 throw std::logic_error(
"find_local did not succeed");
954 const char * yo =
"Zoltan2_Directory::remove";
956 if (debug_level > 4) {
963 Teuchos::ArrayRCP<int> procs;
964 Teuchos::ArrayRCP<char> sbuff;
966 procs = Teuchos::arcp(
967 new int[count], 0, count,
true);
968 sbuff = Teuchos::arcp(
969 new char[count*remove_msg_size], 0, count*remove_msg_size,
true);
972 typedef Zoltan2_DD_Remove_Msg<gid_t,lid_t> msg_t;
975 char * trackptr = sbuff.getRawPtr();
976 for (
size_t i = 0; i < count; i++) {
977 procs[i] = hash_proc(gid[i]);
978 msg_t *ptr =
reinterpret_cast<msg_t*
>(trackptr);
979 ptr->owner = comm->getRank();
980 *(ptr->adjData) = gid[i];
981 trackptr += remove_msg_size;
987 int nrec = directoryComm.getNRec();
990 throw std::logic_error(
"Zoltan_Comm_Create failed");
993 if (debug_level > 6) {
998 Teuchos::ArrayRCP<char> rbuff;
1000 rbuff = Teuchos::arcp(
new char[nrec*remove_msg_size],
1001 0, nrec*remove_msg_size,
true);
1006 sbuff, remove_msg_size, rbuff);
1009 throw std::logic_error(
"Comm_Do error");
1012 if (debug_level > 6) {
1026 node_map.begin_erase();
1027 for (
int i = 0; i < nrec; i++) {
1028 msg_t *ptr =
reinterpret_cast<msg_t*
>(&(rbuff[i*remove_msg_size]));
1029 err = remove_local(ptr->adjData);
1034 node_map.end_erase();
1041 sprintf (str,
"Processed %zu GIDs (%d local), %d GIDs not found",
1042 count, nrec, errcount);
1044 err = (errcount) ? 1 : 0;