Permalink
Browse files

init commit

  • Loading branch information...
Kai-Chun Ning
Kai-Chun Ning committed Jan 30, 2018
1 parent 7758c03 commit 0a9d4ce0c98d583df336b174a85c169e2a4c107a
@@ -0,0 +1,192 @@
cmake_minimum_required(VERSION 3.8 FATAL_ERROR) # CUDA support

project(mqsolver LANGUAGES C CUDA)

# set a default build type if none was specified
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message("Setting build type to 'Release' as none was specified.")
set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build." FORCE)
endif()

# ========================================================================== #
# language standard requirements
# ========================================================================== #

if(NOT DEFINED CMAKE_C_STANDARD)
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED true)
endif()

if(NOT DEFINED CMAKE_CUDA_STANDARD)
set(CMAKE_CUDA_STANDARD 11)
set(CMAKE_CUDA_STANDARD_REQUIRED true)
endif()

# ========================================================================== #
# compilation flags
# ========================================================================== #

include(CheckCCompilerFlag)

check_c_compiler_flag("-Wall" COMPILER_C_ALL_WARN)
if(COMPILER_C_ALL_WARN)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall"
CACHE STRING "Show all warning messages" FORCE
)
endif()

check_c_compiler_flag("-Wextra" COMPILER_C_EXTRA_WARN)
if(COMPILER_C_EXTRA_WARN)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wextra"
CACHE STRING "Show extra warning messages" FORCE
)
endif()

check_c_compiler_flag("-pipe" COMPILER_C_PIPE)
if(COMPILER_C_PIPE)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pipe"
CACHE STRING "Speed up compilation by piping" FORCE
)
endif()

set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -Xcompiler='${CMAKE_C_FLAGS}'"
CACHE STEING "Pass the same C flags to back-end compiler of nvcc" FORCE
)

check_c_compiler_flag("-mavx" COMPILER_C_AVX)
if(COMPILER_C_AVX)
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -mavx"
CACHE STRING "Optimize with AVX instructions" FORCE
)
endif()

check_c_compiler_flag("-mavx2" COMPILER_C_AVX2)
if(COMPILER_C_AVX2)
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -mavx2"
CACHE STRING "Optimize with AVX2 instructions" FORCE
)
endif()

check_c_compiler_flag("-march=native" COMPILER_C_ARCH)
if(COMPILER_C_ARCH)
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -march=native"
CACHE STRING "Optimize based on the architecture" FORCE
)
endif()

check_c_compiler_flag("-mtune=native" COMPILER_C_TUNE)
if(COMPILER_C_TUNE)
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -mtune=native"
CACHE STRING "Fine-tune the program based on the CPU" FORCE
)
endif()

check_c_compiler_flag("-fomit-frame-pointer" COMPILER_C_NO_FP)
if(COMPILER_C_NO_FP)
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -fomit-frame-pointer"
CACHE STRING "Omit frame pointers" FORCE
)
endif()

check_c_compiler_flag("-ffast-math" COMPILER_C_FAST_MATH)
if(COMPILER_C_FAST_MATH)
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -ffast-math"
CACHE STRING "Trade floating point precision for speed" FORCE
)
endif()

set(CMAKE_CUDA_FLAGS_RELEASE
"${CMAKE_CUDA_FLAGS_RELEASE} -Xcompiler='${CMAKE_C_FLAGS_RELEASE}'"
CACHE STEING "Pass the same C release flags to back-end compiler of nvcc"
FORCE
)

# with an nvcc that supports CUDA standard 11, this option should be supported
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -Xptxas '-dlcm=ca'"
CACHE STRING "Enable L1 cache on GPU" FORCE
)

# ========================================================================== #
# dynamically generate C code
# ========================================================================== #

set(GEN_SRCS
gc_decl_lsys.def
gc_copy_lsys.def
gc_check_lsys.def
gc_solve_lsys.def
gc_extract_sol.def
gc_dep_lsys.def
gc_gauss.def
)

if(NOT DEFINED KEEP_VAR_NUM)
message(FATAL_ERROR "The number of variables to keep is not defined")
endif()

add_custom_command(OUTPUT ${GEN_SRCS}
COMMAND python3 ${PROJECT_SOURCE_DIR}/bin/meta.py ${KEEP_VAR_NUM}
DEPENDS ${PROJECT_SOURCE_DIR}/bin/meta.py
COMMENT "Generate C source code based on the choice of k"
)

add_custom_target(gen_code DEPENDS ${GEN_SRCS}
COMMENT "Check if re-generation is required"
)

# ========================================================================== #
# source code
# ========================================================================== #

set(C_SRCS
src/mqsolver/util.c
src/mqsolver/options.c
src/mqsolver/algor.c
src/mqsolver/mq_math.c
src/mqsolver/debug.c
src/mqsolver/mqfix.c
src/mqsolver/drow.c
src/mqsolver/macaulay.c
src/threadpool/threadpool.c
)

set(CUDA_SRCS
src/mqsolver/cuda_util.cu
src/mqsolver/mqsolver.cu
src/mqsolver/graycode.cu
src/mqsolver/fix.cu
src/mqsolver/rmac.cu
)

# ========================================================================== #
# main program
# ========================================================================== #

add_executable(${PROJECT_NAME}
${C_SRCS}
${CUDA_SRCS}
src/main.c
)

target_include_directories(${PROJECT_NAME}
PRIVATE ${PROJECT_SOURCE_DIR}/include/mqsolver
PRIVATE ${PROJECT_SOURCE_DIR}/include/threadpool
PRIVATE ${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES}
PRIVATE ${PROJECT_BINARY_DIR} # include generated C code
)

target_link_libraries(${PROJECT_NAME}
PRIVATE m
PRIVATE pthread
)

set_target_properties(${PROJECT_NAME} PROPERTIES
LINKER_LANGUAGE C
CUDA_SEPARABLE_COMPILATION ON
)

target_compile_definitions(${PROJECT_NAME} PRIVATE
KNUM=${KEEP_VAR_NUM}
)

add_dependencies(${PROJECT_NAME} gen_code)
21 LICENSE
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2018 Kai-Chun Ning <kaichun.ning@gmail.com>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

This file was deleted.

Oops, something went wrong.
@@ -0,0 +1,27 @@
NAME
mqsolver

DESCRIPTION
C implementation of the Parallel Crossbred algorithm for solving
Fukuoka MQ challenges on GPUs.

DEPENDENCIES
cmake, make, python3, gcc, CUDA

OPTIONAL DEPENDENCIES
ssh (for cluster mode)

RUN
see the help message of solve.py

EXAMPLE
./solve.py -d 3 -k 16 -t 20 -v -o 46-92-3-16.log challenge-46-92.txt

BUILD
Instead of using the Python wrapper, you can manually build and launch
mqsolver as follows:

$ mkdir build && cd build
$ cmake -DKEEP_VAR_NUM=16 .. && make

Now, an executable named 'mqsolver' should be available in the build folder
@@ -0,0 +1,17 @@
#!/usr/bin/env python3
# usage: generate preprocess (external hybridation) configuration file
import sys

help_msg = """usage: ./%s <filename> <var num> <starting value> <range>
\texample: ./gen_efix.py extfix.txt 4 5 4""" % (sys.argv[0])

if len(sys.argv) < 5:
sys.exit(help_msg)

fname = sys.argv[1]
var_num = int(sys.argv[2])
start = int(sys.argv[3])
rge = int(sys.argv[4])

with open(fname, 'w') as fp:
fp.write('%d %d %d\n' % (var_num, rge, start))
@@ -0,0 +1,48 @@
#!/usr/bin/env python3

import argparse, sys
from random import randint

parser = argparse.ArgumentParser(description='Generate (solvable) multivariate system over GF(2).',
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('-n', dest='n', type=int, required=True,
help='number of variables')
parser.add_argument('-m', dest='m', type=int, required=True,
help='number of equations')
args = parser.parse_args()

n = args.n
m = args.m

print("""Galois Field : GF(2)
Number of variables (n) : {var_num}
Number of polynomials (m) : {eq_num}
Seed : 0
Order : graded reverse lex order
*********************""".format(var_num=n, eq_num=m))

sol = [randint(0,1) for i in range(n)]

sys.stderr.write(str(sol) + "\n")

for i in range(m):
res = 0

for j in range(n):
for k in range(j+1):
r = randint(0,1)
print(r, end=' ')

if r == 1:
res ^= sol[j] & sol[k]

for j in range(n):
r = randint(0,1)
print(r, end=' ')

if r == 1:
res ^= sol[j]

print(str(res) + ";")

@@ -0,0 +1,54 @@
#!/usr/bin/env ruby
# usage: find the max number of variables one can keep
# arguments:
# 1) var_num: number of variables
# 2) eq_num: number of eqs
# 3) deg: degree of Macaulay

abort 'invalid arguments' unless ARGV.size >= 3
var_num, eq_num, deg, _ = ARGV.map(&:to_i)

def binom2(n)
n * (n-1) / 2
end

def binom3(n)
n * (n-1) * (n-2) / 6
end

def binom4(n)
n * (n-1) * (n-2) * (n-3) / 24
end

def nlnum(n, deg, k)
c = binom2(k) + binom3(k) + binom2(k) * (n-k)

if 4 == deg
c += binom4(k) + binom3(k) * (n-k) + binom2(k) * binom2(n-k)
end

c
end

mac_eq_num = ( (var_num + 1) + ((deg == 4) ? binom2(var_num) : 0) ) * eq_num
mac_term_num = 1 + var_num + binom2(var_num) + binom3(var_num)
mac_term_num += binom4(var_num) if deg == 4
mac_memsize = mac_eq_num.to_f * mac_term_num / 8 / (2 ** 30)

mac_indep_eq_num = mac_eq_num - ((3 == deg) ? 0 : eq_num * (eq_num+1) / 2)

# compute max k
max_k, nl_term_num = var_num.downto(0) do |k|
ntnum = nlnum(var_num, deg, k)
break k, ntnum if mac_indep_eq_num - ntnum >= k
end

puts <<-EOF
number of variables: #{var_num}
number of equations: #{eq_num}
degree of Macaulay matrix: #{deg}
number of rows in Macaulay matrix: #{mac_eq_num}
number of cols in Macaulay matrix: #{mac_term_num}
number of terms to eliminate: #{nl_term_num}
max number of variables one can keep: #{max_k}
EOF
Oops, something went wrong.

0 comments on commit 0a9d4ce

Please sign in to comment.