Skip to content

Commit

Permalink
Merge pull request #77 from SLongshaw/master
Browse files Browse the repository at this point in the history
Enforce output order of create_uniface function
  • Loading branch information
SLongshaw authored Aug 27, 2021
2 parents 344b495 + 1b859cf commit f8ee4a4
Show file tree
Hide file tree
Showing 7 changed files with 4,750 additions and 7 deletions.
3 changes: 3 additions & 0 deletions comm.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ class communicator {
virtual int local_rank() const { return 0; }
virtual int local_size() const { return 1; }
virtual int remote_size() const { return 1; }
virtual std::string uri_host() const { return std::string(); }
virtual std::string uri_path() const { return std::string(); }
virtual std::string uri_protocol() const { return std::string(); }

// send message
void send( message msg, const std::vector<bool> &is_sending ) {
Expand Down
12 changes: 11 additions & 1 deletion comm_mpi.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ class comm_mpi : public communicator {
comm_mpi(const char URI[], MPI_Comm world ) :
domain_local_(0), domain_remote_(0),
local_size_(0), local_rank_(0), remote_size_(0), global_size_(0), global_rank_(0),
initialized(false), init_by_me(false) {
initialized(false), init_by_me(false), uri_host_(std::string()), uri_path_(std::string()),
uri_protocol_(std::string()) {
init(URI, world);
}
virtual ~comm_mpi() {
Expand Down Expand Up @@ -100,6 +101,9 @@ class comm_mpi : public communicator {

// parse URI, split the world using domain tag
uri desc(URI);
uri_host_ = desc.host();
uri_path_ = desc.path();
uri_protocol_ = desc.protocol();
int domain_hash = std::hash<std::string>()( desc.host() );
domain_hash=std::abs(domain_hash);
int ifs_hash = std::hash<std::string>()( desc.path() );
Expand Down Expand Up @@ -146,6 +150,9 @@ class comm_mpi : public communicator {
virtual int remote_size() const { return remote_size_; }
virtual int global_size() const { return global_size_; }
virtual int global_rank() const { return global_rank_; }
virtual std::string uri_host() const { return uri_host_; }
virtual std::string uri_path() const { return uri_path_; }
virtual std::string uri_protocol() const { return uri_protocol_; }

protected:
MPI_Comm domain_local_;
Expand All @@ -155,6 +162,9 @@ class comm_mpi : public communicator {
int remote_size_;
int global_size_;
int global_rank_;
std::string uri_host_;
std::string uri_path_;
std::string uri_protocol_;
private:
bool initialized, init_by_me;
};
Expand Down
25 changes: 20 additions & 5 deletions lib_mpi_multidomain.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,14 @@ inline std::vector<std::unique_ptr<uniface<CONFIG>>> create_uniface( std::string
MPI_Comm_rank( world, &global_rank );

std::map<int, std::string> map;

std::vector<int> my_hashes;
for( auto &i : interfaces ) {
auto h = std::hash<std::string>()( i );
my_hashes.push_back( h );
map[h] = i;
}

for( int i = 0; i < global_size; i++ ) {
if( global_rank == i ) {
for( auto &e : map ) {
Expand All @@ -87,7 +89,7 @@ inline std::vector<std::unique_ptr<uniface<CONFIG>>> create_uniface( std::string
int n_unique;
std::set<int> unique_ifs;
if( global_rank == 0 ) {
std::vector<int> nifs = gather( ( int )interfaces.size(), world );
std::vector<int> nifs = gather( static_cast<int>(interfaces.size()), world );
std::vector<int> displs( global_size + 1, 0 );
std::partial_sum( nifs.begin(), nifs.end(), displs.begin() + 1 );

Expand All @@ -101,34 +103,47 @@ inline std::vector<std::unique_ptr<uniface<CONFIG>>> create_uniface( std::string
gather( ( int )interfaces.size(), world );
MPI_Gatherv( my_hashes.data(), my_hashes.size(), MPI_INT, NULL, NULL, NULL, MPI_INT, 0, world );
}

MPI_Barrier( world );
MPI_Bcast( &n_unique, 1, MPI_INT, 0, world );
std::vector<int> uniq_hashes( n_unique );
if( global_rank == 0 ) uniq_hashes.assign( unique_ifs.begin(), unique_ifs.end() );
MPI_Bcast( uniq_hashes.data(), n_unique, MPI_INT, 0, world );

std::vector<std::unique_ptr<uniface<CONFIG>>> unifaces;
std::vector<uniface<CONFIG>*> unifaces;
for( auto &i : uniq_hashes ) {
MPI_Comm comm_ifs;
if( map.find( i ) != map.end() ) {
MPI_Comm_split( world, 1, global_rank, &comm_ifs );
int comm_rank;
MPI_Comm_rank( comm_ifs, &comm_rank );
if( comm_rank == 0 ){
if( comm_rank == 0 ) {
std::cout << "MUI [lib_mpi_multidomain]: Setting up interface " << map[i] << " [" << std::hex << i
<< std::dec << "] (rank ids are local to each interface)" << std::endl;
}
std::string full_uri( "mpi://" );
full_uri = full_uri + domain + "/" + map[i];
unifaces.push_back( std::unique_ptr<uniface<CONFIG>>(new uniface<CONFIG>( new comm_mpi_smart( full_uri.c_str(), comm_ifs ) )) );
unifaces.push_back( new uniface<CONFIG>( new comm_mpi_smart( full_uri.c_str(), comm_ifs ) ) );
} else {
MPI_Comm_split( world, 0, global_rank, &comm_ifs );
}

MPI_Barrier( world );
}

return unifaces;
// Sort return vector into original interface order (order can be mangled due to use of hash values)
std::vector<std::unique_ptr<uniface<CONFIG>>> unifaces_sorted;

for (const auto &orig_inter : interfaces) {
for (auto &uni : unifaces) {
if( uni->uri_path().compare(orig_inter) == 0 ) {
unifaces_sorted.push_back( std::unique_ptr<uniface<CONFIG>>(uni) );
break;
}
}
}

return unifaces_sorted;
}

// Ensure all interfaces in the range of the two iterators have hit sync_all
Expand Down
18 changes: 18 additions & 0 deletions uniface.h
Original file line number Diff line number Diff line change
Expand Up @@ -740,6 +740,24 @@ class uniface {
memory_length = length;
}

/** \brief Returns the URI host (domain) for the created uniface
*/
std::string uri_host() {
return comm->uri_host();
}

/** \brief Returns the URI path (name) for the created uniface
*/
std::string uri_path() {
return comm->uri_path();
}

/** \brief Returns the URI protocol for the created uniface
*/
std::string uri_protocol() {
return comm->uri_protocol();
}

private:
/** \brief Triggers communication
*/
Expand Down
2 changes: 1 addition & 1 deletion wrappers/C/config_c_wrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
* @author S. M. Longshaw
* @date 12 July 2021
* @brief File containing data structures defining all data types used
* by an interface using the C wrapper - based on original config.h.
* by an interface using the C wrapper - based on original config.h.
*/

#ifndef CONFIG_C_WRAPPER_H
Expand Down
120 changes: 120 additions & 0 deletions wrappers/Fortran/config_f_wrapper.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/*****************************************************************************
* Multiscale Universal Interface Code Coupling Library *
* *
* Copyright (C) 2021 Y. H. Tang, S. Kudo, X. Bian, Z. Li, G. E. Karniadakis, *
* S. M. Longshaw *
* *
* This software is jointly licensed under the Apache License, Version 2.0 *
* and the GNU General Public License version 3, you may use it according *
* to either. *
* *
* ** Apache License, version 2.0 ** *
* *
* Licensed under the Apache License, Version 2.0 (the "License"); *
* you may not use this file except in compliance with the License. *
* You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, software *
* distributed under the License is distributed on an "AS IS" BASIS, *
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
* See the License for the specific language governing permissions and *
* limitations under the License. *
* *
* ** GNU General Public License, version 3 ** *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
*****************************************************************************/

/**
* @file config_f_wrapper.h
* @author S. M. Longshaw
* @date 11 August 2021
* @brief File containing data structures defining all data types used
* by an interface using the Fortran wrapper - based on original config.h.
*/

#ifndef CONFIG_F_WRAPPER_H
#define CONFIG_F_WRAPPER_H

#include "../../util.h"
#include "../../dim.h"
#include "../../exception.h"

namespace mui {

struct mui_f_wrapper_1D {
using EXCEPTION = exception_segv; //- Exception handling type

static const bool DEBUG = false; //- Enable extra debugging output
static const int D = 1; //- Dimensionality of the domain
static const bool FIXEDPOINTS = false; //- Enable optimisations for problems with fixed point structure
static const bool QUIET = false; //- If the library is quiet then it will only issue critical warning messages

using REAL = double; //- REAL data type
using INT = int; //- INT data type

using time_type = REAL; //- time_type INT for iteration coupling, REAL for exact coupling
using point_type = point<REAL,D>; //- "point" data type and dimensionality
using data_types = type_list<int32_t, //- Data types that can be used in the interface
int64_t,
double,
float
>;
};

struct mui_f_wrapper_2D {
using EXCEPTION = exception_segv; //- Exception handling type

static const bool DEBUG = false; //- Enable extra debugging output
static const int D = 2; //- Dimensionality of the domain
static const bool FIXEDPOINTS = false; //- Enable optimisations for problems with fixed point structure
static const bool QUIET = false; //- If the library is quiet then it will only issue critical warning messages

using REAL = double; //- REAL data type
using INT = int; //- INT data type

using time_type = REAL; //- time_type INT for iteration coupling, REAL for exact coupling
using point_type = point<REAL,D>; //- "point" data type and dimensionality
using data_types = type_list<int32_t, //- Data types that can be used in the interface
int64_t,
double,
float
>;
};

struct mui_f_wrapper_3D {
using EXCEPTION = exception_segv; //- Exception handling type

static const bool DEBUG = false; //- Enable extra debugging output
static const int D = 3; //- Dimensionality of the domain
static const bool FIXEDPOINTS = false; //- Enable optimisations for problems with fixed point structure
static const bool QUIET = false; //- If the library is quiet then it will only issue critical warning messages

using REAL = double; //- REAL data type
using INT = int; //- INT data type

using time_type = REAL; //- time_type INT for iteration coupling, REAL for exact coupling
using point_type = point<REAL,D>; //- "point" data type and dimensionality
using data_types = type_list<int32_t, //- Data types that can be used in the interface
int64_t,
double,
float
>;
};

}

#endif
Loading

0 comments on commit f8ee4a4

Please sign in to comment.