diff --git a/cmake/cudnn.cmake b/cmake/cudnn.cmake index e2ff923a22923243e50233b1bad28edb672ab11e..e5b59be19369d3ba3e852624426b95ae365e7357 100644 --- a/cmake/cudnn.cmake +++ b/cmake/cudnn.cmake @@ -15,7 +15,7 @@ list(APPEND CUDNN_CHECK_LIBRARY_DIRS $ENV{CUDNN_ROOT}/lib64 $ENV{CUDNN_ROOT}/lib /usr/lib) -find_library(CUDNN_LIBRARY NAMES libcudnn.so # libcudnn_static.a +find_library(CUDNN_LIBRARY NAMES libcudnn.so libcudnn.dylib # libcudnn_static.a PATHS ${CUDNN_CHECK_LIBRARY_DIRS} ${CUDNN_INCLUDE_DIR} ${__libpath_hist} NO_DEFAULT_PATH DOC "Path to cuDNN library.") diff --git a/cmake/flags.cmake b/cmake/flags.cmake index 4b99e7f7fb6af3ca85d6dc642a4aea07e64c7049..c95d4063105e74df7acd491558f399dff6a8e0a8 100644 --- a/cmake/flags.cmake +++ b/cmake/flags.cmake @@ -58,8 +58,8 @@ set(COMMON_FLAGS -fPIC -fno-omit-frame-pointer -Wall - -Wextra - -Werror +# -Wextra +# -Werror -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wno-unused-parameter diff --git a/cmake/util.cmake b/cmake/util.cmake index e0e372fed0b0496106ee82d5c6e4938f7a0f3343..bad44c7e9dda643386bf9ab441e72780c2814626 100644 --- a/cmake/util.cmake +++ b/cmake/util.cmake @@ -1,4 +1,21 @@ # Some common routine for paddle compile. +if(APPLE) + # ------------------------------------------------------- + # OSX + # ------------------------------------------------------- + set(GROUP_START "-Wl,-force_load") + set(GROUP_END "") + + set(ARCHIVE_START "-Wl,-force_load") + set(ARCHIVE_END "") +else() + set(GROUP_START "-Wl,--start-group") + set(GROUP_END "-Wl,--end-group") + + set(ARCHIVE_START "-Wl,--whole-archive") + set(ARCHIVE_END "-Wl,--no-whole-archive") +endif() + # target_circle_link_libraries @@ -7,10 +24,18 @@ # First Argument: target name want to be linked with libraries # Rest Arguments: libraries which link together. function(target_circle_link_libraries TARGET_NAME) - target_link_libraries(${TARGET_NAME} - -Wl,--start-group - ${ARGN} - -Wl,--end-group) + if(APPLE) + foreach(f ${ARGN}) + list(APPEND OSX_LIBRARIES "-Wl,-force_load" "${f}") + endforeach(f) + target_link_libraries(${TARGET_NAME} + ${OSX_LIBRARIES}) + else() + target_link_libraries(${TARGET_NAME} + ${GROUP_START} + ${ARGN} + ${GROUP_END}) + endif() endfunction() # compile_cu_as_cpp @@ -41,20 +66,18 @@ function(link_paddle_exe TARGET_NAME) if(PADDLE_WITH_INTERNAL) set(INTERAL_LIBS paddle_internal_gserver paddle_internal_parameter) target_circle_link_libraries(${TARGET_NAME} - -Wl,--whole-archive paddle_internal_gserver paddle_internal_owlqn - -Wl,--no-whole-archive paddle_internal_parameter) else() set(INTERAL_LIBS "") endif() target_circle_link_libraries(${TARGET_NAME} - -Wl,--whole-archive +# ${ARCHIVE_START} paddle_gserver ${METRIC_LIBS} - -Wl,--no-whole-archive +# ${ARCHIVE_END} paddle_pserver paddle_trainer_lib paddle_network @@ -69,7 +92,7 @@ function(link_paddle_exe TARGET_NAME) ${CBLAS_LIBS} ${CMAKE_DL_LIBS} ${INTERAL_LIBS} - -lz) + ) if(WITH_PYTHON) target_link_libraries(${TARGET_NAME} diff --git a/paddle/api/Util.cpp b/paddle/api/Util.cpp index 4e655c324a1ede19dacab9237d62fcfcaf70d64d..8a6741078f2f19d8c3cb081f129447d6fc5801c9 100644 --- a/paddle/api/Util.cpp +++ b/paddle/api/Util.cpp @@ -17,6 +17,7 @@ limitations under the License. */ #include "paddle/utils/Util.h" #include "paddle/utils/PythonUtil.h" #include "paddle/utils/Flags.h" +#include "paddle/utils/Excepts.h" #include "paddle/parameter/Parameter.h" #include diff --git a/paddle/gserver/dataproviders/PyDataProvider.cpp b/paddle/gserver/dataproviders/PyDataProvider.cpp index aeefd16063df82ce3e190bdaacdb2b788f5f9b8e..cc3e09a3c2ecb4cd172bb3abf6e09aff5ebcc784 100644 --- a/paddle/gserver/dataproviders/PyDataProvider.cpp +++ b/paddle/gserver/dataproviders/PyDataProvider.cpp @@ -17,6 +17,8 @@ limitations under the License. */ #include "paddle/utils/PythonUtil.h" #include #include "paddle/utils/Util.h" +#include "paddle/utils/Excepts.h" + namespace paddle { diff --git a/paddle/gserver/gradientmachines/NeuralNetwork.cpp b/paddle/gserver/gradientmachines/NeuralNetwork.cpp index fca52828957a2da42238c9f945f5126beea95008..f9da812027dc3a5af026f44a608a14a5b1de2618 100644 --- a/paddle/gserver/gradientmachines/NeuralNetwork.cpp +++ b/paddle/gserver/gradientmachines/NeuralNetwork.cpp @@ -384,17 +384,17 @@ void NeuralNetwork::setOutputGrad(const std::vector& args) { } } -extern NeuralNetwork* newCustomNeuralNetwork( - const std::string& name, NeuralNetwork* network) __attribute__((weak)); +// extern NeuralNetwork* newCustomNeuralNetwork( +// const std::string& name, NeuralNetwork* network) __attribute__((weak)); NeuralNetwork* NeuralNetwork::newNeuralNetwork( const std::string& name, NeuralNetwork* rootNetwork) { - if (newCustomNeuralNetwork) { - return newCustomNeuralNetwork(name, rootNetwork); - } else { +// if (newCustomNeuralNetwork) { +// return newCustomNeuralNetwork(name, rootNetwork); +// } else { return new NeuralNetwork(name, rootNetwork); - } +// } } } // namespace paddle diff --git a/paddle/math/Allocator.h b/paddle/math/Allocator.h index 36166236e9effdb8171f56289bba7ca99515d1cd..7d277b1c10d2b498d9b3d7f78a93f079d75044e4 100644 --- a/paddle/math/Allocator.h +++ b/paddle/math/Allocator.h @@ -16,7 +16,7 @@ limitations under the License. */ #pragma once #include -#include +#include #include "hl_gpu.h" #include "paddle/utils/Logging.h" @@ -48,9 +48,14 @@ public: * @return Pointer to the allocated memory */ virtual void* alloc(size_t size) { - void* ptr = memalign(32ul, size); - CHECK(ptr) << "Fail to allocate CPU memory: size=" << size; - return ptr; + #if defined(__APPLE__) || defined(__OSX__) + return malloc(size); + #else + void* ptr; + posix_memalign(&ptr, 32ul, size); + CHECK(ptr) << "Fail to allocate CPU memory: size=" << size; + return ptr; + #endif } /** diff --git a/paddle/math/MathFunctions.h b/paddle/math/MathFunctions.h index fe486c741d6f5dd79962c40af2396c00568c551f..43075977dc9cef1573cf6dd75d9ef577b07d337e 100644 --- a/paddle/math/MathFunctions.h +++ b/paddle/math/MathFunctions.h @@ -23,6 +23,8 @@ extern "C" { } #endif +#include + namespace paddle { template diff --git a/paddle/math/Storage.cpp b/paddle/math/Storage.cpp index 9a879a964ec6d04ad1c6cbf1a009b6414a8e23fd..2bd3db2341638b1f463f22c5a85a1632e0b9ac09 100644 --- a/paddle/math/Storage.cpp +++ b/paddle/math/Storage.cpp @@ -25,8 +25,8 @@ namespace paddle { // Initialization StorageEngine singleton. // Other modules may rely on storage management, // so StorageEngine need to be initialized before other modules. -static InitFunction __init_storage_engine( - StorageEngine::singleton, std::numeric_limits::max()); +// static InitFunction __init_storage_engine( +// StorageEngine::singleton, std::numeric_limits::max()); StorageEngine::StorageEngine() : cpuAllocator_(nullptr) { } diff --git a/paddle/pserver/LightNetwork.cpp b/paddle/pserver/LightNetwork.cpp index fb427832fad646b4181cbaa98a29d5ae22970556..c42d2dbe4bbf56600640c1aa0817c463ece3ccda 100644 --- a/paddle/pserver/LightNetwork.cpp +++ b/paddle/pserver/LightNetwork.cpp @@ -24,7 +24,12 @@ limitations under the License. */ #include #include #include + +#if defined(__OSX__) || defined(__APPLE__) +#include +#else #include +#endif #include "LightNetwork.h" #include "paddle/utils/Util.h" @@ -92,10 +97,12 @@ void setOption(int sockfd) { CHECK_GE( setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &optval, sizeof(optval)), 0); +#ifdef TCP_QUICKACK optval = 1; CHECK_GE( setsockopt(sockfd, IPPROTO_TCP, TCP_QUICKACK, &optval, sizeof(optval)), 0); +#endif } int reuse = 1; CHECK_GE(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)), @@ -340,17 +347,27 @@ void SocketWorker::run() { */ void SocketClient::TcpClient(const std::string &serverAddr, int serverPort) { struct sockaddr_in serv_addr; - struct hostent hostinfo, *server; - char buf[1024]; // temp for gethostbyname_r + struct hostent *server; + int errRet; // temp for gethostbyname_r /// Create a socket point int sockfd = socket(AF_INET, SOCK_STREAM, 0); PCHECK(sockfd >= 0) << "ERROR opening socket"; - CHECK_EQ(0, gethostbyname_r(serverAddr.c_str(), &hostinfo, buf, sizeof(buf), - &server, &errRet)) - << "ERROR, no such host: " << serverAddr << " ret = " << errRet; - CHECK(server) << "gethostbyname_r err"; + +#if defined(__OSX__) || defined(__APPLE__) + server = getipnodebyname(serverAddr.c_str(), AF_INET, AI_DEFAULT, &errRet); + CHECK_NE(HOST_NOT_FOUND, errRet) + << "ERROR, no such host: " << serverAddr << " ret = " << errRet; + CHECK(server) << "getipnodebyname error!"; +#else + struct hostent hostinfo; + char buf[1024]; // temp for gethostbyname_r + CHECK_EQ(0, gethostbyname_r(serverAddr.c_str(), &hostinfo, buf, sizeof(buf), + &server, &errRet)) + << "ERROR, no such host: " << serverAddr << " ret = " << errRet; + CHECK(server) << "gethostbyname_r error!"; +#endif bzero((char *)&serv_addr, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; diff --git a/paddle/pserver/SocketChannel.cpp b/paddle/pserver/SocketChannel.cpp index 698473060a4c1660b93c10b40053e074d2ac81e9..b9d542a296ddddcd5e00d345b71fa976f0d72388 100644 --- a/paddle/pserver/SocketChannel.cpp +++ b/paddle/pserver/SocketChannel.cpp @@ -27,6 +27,15 @@ limitations under the License. */ namespace paddle { +/** + * UIO_MAXIOV is documented in writev(2), but only + * declares it on osx/ios if defined(KERNEL) + */ +#ifndef UIO_MAXIOV +#define UIO_MAXIOV 512 +#endif + + SocketChannel::~SocketChannel() { if (tcpRdma_ == F_TCP) close(tcpSocket_); @@ -148,8 +157,7 @@ void SocketChannel::writeMessage(const std::vector& userIovs) { std::vector iovs; iovs.reserve(userIovs.size() + 2); iovs.push_back({&header, sizeof(header)}); - iovs.push_back({&iovLengths[0], - sizeof(iovLengths[0]) * (size_t) header.numIovs}); + iovs.push_back({&iovLengths[0], sizeof(iovLengths[0]) * header.numIovs}); iovs.insert(iovs.end(), userIovs.begin(), userIovs.end()); header.totalLength = 0; diff --git a/paddle/trainer/Trainer.cpp b/paddle/trainer/Trainer.cpp index 2890f5b5d7ad93026113346722b4e07504e50482..84d2ee1e73a54ab96b2dd5d9885df366656b915d 100644 --- a/paddle/trainer/Trainer.cpp +++ b/paddle/trainer/Trainer.cpp @@ -28,6 +28,7 @@ limitations under the License. */ #include "paddle/utils/PythonUtil.h" #include "paddle/utils/Stat.h" #include "paddle/utils/Util.h" +#include "paddle/utils/Excepts.h" #include "paddle/utils/GlobalConstants.h" #include "paddle/gserver/gradientmachines/NeuralNetwork.h" diff --git a/paddle/trainer/TrainerMain.cpp b/paddle/trainer/TrainerMain.cpp index dd30b2c8a5b4539466378173cbe5e3e089adc18d..94266639f94ade6b490eb26243dd964ddedf40b9 100644 --- a/paddle/trainer/TrainerMain.cpp +++ b/paddle/trainer/TrainerMain.cpp @@ -16,6 +16,7 @@ limitations under the License. */ #include #include "paddle/utils/PythonUtil.h" #include "paddle/utils/StringUtil.h" +#include "paddle/utils/Excepts.h" #include "paddle/pserver/ParameterServer2.h" #include "ParamUtil.h" diff --git a/paddle/utils/Excepts.cpp b/paddle/utils/Excepts.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9123508fc78d002a9fc5fd0e7e9da8ddec975d6f --- /dev/null +++ b/paddle/utils/Excepts.cpp @@ -0,0 +1,54 @@ +/* Copyright (c) 2016 Baidu, Inc. All Rights Reserve. + +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. */ + +#include "Excepts.h" + +#if defined(__APPLE__) || defined(__OSX__) + +#include + +int fegetexcept(void) { + static fenv_t fenv; + return fegetenv(&fenv) ? -1 : (fenv.__control & FE_ALL_EXCEPT); +} + +int feenableexcept(unsigned int excepts) { + static fenv_t fenv; + unsigned int new_excepts = excepts & FE_ALL_EXCEPT, old_excepts; + + if ( fegetenv (&fenv) ) return -1; + old_excepts = fenv.__control & FE_ALL_EXCEPT; + + // unmask + fenv.__control &= ~new_excepts; + fenv.__mxcsr &= ~(new_excepts << 7); + + return ( fesetenv (&fenv) ? -1 : old_excepts ); +} + +int fedisableexcept(unsigned int excepts) { + static fenv_t fenv; + unsigned int new_excepts = excepts & FE_ALL_EXCEPT, old_excepts; + + if ( fegetenv (&fenv) ) return -1; + old_excepts = fenv.__control & FE_ALL_EXCEPT; + + // mask + fenv.__control |= new_excepts; + fenv.__mxcsr |= new_excepts << 7; + + return ( fesetenv (&fenv) ? -1 : old_excepts ); +} + +#endif diff --git a/paddle/utils/Excepts.h b/paddle/utils/Excepts.h new file mode 100644 index 0000000000000000000000000000000000000000..a84a2d33a6a3d0664218151befd6b2af44f72a97 --- /dev/null +++ b/paddle/utils/Excepts.h @@ -0,0 +1,26 @@ +/* Copyright (c) 2016 Baidu, Inc. All Rights Reserve. + +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. */ + +#ifndef EXCEPTS_H_ +#define EXCEPTS_H_ + +#if defined(__APPLE__) || defined(__OSX__) + +int fegetexcept(void); +int feenableexcept(unsigned int excepts); +int fedisableexcept(unsigned int excepts); + +#endif + +#endif // EXCEPTS_H_ diff --git a/paddle/utils/Locks.cpp b/paddle/utils/Locks.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c2f58cf5764ef9d36a40f8fffa11075ed5ced75b --- /dev/null +++ b/paddle/utils/Locks.cpp @@ -0,0 +1,106 @@ +/* Copyright (c) 2016 Baidu, Inc. All Rights Reserve. + +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. */ + +#ifdef __APPLE__ +#include +#endif + +#ifdef __APPLE__ +#ifndef PTHREAD_BARRIER_H_ +#define PTHREAD_BARRIER_H_ + +#include +#include + +typedef int pthread_barrierattr_t; +typedef struct { + pthread_mutex_t mutex; + pthread_cond_t cond; + int count; + int tripCount; +} pthread_barrier_t; + +int pthread_barrier_init(pthread_barrier_t *barrier, + const pthread_barrierattr_t *attr, unsigned int count) { + if (count == 0) { + errno = EINVAL; + return -1; + } + if (pthread_mutex_init(&barrier->mutex, 0) < 0) { + return -1; + } + if (pthread_cond_init(&barrier->cond, 0) < 0) { + pthread_mutex_destroy(&barrier->mutex); + return -1; + } + barrier->tripCount = count; + barrier->count = 0; + + return 0; +} + +int pthread_barrier_destroy(pthread_barrier_t *barrier) { + pthread_cond_destroy(&barrier->cond); + pthread_mutex_destroy(&barrier->mutex); + return 0; +} + +int pthread_barrier_wait(pthread_barrier_t *barrier) { + pthread_mutex_lock(&barrier->mutex); + ++(barrier->count); + if (barrier->count >= barrier->tripCount) { + barrier->count = 0; + pthread_cond_broadcast(&barrier->cond); + pthread_mutex_unlock(&barrier->mutex); + return 1; + } else { + pthread_cond_wait(&barrier->cond, &(barrier->mutex)); + pthread_mutex_unlock(&barrier->mutex); + return 0; + } +} + +#endif // PTHREAD_BARRIER_H_ + +typedef int pthread_spinlock_t; + +int pthread_spin_init(pthread_spinlock_t *lock, int pshared) { + __asm__ __volatile__("" ::: "memory"); + *lock = 0; + return 0; +} + +int pthread_spin_destroy(pthread_spinlock_t *lock) { + return 0; +} + +int pthread_spin_lock(pthread_spinlock_t *lock) { + while (1) { + int i; + for (i=0; i < 10000; i++) { + if (__sync_bool_compare_and_swap(lock, 0, 1)) { + return 0; + } + } + sched_yield(); + } +} + +int pthread_spin_unlock(pthread_spinlock_t *lock) { + __asm__ __volatile__("" ::: "memory"); + *lock = 0; + return 0; +} + +#endif // __APPLE__ diff --git a/paddle/utils/Locks.h b/paddle/utils/Locks.h index 085aca508dbbec4b290b99722d8b907528006b78..e7b0b77081f3695e4dad33068c2e3fdf65f631eb 100644 --- a/paddle/utils/Locks.h +++ b/paddle/utils/Locks.h @@ -23,6 +23,50 @@ limitations under the License. */ #include #include +#ifdef __APPLE__ +#include +#endif + +#ifdef __APPLE__ +#ifndef PTHREAD_BARRIER_H_ +#define PTHREAD_BARRIER_H_ + +#include +#include + +typedef int pthread_barrierattr_t; +typedef struct { + pthread_mutex_t mutex; + pthread_cond_t cond; + int count; + int tripCount; +} pthread_barrier_t; + + +extern int pthread_barrier_init(pthread_barrier_t *barrier, + const pthread_barrierattr_t *attr, + unsigned int count); + +extern int pthread_barrier_destroy(pthread_barrier_t *barrier); + +extern int pthread_barrier_wait(pthread_barrier_t *barrier); + +#endif // PTHREAD_BARRIER_H_ + +typedef int pthread_spinlock_t; + +extern int pthread_spin_init(pthread_spinlock_t *lock, int pshared); + +extern int pthread_spin_destroy(pthread_spinlock_t *lock); + +extern int pthread_spin_lock(pthread_spinlock_t *lock); + +extern int pthread_spin_unlock(pthread_spinlock_t *lock); + +#endif + + + namespace paddle { /** @@ -117,6 +161,29 @@ protected: /** * A simple wapper of semaphore which can only be shared in the same process. */ + +#ifdef __APPLE__ + +class Semaphore { +public: + explicit Semaphore(int initValue = 0) { + sem_ = dispatch_semaphore_create(initValue); + } + + ~Semaphore() { dispatch_release(sem_); } + bool timeWait(struct timespec* ts) { + dispatch_time_t m = dispatch_walltime(ts, 0); + return (0 == dispatch_semaphore_wait(sem_, m)); + } + void wait() { dispatch_semaphore_wait(sem_, DISPATCH_TIME_FOREVER); } + void post() { dispatch_semaphore_signal(sem_);} + +protected: + dispatch_semaphore_t sem_; +}; + +#else + class Semaphore { public: /** @@ -153,6 +220,8 @@ protected: sem_t sem_; }; +#endif + static_assert(sizeof(SpinLock) == 64, "Wrong padding"); /** diff --git a/paddle/utils/PythonUtil.h b/paddle/utils/PythonUtil.h index 4467fd784ec4ebe853ea60c24916286d85d24e55..397229d803df9d750a440498ad5a90b779597ee9 100644 --- a/paddle/utils/PythonUtil.h +++ b/paddle/utils/PythonUtil.h @@ -18,6 +18,12 @@ limitations under the License. */ #ifndef PADDLE_NO_PYTHON // must include the following two blocks, otherwise, // gcc compiler may produce warning +#ifdef __APPLE__ +#define _POSIX_SOURCE +#define _POSIX_C_SOURCE 200809L +#define _XOPEN_SOURCE 700 +#endif + #ifdef _POSIX_C_SOURCE #define __TEMP_POSIX_C_SOURCE _POSIX_C_SOURCE #undef _POSIX_C_SOURCE @@ -28,12 +34,14 @@ limitations under the License. */ #endif #include #include -#ifndef _POSIX_C_SOURCE -#warning "no _POSIX_C_SOURCE defined in Python.h" -#endif -#ifndef _XOPEN_SOURCE -#warning "no _XOPEN_SOURCE defined in Python.h" -#endif + +// #ifndef _POSIX_C_SOURCE +// #warning "no _POSIX_C_SOURCE defined in Python.h" +// #endif +// #ifndef _XOPEN_SOURCE +// #warning "no _XOPEN_SOURCE defined in Python.h" +// #endif + #endif #include "paddle/utils/Util.h"