/* * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana * University Research and Technology * Corporation. All rights reserved. * Copyright (c) 2004-2005 The University of Tennessee and The University * of Tennessee Research Foundation. All rights * reserved. * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, * University of Stuttgart. All rights reserved. * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow * * $HEADER$ */ #include "ompi_config.h" #include "mpi.h" #include "mca/mca.h" #include "mca/coll/coll.h" #include "request/request.h" #include "mca/pml/pml.h" /* need to include our own topo prototypes so we can malloc data on the comm correctly */ #include "coll_tuned_topo.h" /* also need the dynamic rule structures */ #include "coll_tuned_dynamic_rules.h" #include #include ompi_coll_alg_rule_t* coll_tuned_mk_alg_rules (int n_alg) { int i; ompi_coll_alg_rule_t* alg_rules; alg_rules = (ompi_coll_alg_rule_t *) calloc (n_alg, sizeof (ompi_coll_alg_rule_t)); if (!alg_rules) return (alg_rules); /* set all we can at this point */ for (i=0;ialg_rule_id, msg_p->com_rule_id, msg_p->mpi_comsize, msg_p->msg_rule_id); printf("msg_size %6d -> algorithm %2d\tsegsize %5d\n", msg_p->msg_size, msg_p->result_alg, msg_p->result_segsize); return (0); } int coll_tuned_dump_com_rule (ompi_coll_com_rule_t* com_p) { int i; ompi_coll_msg_rule_t* msg_p; if (!com_p) { fprintf(stderr,"Com rule was a NULL ptr?!\n"); return (-1); } printf("alg_id %3d\tcom_id %3d\tcom_size %3d\t", com_p->alg_rule_id, com_p->com_rule_id, com_p->mpi_comsize); if (!com_p->n_msg_sizes) { printf("no msgsizes defined\n"); return (0); } printf("number of message sizes %3d\n", com_p->n_msg_sizes); for (i=0;in_msg_sizes;i++) { coll_tuned_dump_msg_rule (&(com_p->msg_rules[i])); } return (0); } int coll_tuned_dump_alg_rule (ompi_coll_alg_rule_t* alg_p) { int i; ompi_coll_com_rule_t* com_p; if (!alg_p) { fprintf(stderr,"Algorithm rule was a NULL ptr?!\n"); return (-1); } printf("alg_id %3d\t", alg_p->alg_rule_id); if (!alg_p->n_com_sizes) { printf("no coms defined\n"); return (0); } printf("number of com sizes %3d\n", alg_p->n_com_sizes); for (i=0;in_com_sizes;i++) { coll_tuned_dump_com_rule (&(alg_p->com_rules[i])); } return (0); } int coll_tuned_dump_all_rules (ompi_coll_alg_rule_t* alg_p, int n_rules) { int i; if (!alg_p) { fprintf(stderr,"Algorithm rule was a NULL ptr?!\n"); return (-1); } printf("Number of algorithm rules %3d\n", n_rules); for (i=0;in_msg_sizes) { msg_p = com_p->msg_rules; if (!msg_p) { fprintf(stderr,"attempt to free NULL msg_rules when msg count was %d\n", com_p->n_msg_sizes); rc = -1; /* some error */ } else { /* ok, memory exists for the msg rules so free that first */ free (com_p->msg_rules); com_p->msg_rules = (ompi_coll_msg_rule_t*) NULL; } } /* if we have msg rules to free as well */ return (rc); } int coll_tuned_free_coms_in_alg_rule (ompi_coll_alg_rule_t* alg_p) { int rc=0; int i; ompi_coll_com_rule_t* com_p; if (!alg_p) { fprintf(stderr,"attempt to free NULL alg_rule ptr\n"); return (-1); } if (alg_p->n_com_sizes) { com_p = alg_p->com_rules; if (!com_p) { fprintf(stderr,"attempt to free NULL com_rules when com count was %d\n", alg_p->n_com_sizes); } else { /* ok, memory exists for the com rules so free their message rules first */ for (i=0;in_com_sizes;i++) { com_p = &(alg_p->com_rules[i]); coll_tuned_free_msg_rules_in_com_rule (com_p); } /* we are now free to free the com rules themselives */ free (alg_p->com_rules); alg_p->com_rules = (ompi_coll_com_rule_t*) NULL; } } /* if we have msg rules to free as well */ return (rc); } int coll_tuned_free_all_rules (ompi_coll_alg_rule_t* alg_p, int n_algs) { int i; int rc; for(i=0;in_com_sizes) { /* check for count of communicator sizes */ return ((ompi_coll_com_rule_t*)NULL); /* no com sizes so no rule */ } /* ok have some com sizes, now to find the one closest to my mpi_comsize */ /* make a copy of the first com rule */ best_com_p = com_p = alg_p->com_rules; i = best = 0; while (in_com_sizes) { printf("checking comsize %d against alg_id %d com_id %d index %d com_size %d", mpi_comsize, com_p->alg_rule_id, com_p->com_rule_id, i, com_p->mpi_comsize); if (com_p->mpi_comsize <= mpi_comsize) { best = i; best_com_p = com_p; printf(":ok\n"); } else { printf(":nop\n"); break; } /* go to the next entry */ com_p++; i++; } printf("Selected the following com rule id %d\n", best_com_p->com_rule_id); coll_tuned_dump_com_rule (best_com_p); return (best_com_p); } /* * This function takes a com_rule ptr (from the communicators coll tuned data structure) * (Which is chosen for a particular MPI collective) * and a (total_)msg_size and it returns (0) and a algorithm to use and a recommended segment size * all based on the user supplied rules * * Just like the above functions it uses a less than or equal msg size * (hense config file must have a default defined for '0' if we reach this point) * else if no rules match we return '0' + '0' or used fixed decision table with no segmentation * of users data.. shame. * * On error return 0 so we default to fixed rules anyway :) * */ int coll_tuned_get_target_method_params (ompi_coll_com_rule_t* base_com_rule, int mpi_msgsize, int* result_segsize) { ompi_coll_msg_rule_t* msg_p = (ompi_coll_msg_rule_t*) NULL; ompi_coll_msg_rule_t* best_msg_p = (ompi_coll_msg_rule_t*) NULL; int i, best; if (!base_com_rule) { return (0); } if (!result_segsize) { return (0); } if (!base_com_rule->n_msg_sizes) { /* check for count of message sizes */ return (0); /* no msg sizes so no rule */ } /* ok have some msg sizes, now to find the one closest to my mpi_msgsize */ /* make a copy of the first msg rule */ best_msg_p = msg_p = base_com_rule->msg_rules; i = best = 0; while (in_msg_sizes) { printf("checking mpi_msgsize %d against com_id %d msg_id %d index %d msg_size %d", mpi_msgsize, msg_p->com_rule_id, msg_p->msg_rule_id, i, msg_p->msg_size); if (msg_p->msg_size <= mpi_msgsize) { best = i; best_msg_p = msg_p; printf(":ok\n"); } else { printf(":nop\n"); break; } /* go to the next entry */ msg_p++; i++; } printf("Selected the following msg rule id %d\n", best_msg_p->msg_rule_id); coll_tuned_dump_msg_rule (best_msg_p); /* return the segment size */ *result_segsize = best_msg_p->result_segsize; return (best_msg_p->result_alg); }