set(THREAD_PTHREADS 1)
#add_definitions(-DTHREAD_PTHREADS)
set(THREAD_MPI_SRC
- thread_mpi/barrier.c thread_mpi/hwinfo.c thread_mpi/pthreads.c
- thread_mpi/collective.c thread_mpi/list.c thread_mpi/reduce_fast.c
- thread_mpi/comm.c thread_mpi/lock.c thread_mpi/tmpi_init.c
- thread_mpi/errhandler.c thread_mpi/once.c thread_mpi/topology.c
- thread_mpi/event.c thread_mpi/p2p.c thread_mpi/type.c
- thread_mpi/group.c thread_mpi/profile.c)
+ thread_mpi/alltoall.c thread_mpi/p2p_protocol.c
+ thread_mpi/barrier.c thread_mpi/p2p_send_recv.c
+ thread_mpi/bcast.c thread_mpi/p2p_wait.c
+ thread_mpi/collective.c thread_mpi/profile.c
+ thread_mpi/comm.c thread_mpi/pthreads.c
+ thread_mpi/errhandler.c thread_mpi/reduce.c
+ thread_mpi/event.c thread_mpi/reduce_fast.c
+ thread_mpi/gather.c thread_mpi/scatter.c
+ thread_mpi/group.c thread_mpi/tmpi_init.c
+ thread_mpi/hwinfo.c thread_mpi/topology.c
+ thread_mpi/list.c thread_mpi/type.c
+ thread_mpi/lock.c
+ thread_mpi/once.c)
set(THREAD_LIB ${CMAKE_THREAD_LIBS_INIT})
else (CMAKE_USE_PTHREADS_INIT)
if (CMAKE_USE_WIN32_THREADS_INIT)
set(THREAD_WINDOWS 1)
#add_definitions(-DTHREAD_WINDOWS)
set(THREAD_MPI_SRC
- thread_mpi/barrier.c thread_mpi/hwinfo.c
- thread_mpi/collective.c thread_mpi/list.c thread_mpi/reduce_fast.c
- thread_mpi/comm.c thread_mpi/lock.c thread_mpi/tmpi_init.c
- thread_mpi/errhandler.c thread_mpi/once.c thread_mpi/topology.c
- thread_mpi/event.c thread_mpi/p2p.c thread_mpi/type.c
- thread_mpi/group.c thread_mpi/profile.c thread_mpi/winthreads.c)
+ thread_mpi/alltoall.c thread_mpi/p2p_protocol.c
+ thread_mpi/barrier.c thread_mpi/p2p_send_recv.c
+ thread_mpi/bcast.c thread_mpi/p2p_wait.c
+ thread_mpi/collective.c thread_mpi/profile.c
+ thread_mpi/comm.c
+ thread_mpi/errhandler.c thread_mpi/reduce.c
+ thread_mpi/event.c thread_mpi/reduce_fast.c
+ thread_mpi/gather.c thread_mpi/scatter.c
+ thread_mpi/group.c thread_mpi/tmpi_init.c
+ thread_mpi/hwinfo.c thread_mpi/topology.c
+ thread_mpi/list.c thread_mpi/type.c
+ thread_mpi/lock.c thread_mpi/winthreads.c
+ thread_mpi/once.c)
set(THREAD_LIBRARY )
endif (CMAKE_USE_WIN32_THREADS_INIT)
endif (CMAKE_USE_PTHREADS_INIT)
# Note that not all .c files are compiled directly: some of them
# are #included (some multiple times) from other source files.
-set(THREAD_MPI_LIB_SOURCE tmpi_init.c
- errhandler.c type.c group.c comm.c topology.c p2p.c collective.c
- once.c list.c reduce_fast.c profile.c event.c barrier.c
- lock.c hwinfo.c)
+set(THREAD_MPI_LIB_SOURCE
+ alltoall.c hwinfo.c reduce.c
+ barrier.c list.c reduce_fast.c
+ bcast.c lock.c scatter.c
+ collective.c once.c tmpi_init.c
+ comm.c p2p_protocol.c topology.c
+ errhandler.c p2p_send_recv.c type.c
+ event.c p2p_wait.c
+ gather.c profile.c
+ group.c )
if (THREAD_PTHREADS)
noinst_LTLIBRARIES = libthread_mpi.la
# again, we assume that we're using pthreads if we're using autotools.
-libthread_mpi_la_SOURCES = alltoall.h lock.c reduce_fast.c \
- barrier.c scatter.h bcast.h \
+libthread_mpi_la_SOURCES = alltoall.c lock.c reduce_fast.c \
+ barrier.c scatter.c bcast.c \
once.c settings.h collective.c \
- p2p.c \
- comm.c p2p_protocol.h tmpi_init.c \
- errhandler.c p2p_send_recv.h tmpi_ops.h \
- event.c p2p_wait.h topology.c \
- gather.h profile.c type.c \
+ p2p.h collective.h \
+ comm.c p2p_protocol.c tmpi_init.c \
+ errhandler.c p2p_send_recv.c tmpi_ops.h \
+ event.c p2p_wait.c topology.c \
+ gather.c profile.c type.c \
group.c profile.h hwinfo.c \
- pthreads.c impl.h pthreads.h\
- list.c reduce.h
+ pthreads.c impl.h pthreads.h \
+ list.c reduce.c
CLEANFILES = *.la *~ \\\#*
files.
*/
-/* this file is #included from collective.c; it's not really a header file,
- but this defines a lot of functions that probably need to be inlined.*/
+#ifdef HAVE_TMPI_CONFIG_H
+#include "tmpi_config.h"
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+
+#include "impl.h"
+#include "collective.h"
+
int tMPI_Alltoall(void* sendbuf, int sendcount, tMPI_Datatype sendtype,
be called official thread_mpi. Details are found in the README & COPYING
files.
*/
+#ifdef HAVE_TMPI_CONFIG_H
+#include "tmpi_config.h"
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include "impl.h"
+#include "collective.h"
-/* this file is to be #included from collective.c; it's not really a header
- file, but this defines a lot of functions that probably need to be inlined.*/
/* broadcast */
int tMPI_Bcast(void* buffer, int count, tMPI_Datatype datatype, int root,
#include <string.h>
#include "impl.h"
+#include "collective.h"
-/* get a pointer the next coll_env once it's ready */
-static struct coll_env *tMPI_Get_cev(tMPI_Comm comm, int myrank, int *synct);
-
-/* post the availability of data in a cev.
- cev = the collective comm environment
- myrank = my rank
- index = the buffer index
- tag = the tag
- datatype = the datatype
- busize = the buffer size
- buf = the buffer to xfer
- n_remaining = the number of remaining threads that need to transfer
- synct = the multicast sync number
- dest = -1 for all theads, or a specific rank number.
-*/
-static void tMPI_Post_multi(struct coll_env *cev, int myrank, int index,
- int tag, tMPI_Datatype datatype,
- size_t bufsize, void *buf, int n_remaining,
- int synct, int dest);
-
-/* transfer data from cev->met[rank] to recvbuf */
-static void tMPI_Mult_recv(tMPI_Comm comm, struct coll_env *cev, int rank,
- int index, int expected_tag, tMPI_Datatype recvtype,
- size_t recvsize, void *recvbuf, int *ret);
-
-/* do a root transfer (from root send buffer to root recv buffer) */
-static void tMPI_Coll_root_xfer(tMPI_Comm comm,
- tMPI_Datatype sendtype, tMPI_Datatype recvtype,
- size_t sendsize, size_t recvsize,
- void* sendbuf, void* recvbuf, int *ret);
-
-/* wait for other processes to copy data from my cev */
-static void tMPI_Wait_for_others(struct coll_env *cev, int myrank);
-/* wait for data to become available from a specific rank */
-static void tMPI_Wait_for_data(struct tmpi_thread *cur, struct coll_env *cev,
- int myrank);
- /*int rank, int myrank, int synct);*/
-
-/* run a single binary reduce operation on src_a and src_b, producing dest.
- dest and src_a may be identical */
-static int tMPI_Reduce_run_op(void *dest, void *src_a, void *src_b,
- tMPI_Datatype datatype, int count, tMPI_Op op,
- tMPI_Comm comm);
-
-static void tMPI_Coll_envt_init(struct coll_env_thread *met, int N)
+void tMPI_Coll_envt_init(struct coll_env_thread *met, int N)
{
tMPI_Atomic_set(&(met->current_sync), 0);
tMPI_Atomic_set(&(met->n_remaining), 0);
}
-static void tMPI_Coll_envt_destroy(struct coll_env_thread *met)
+void tMPI_Coll_envt_destroy(struct coll_env_thread *met)
{
free( (void*)met->buf );
free( (void*)met->bufsize );
/* get a pointer the next coll_env once it's ready. */
-static struct coll_env *tMPI_Get_cev(tMPI_Comm comm, int myrank, int *counter)
+struct coll_env *tMPI_Get_cev(tMPI_Comm comm, int myrank, int *counter)
{
struct coll_sync *csync=&(comm->csync[myrank]);
struct coll_env *cev;
-static void tMPI_Mult_recv(tMPI_Comm comm, struct coll_env *cev, int rank,
- int index, int expected_tag, tMPI_Datatype recvtype,
- size_t recvsize, void *recvbuf, int *ret)
+void tMPI_Mult_recv(tMPI_Comm comm, struct coll_env *cev, int rank,
+ int index, int expected_tag, tMPI_Datatype recvtype,
+ size_t recvsize, void *recvbuf, int *ret)
{
size_t sendsize=cev->met[rank].bufsize[index];
}
}
-static void tMPI_Coll_root_xfer(tMPI_Comm comm, tMPI_Datatype sendtype,
- tMPI_Datatype recvtype,
- size_t sendsize, size_t recvsize,
- void* sendbuf, void* recvbuf, int *ret)
+void tMPI_Coll_root_xfer(tMPI_Comm comm, tMPI_Datatype sendtype,
+ tMPI_Datatype recvtype,
+ size_t sendsize, size_t recvsize,
+ void* sendbuf, void* recvbuf, int *ret)
{
/* do root transfer */
if (recvsize < sendsize)
memcpy(recvbuf, sendbuf, sendsize);
}
-static void tMPI_Post_multi(struct coll_env *cev, int myrank, int index,
- int tag, tMPI_Datatype datatype, size_t bufsize,
- void *buf, int n_remaining, int synct, int dest)
+void tMPI_Post_multi(struct coll_env *cev, int myrank, int index,
+ int tag, tMPI_Datatype datatype, size_t bufsize,
+ void *buf, int n_remaining, int synct, int dest)
{
int i;
#ifdef USE_COLLECTIVE_COPY_BUFFER
}
-static void tMPI_Wait_for_others(struct coll_env *cev, int myrank)
+void tMPI_Wait_for_others(struct coll_env *cev, int myrank)
{
#if defined(TMPI_PROFILE)
struct tmpi_thread *cur=tMPI_Get_current();
#endif
}
-static void tMPI_Wait_for_data(struct tmpi_thread *cur, struct coll_env *cev,
- int myrank)
- /*int rank, int myrank, int synct)*/
+void tMPI_Wait_for_data(struct tmpi_thread *cur, struct coll_env *cev,
+ int myrank)
{
#if defined(TMPI_PROFILE)
tMPI_Profile_wait_start(cur);
-/* The actual collective functions are #included, so that the static
- functions above are available to them and can get inlined if the
- compiler deems it appropriate. */
-#include "bcast.h"
-#include "scatter.h"
-#include "gather.h"
-#include "alltoall.h"
-#include "reduce.h"
-
--- /dev/null
+/*
+This source code file is part of thread_mpi.
+Written by Sander Pronk, Erik Lindahl, and possibly others.
+
+Copyright (c) 2009, Sander Pronk, Erik Lindahl.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+1) Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2) Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+3) Neither the name of the copyright holders nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY US ''AS IS'' AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL WE BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+If you want to redistribute modifications, please consider that
+scientific software is very special. Version control is crucial -
+bugs must be traceable. We will be happy to consider code for
+inclusion in the official distribution, but derived work should not
+be called official thread_mpi. Details are found in the README & COPYING
+files.
+*/
+
+
+/* get a pointer the next coll_env once it's ready */
+struct coll_env *tMPI_Get_cev(tMPI_Comm comm, int myrank, int *synct);
+
+/* post the availability of data in a cev.
+ cev = the collective comm environment
+ myrank = my rank
+ index = the buffer index
+ tag = the tag
+ datatype = the datatype
+ busize = the buffer size
+ buf = the buffer to xfer
+ n_remaining = the number of remaining threads that need to transfer
+ synct = the multicast sync number
+ dest = -1 for all theads, or a specific rank number.
+ */
+void tMPI_Post_multi(struct coll_env *cev, int myrank, int index,
+ int tag, tMPI_Datatype datatype,
+ size_t bufsize, void *buf, int n_remaining,
+ int synct, int dest);
+
+/* transfer data from cev->met[rank] to recvbuf */
+void tMPI_Mult_recv(tMPI_Comm comm, struct coll_env *cev, int rank,
+ int index, int expected_tag, tMPI_Datatype recvtype,
+ size_t recvsize, void *recvbuf, int *ret);
+
+/* do a root transfer (from root send buffer to root recv buffer) */
+void tMPI_Coll_root_xfer(tMPI_Comm comm,
+ tMPI_Datatype sendtype, tMPI_Datatype recvtype,
+ size_t sendsize, size_t recvsize,
+ void* sendbuf, void* recvbuf, int *ret);
+
+/* wait for other processes to copy data from my cev */
+void tMPI_Wait_for_others(struct coll_env *cev, int myrank);
+/* wait for data to become available from a specific rank */
+void tMPI_Wait_for_data(struct tmpi_thread *cur, struct coll_env *cev,
+ int myrank);
+/*int rank, int myrank, int synct);*/
+
+
+
files.
*/
+#ifdef HAVE_TMPI_CONFIG_H
+#include "tmpi_config.h"
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
-/* this file is #included from collective.c; it's not really a header file,
- but this defines a lot of functions that probably need to be inlined.*/
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include "impl.h"
+#include "collective.h"
int tMPI_Gather(void* sendbuf, int sendcount, tMPI_Datatype sendtype,
void tMPI_Cart_destroy(struct cart_topol *top);
-#ifdef USE_COLLECTIVE_COPY_BUFFER
-/* initialize a copy_buffer_list */
-void tMPI_Copy_buffer_list_init(struct copy_buffer_list *cbl, int Nbufs,
- size_t size);
-/* initialize a copy_buffer_list */
-void tMPI_Copy_buffer_list_destroy(struct copy_buffer_list *cbl);
-/* get a copy buffer from a list */
-struct copy_buffer *tMPI_Copy_buffer_list_get(struct copy_buffer_list *cbl);
-/* return a copy buffer to a list */
-void tMPI_Copy_buffer_list_return(struct copy_buffer_list *cbl,
- struct copy_buffer *cb);
-/* initialize a copy buffer */
-void tMPI_Copy_buffer_init(struct copy_buffer *cb, size_t size);
-void tMPI_Copy_buffer_destroy(struct copy_buffer *cb);
-#endif
-
+/* collective data structure ops */
+
-/* multicast functions */
/* initialize a coll env structure */
void tMPI_Coll_env_init(struct coll_env *mev, int N);
/* destroy a coll env structure */
/* destroy a coll sync structure */
void tMPI_Coll_sync_destroy(struct coll_sync *msc);
+#ifdef USE_COLLECTIVE_COPY_BUFFER
+/* initialize a copy_buffer_list */
+void tMPI_Copy_buffer_list_init(struct copy_buffer_list *cbl, int Nbufs,
+ size_t size);
+/* initialize a copy_buffer_list */
+void tMPI_Copy_buffer_list_destroy(struct copy_buffer_list *cbl);
+/* get a copy buffer from a list */
+struct copy_buffer *tMPI_Copy_buffer_list_get(struct copy_buffer_list *cbl);
+/* return a copy buffer to a list */
+void tMPI_Copy_buffer_list_return(struct copy_buffer_list *cbl,
+ struct copy_buffer *cb);
+/* initialize a copy buffer */
+void tMPI_Copy_buffer_init(struct copy_buffer *cb, size_t size);
+void tMPI_Copy_buffer_destroy(struct copy_buffer *cb);
+#endif
+
+++ /dev/null
-/*
-This source code file is part of thread_mpi.
-Written by Sander Pronk, Erik Lindahl, and possibly others.
-
-Copyright (c) 2009, Sander Pronk, Erik Lindahl.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-1) Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2) Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3) Neither the name of the copyright holders nor the
- names of its contributors may be used to endorse or promote products
- derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY US ''AS IS'' AND ANY
-EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL WE BE LIABLE FOR ANY
-DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-If you want to redistribute modifications, please consider that
-scientific software is very special. Version control is crucial -
-bugs must be traceable. We will be happy to consider code for
-inclusion in the official distribution, but derived work should not
-be called official thread_mpi. Details are found in the README & COPYING
-files.
-*/
-
-#ifdef HAVE_TMPI_CONFIG_H
-#include "tmpi_config.h"
-#endif
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#include <errno.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-
-
-#include "impl.h"
-
-
-
-/* free envelopes: */
-static struct envelope *tMPI_Free_env_list_fetch_recv(struct free_envelope_list
- *evl);
-
-/* return an envelope to the free envelopes list */
-static void tMPI_Free_env_list_return_recv(struct free_envelope_list *evl,
- struct envelope *rev);
-
-
-
-/* send envelopes: */
-/* get a new envelope from the send list's free envelope list */
-static struct envelope*
-tMPI_Send_env_list_fetch_new(struct send_envelope_list *evl);
-
-/* return a send envelope to the send list's free envelope list,
- (to be used by the sending thread, who owns the send_envelope_list) */
-static void tMPI_Send_env_list_return(struct envelope *ev);
-#ifdef USE_SEND_RECV_COPY_BUFFER
-/* return a send envelope to the sender's send list.
- (to be used by the receiving thread). */
-static void tMPI_Send_env_list_rts(struct envelope *sev);
-#endif
-
-/* remove a send envelope from the old list. Does not lock */
-static void tMPI_Send_env_list_remove_old(struct envelope *sev);
-
-
-
-/* remove a send envelope from its head_old list. Does not lock */
-static void tMPI_Send_env_list_remove_old(struct envelope *sev);
-
-/* add a send envelope to the new envelopes queue in a list */
-static void tMPI_Send_env_list_add_new(struct tmpi_thread *cur,
- struct send_envelope_list *evl,
- struct envelope *sev);
-/* move a send envelope to the old envelopes queue in a list.
- Assumes that this is safe to do without interference
- from other threads, i.e. the list it's in must have been
- detached. */
-static void tMPI_Send_env_list_move_to_old(struct envelope *sev);
-
-
-/* receive envelopes: */
-/* add a receive envelope to a list */
-static void tMPI_Recv_env_list_add(struct recv_envelope_list *evl,
- struct envelope *ev);
-/* remove a receive envelope from its list */
-static void tMPI_Recv_env_list_remove(struct envelope *ev);
-
-
-
-
-/* request list: */
-/* get a request from the thread's pre-allocated request list */
-static struct tmpi_req_ *tMPI_Get_req(struct req_list *rl);
-/* return a request to the thread's pre-allocated request list */
-static void tMPI_Return_req(struct req_list *rl, struct tmpi_req_ *req);
-
-/* initialize a request with sensible values */
-static void tMPI_Req_init(struct tmpi_req_ *rq, struct envelope *ev);
-
-/* wait for incoming connections (and the completion of outgoing connections
- if spin locks are disabled), and handle them. */
-static void tMPI_Wait_process_incoming(struct tmpi_thread *th);
-
-/* do the actual point-to-point transfer */
-static void tMPI_Xfer(struct tmpi_thread *cur, struct envelope *sev,
- struct envelope *rev);
-
-
-/* check for the completion of a single request */
-static tmpi_bool tMPI_Test_single(struct tmpi_thread *cur,
- struct tmpi_req_ *rq);
-/* check and wait for the completion of a single request */
-static void tMPI_Wait_single(struct tmpi_thread *cur, struct tmpi_req_ *rq);
-
-/* check for the completion of a NULL-delimited doubly linked list of
- requests */
-static tmpi_bool tMPI_Test_multi(struct tmpi_thread *cur, struct tmpi_req_ *rqs,
- tmpi_bool *any_done);
-
-
-
-#include "p2p_protocol.h"
-#include "p2p_send_recv.h"
-#include "p2p_wait.h"
-
--- /dev/null
+/*
+This source code file is part of thread_mpi.
+Written by Sander Pronk, Erik Lindahl, and possibly others.
+
+Copyright (c) 2009, Sander Pronk, Erik Lindahl.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+1) Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2) Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+3) Neither the name of the copyright holders nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY US ''AS IS'' AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL WE BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+If you want to redistribute modifications, please consider that
+scientific software is very special. Version control is crucial -
+bugs must be traceable. We will be happy to consider code for
+inclusion in the official distribution, but derived work should not
+be called official thread_mpi. Details are found in the README & COPYING
+files.
+*/
+
+
+/* request list: */
+/* get a request from the thread's pre-allocated request list */
+struct tmpi_req_ *tMPI_Get_req(struct req_list *rl);
+/* return a request to the thread's pre-allocated request list */
+void tMPI_Return_req(struct req_list *rl, struct tmpi_req_ *req);
+
+/* initialize a request with sensible values */
+void tMPI_Req_init(struct tmpi_req_ *rq, struct envelope *ev);
+
+/* wait for incoming connections (and the completion of outgoing connections
+ if spin locks are disabled), and handle them. */
+void tMPI_Wait_process_incoming(struct tmpi_thread *th);
+
+
+
+
+
+/* check for the completion of a single request */
+tmpi_bool tMPI_Test_single(struct tmpi_thread *cur,
+ struct tmpi_req_ *rq);
+/* check and wait for the completion of a single request */
+void tMPI_Wait_single(struct tmpi_thread *cur, struct tmpi_req_ *rq);
+
+/* check for the completion of a NULL-delimited doubly linked list of
+ requests */
+tmpi_bool tMPI_Test_multi(struct tmpi_thread *cur, struct tmpi_req_ *rqs,
+ tmpi_bool *any_done);
+
+
+
+/* set a request status */
+void tMPI_Set_status(struct tmpi_req_ *req, tMPI_Status *st);
+
+
+/* post a send envelope */
+struct envelope *tMPI_Post_send(struct tmpi_thread *cur,
+ tMPI_Comm comm,
+ struct tmpi_thread *dest,
+ void *send_buf, int send_count,
+ tMPI_Datatype datatype, int tag,
+ tmpi_bool nonblock);
+
+/* post and match a receive envelope */
+struct envelope* tMPI_Post_match_recv(struct tmpi_thread *cur,
+ tMPI_Comm comm,
+ struct tmpi_thread *src,
+ void *recv_buf, int recv_count,
+ tMPI_Datatype datatype,
+ int tag, tmpi_bool nonblock);
+
+
files.
*/
-/* this file is included from p2p.c; it's not really a header file,
- but this defines a lot of functions that probably need to be inlined.*/
+#ifdef HAVE_TMPI_CONFIG_H
+#include "tmpi_config.h"
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+
+
+#include "impl.h"
+#include "p2p.h"
+
+/* free envelopes: */
+/* free envelopes: */
+static struct envelope *tMPI_Free_env_list_fetch_recv(struct free_envelope_list
+ *evl);
+
+/* return an envelope to the free envelopes list */
+static void tMPI_Free_env_list_return_recv(struct free_envelope_list *evl,
+ struct envelope *rev);
+
+
+
+/* send envelope lists: */
+/* send envelopes: */
+/* get a new envelope from the send list's free envelope list */
+static struct envelope* tMPI_Send_env_list_fetch_new(struct
+ send_envelope_list *evl);
+
+/* return a send envelope to the send list's free envelope list,
+ (to be used by the sending thread, who owns the send_envelope_list) */
+static void tMPI_Send_env_list_return(struct envelope *ev);
+#ifdef USE_SEND_RECV_COPY_BUFFER
+/* return a send envelope to the sender's send list.
+ (to be used by the receiving thread). */
+static void tMPI_Send_env_list_rts(struct envelope *sev);
+#endif
+
+
+
+
+/* send envelopes: */
+/* remove a send envelope from its head_old list. Does not lock */
+static void tMPI_Send_env_list_remove_old(struct envelope *sev);
+
+/* add a send envelope to the new envelopes queue in a list */
+static void tMPI_Send_env_list_add_new(struct tmpi_thread *cur,
+ struct send_envelope_list *evl,
+ struct envelope *sev);
+/* move a send envelope to the old envelopes queue in a list.
+ Assumes that this is safe to do without interference
+ from other threads, i.e. the list it's in must have been
+ detached. */
+static void tMPI_Send_env_list_move_to_old(struct envelope *sev);
+
+
-/* Point-to-point communication protocol functions */
+/* receive envelopes: */
+/* add a receive envelope to a list */
+static void tMPI_Recv_env_list_add(struct recv_envelope_list *evl,
+ struct envelope *ev);
+/* remove a receive envelope from its list */
+static void tMPI_Recv_env_list_remove(struct envelope *ev);
+
+
+
+/* do the actual point-to-point transfer */
+static void tMPI_Xfer(struct tmpi_thread *cur, struct envelope *sev,
+ struct envelope *rev);
+
+
+
+
+/* Point-to-point communication protocol functions */
void tMPI_Free_env_list_init(struct free_envelope_list *evl, int N)
{
int i;
}
-static struct envelope*
-tMPI_Send_env_list_fetch_new(struct send_envelope_list *evl)
+static struct envelope* tMPI_Send_env_list_fetch_new(struct
+ send_envelope_list *evl)
{
struct envelope *ret;
-static struct tmpi_req_ *tMPI_Get_req(struct req_list *rl)
+struct tmpi_req_ *tMPI_Get_req(struct req_list *rl)
{
struct tmpi_req_ *req=rl->head;
return req;
}
-static void tMPI_Return_req(struct req_list *rl, struct tmpi_req_ *req)
+void tMPI_Return_req(struct req_list *rl, struct tmpi_req_ *req)
{
req->next=rl->head;
req->prev=NULL;
-static void tMPI_Req_init(struct tmpi_req_ *rq, struct envelope *ev)
+void tMPI_Req_init(struct tmpi_req_ *rq, struct envelope *ev)
{
rq->ev=ev;
rq->finished=FALSE;
-static void tMPI_Set_req(struct envelope *ev, struct tmpi_req_ *req)
+void tMPI_Set_req(struct envelope *ev, struct tmpi_req_ *req)
{
req->source = ev->src;
req->comm = ev->comm;
}
}
-static void tMPI_Set_status(struct tmpi_req_ *req, tMPI_Status *st)
+void tMPI_Set_status(struct tmpi_req_ *req, tMPI_Status *st)
{
if (st)
{
}
-static tmpi_bool tMPI_Envelope_matches(const struct envelope *sev,
- const struct envelope *rev)
+tmpi_bool tMPI_Envelope_matches(const struct envelope *sev,
+ const struct envelope *rev)
{
#ifdef TMPI_DEBUG
printf("%5d: tMPI_Envelope_matches (%d->%d)==(%d->%d), tag=(%d==%d), \n datatype=(%ld==%ld), comm=(%ld,%ld),\n finished=(%d==%d)\n",
-static struct envelope*
-tMPI_Send_env_list_search_old(struct send_envelope_list *evl,
- struct envelope *rev)
+struct envelope* tMPI_Send_env_list_search_old(struct send_envelope_list *evl,
+ struct envelope *rev)
{
struct envelope *sev;
}
-static struct envelope*
-tMPI_Recv_env_list_search_new(struct recv_envelope_list *evl,
- struct envelope *sev)
+struct envelope* tMPI_Recv_env_list_search_new(struct recv_envelope_list *evl,
+ struct envelope *sev)
{
struct envelope *rev;
#ifdef USE_SEND_RECV_COPY_BUFFER
-static void tMPI_Send_copy_buffer(struct envelope *sev, struct tmpi_req_ *req)
+void tMPI_Send_copy_buffer(struct envelope *sev, struct tmpi_req_ *req)
{
/* Fill copy buffer, after having anounced its possible use */
#endif
-static struct envelope* tMPI_Prep_send_envelope(struct send_envelope_list *evl,
- tMPI_Comm comm, struct tmpi_thread *src,
- struct tmpi_thread *dest, void *buf, int count,
- tMPI_Datatype datatype, int tag, tmpi_bool nonblock)
+struct envelope* tMPI_Prep_send_envelope(struct send_envelope_list *evl,
+ tMPI_Comm comm,
+ struct tmpi_thread *src,
+ struct tmpi_thread *dest,
+ void *buf, int count,
+ tMPI_Datatype datatype,
+ int tag, tmpi_bool nonblock)
{
/* get an envelope from the send-envelope stack */
struct envelope *ev=tMPI_Send_env_list_fetch_new( evl );
return ev;
}
-static struct envelope* tMPI_Prep_recv_envelope(struct tmpi_thread *cur,
- tMPI_Comm comm, struct tmpi_thread *src,
- struct tmpi_thread *dest, void *buf, int count,
- tMPI_Datatype datatype, int tag, tmpi_bool nonblock)
+struct envelope* tMPI_Prep_recv_envelope(struct tmpi_thread *cur,
+ tMPI_Comm comm,
+ struct tmpi_thread *src,
+ struct tmpi_thread *dest,
+ void *buf, int count,
+ tMPI_Datatype datatype, int tag,
+ tmpi_bool nonblock)
{
/* get an envelope from the stack */
struct envelope *ev=tMPI_Free_env_list_fetch_recv( &(cur->envelopes) );
-static struct envelope* tMPI_Post_match_recv(struct tmpi_thread *cur,
- tMPI_Comm comm,
- struct tmpi_thread *src,
- void *recv_buf, int recv_count,
- tMPI_Datatype datatype,
- int tag, tmpi_bool nonblock)
+struct envelope* tMPI_Post_match_recv(struct tmpi_thread *cur,
+ tMPI_Comm comm,
+ struct tmpi_thread *src,
+ void *recv_buf, int recv_count,
+ tMPI_Datatype datatype,
+ int tag, tmpi_bool nonblock)
{
struct tmpi_thread *dest=cur;
struct envelope *rev;
-static struct envelope *tMPI_Post_send(struct tmpi_thread *cur,
- tMPI_Comm comm,
- struct tmpi_thread *dest,
- void *send_buf, int send_count,
- tMPI_Datatype datatype, int tag,
- tmpi_bool nonblock)
+struct envelope *tMPI_Post_send(struct tmpi_thread *cur,
+ tMPI_Comm comm,
+ struct tmpi_thread *dest,
+ void *send_buf, int send_count,
+ tMPI_Datatype datatype, int tag,
+ tmpi_bool nonblock)
{
struct tmpi_thread *src=cur;
struct envelope *sev;
-static void tMPI_Wait_process_incoming(struct tmpi_thread *cur)
+void tMPI_Wait_process_incoming(struct tmpi_thread *cur)
{
int i;
int check_id;
tMPI_Event_process( &(cur->p2p_event), n_handled);
}
-static tmpi_bool tMPI_Test_single(struct tmpi_thread *cur, struct tmpi_req_ *rq)
+tmpi_bool tMPI_Test_single(struct tmpi_thread *cur, struct tmpi_req_ *rq)
{
struct envelope *ev=rq->ev;
return rq->finished;
}
-static void tMPI_Wait_single(struct tmpi_thread *cur, struct tmpi_req_ *rq)
+void tMPI_Wait_single(struct tmpi_thread *cur, struct tmpi_req_ *rq)
{
do
{
} while(TRUE);
}
-static tmpi_bool tMPI_Test_multi(struct tmpi_thread *cur, struct tmpi_req_ *rqs,
+tmpi_bool tMPI_Test_multi(struct tmpi_thread *cur, struct tmpi_req_ *rqs,
tmpi_bool *any_done)
{
tmpi_bool all_done=TRUE;
files.
*/
-/* this file is included from p2p.c; it's not really a header file,
- but this defines a lot of functions that probably need to be inlined.*/
+#ifdef HAVE_TMPI_CONFIG_H
+#include "tmpi_config.h"
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+
+
+#include "impl.h"
+#include "p2p.h"
/* point-to-point communication exported functions */
files.
*/
-/* this file is #included from p2p.c;it's not really a header file,
- but this defines a lot of functions that probably need to be inlined.*/
+#ifdef HAVE_TMPI_CONFIG_H
+#include "tmpi_config.h"
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+
+#include "impl.h"
+#include "p2p.h"
int tMPI_Wait(tMPI_Request *request, tMPI_Status *status)
files.
*/
-/* this file is #included from collective.c; it's not really a header file,
- but this defines a lot of functions that probably need to be inlined.*/
+#ifdef HAVE_TMPI_CONFIG_H
+#include "tmpi_config.h"
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+
+#include "impl.h"
+#include "collective.h"
+
/* run a single binary reduce operation on src_a and src_b, producing dest.
files.
*/
-/* this file is #included from collective.c; it's not really a header file,
- but this defines a lot of functions that probably need to be inlined.*/
+#ifdef HAVE_TMPI_CONFIG_H
+#include "tmpi_config.h"
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+
+#include "impl.h"
+#include "collective.h"
+
int tMPI_Scatter(void* sendbuf, int sendcount, tMPI_Datatype sendtype,