Commit 0bd3e6df authored by Quentin HAMMERER's avatar Quentin HAMMERER
Browse files

Il faut faire un peu de bash pour rendre le script universel, et l'output en...

Il faut faire un peu de bash pour rendre le script universel, et l'output en parametre doit s'appeler 'mat'
parent d9fb902d
CC = gcc
CFLAGS = -std=c11 -g -Wall -Wextra -O3 -Wno-unused-parameter -Wno-maybe-uninitialized -Werror -march=native
# OpenMP
CFLAGS += -fopenmp
LDFLAGS += -fopenmp
LDLIBS += -lm
all: macaulay_gen
macaulay_gen: parser.o tools.o macaulay_gen.o
macaulay_gen: LDLIBS += `pkg-config --libs m4ri`
parser.o: parser.h
tools.o: tools.h
macaulay_gen.o: parser.h tools.h
macaulay_gen.o: CFLAGS += `pkg-config --cflags m4ri`
clean:
rm -rf *.o my_mat/ *log.bin
rm -f parser_demo moebius_demo parser_demo_alt monica monica_vector macaulay_gen lanczos
#!/bin/bash
echo "Start script"
rm -rf my_mat/ ker.bin
mkdir my_mat
mv mat.bin my_mat/
mv mat.cw.bin my_mat/
mv mat.rw.bin my_mat/
~/stage/cado-nfs-master/build/poste-almasty-02/linalg/bwc/./bwc.pl :complete balancing_options="reorder=columns" matrix=`pwd`/my_mat/mat.bin mn=64
cp my_mat/mat.bin-1x1/W ker.bin
echo "End script"
\ No newline at end of file
a, b, c
a
a*b
a*c
b
b*c
c
a*b + a*c + b*c + a + b + c + 1
\ No newline at end of file
File added
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
#define _POSIX_C_SOURCE 200809L
#include <stdbool.h>
#include <stdlib.h>
#include <err.h>
#include <string.h> // strcmp, strdup
#include <ctype.h> // isblank
#include "parser.h"
struct parser_state {
void * callback_ctx;
variables_callback_t vcallback;
monomial_callback_t mcallback;
polynomial_callback_t pcallback;
finalization_callback_t fcallback;
bool read_variables;
// buffer
FILE *istream;
char *buffer;
int capacity; // buffer capacity
int lo; // next available byte in buffer
int hi; // last available byte in buffer
int lineno;
int col;
bool eof;
char current; // current byte
// variables
struct var_list *vars_head, *vars_tail;
int nvars;
};
struct var_list {
char *name;
struct var_list *next;
};
static void advance(struct parser_state * s)
{
if (s->lo == s->hi) {
s->lo = 0;
s->hi = fread(s->buffer, 1, s->capacity, s->istream);
if (s->hi == 0) {
if (ferror(s->istream))
err(1, "error while reading input");
if (feof(s->istream)) {
s->eof = true;
return;
}
}
}
if (s->current == '\n') {
s->col = 0;
s->lineno += 1;
} else {
s->col += 1;
}
s->current = s->buffer[s->lo];
s->lo += 1;
if (isblank(s->current))
advance(s);
}
static int find_variable(struct parser_state *s, char *name)
{
int i = 0;
struct var_list * head = s->vars_head->next;
while (head != NULL) {
if (strcmp(name, head->name) == 0)
return i;
i += 1;
head = head->next;
}
return -1;
}
static bool read_variable(struct parser_state *s, char *buffer)
{
int i = 0;
while (true) {
char c = s->current;
if (s->eof || c == '+' || c == ',' || c == '*' || c == '\n')
break;
if (i == 128) {
buffer[128] = '\0';
errx(1, "variable name %s too long on line %d, column %d\n", buffer, s->lineno, s->col);
}
buffer[i] = c;
i++;
advance(s);
}
buffer[i] = '\0';
return (i != 0);
}
static void read_variables(struct parser_state *s)
{
char name[129];
int n = 0;
while (read_variable(s, name)) {
struct var_list *new = malloc(sizeof(*new));
if (find_variable(s, name) >= 0)
errx(1, "duplicate variable name %s\n", name);
new->name = strdup(name);
new->next = NULL;
s->vars_tail->next = new;
s->vars_tail = new;
n += 1;
if (s->current == ',')
advance(s);
}
if (s->current != '\n')
errx(1, "parse error line %d col %d: expected newline, got %c\n", s->lineno, s->col, s->current);
advance(s); // skip newline
char ** allvars = malloc(n * sizeof(*allvars));
// TODO : error checking
struct var_list * v = s->vars_head;
for (int i = 0; i < n; i++) {
v = v->next;
allvars[i] = v->name;
}
if (s->vcallback != NULL)
(*s->vcallback)(s->callback_ctx, n, (const char **) allvars);
free(allvars);
s->nvars = n;
s->read_variables = true;
}
static bool read_term(struct parser_state *s)
{
char buffer[129];
int variables[s->nvars];
int degree = 0;
bool something = false;
bool forget = false;
while (read_variable(s, buffer)) {
something = true;
if (s->current == '*')
advance(s);
if (strcmp(buffer, "1") == 0)
continue;
if (strcmp(buffer, "0") == 0) {
forget = true;
continue;
}
int x = find_variable(s, buffer);
if (x < 0)
errx(1, "unknown variable %s on line %d col %d\n", buffer, s->lineno, s->col);
variables[degree] = x;
degree += 1;
}
if (forget)
return true;
if (!something)
return false;
if (s->mcallback != NULL)
(*s->mcallback)(s->callback_ctx, s->lineno, s->col, degree, variables);
return true;
}
static void read_poly(struct parser_state *s)
{
while (read_term(s)) {
if (s->current == '+')
advance(s);
}
if (!s->eof && s->current != '\n')
errx(1, "parser error : unexpected stuff (%c) on line %d, col %d\n", s->current, s->lineno, s->col);
advance(s); // skip \n
if (s->pcallback != NULL)
(*s->pcallback)(s->callback_ctx, s->lineno);
}
static void parser_setup(struct parser_state *s)
{
s->capacity = 1000000;
s->buffer = malloc(s->capacity);
if (s->buffer == NULL)
err(1, "cannot allocate buffer");
s->lo = 0;
s->hi = 0;
s->lineno = -1;
s->col = 0;
s->eof = false;
s->current = '\n';
struct var_list * dummy = malloc(sizeof(*dummy));
dummy->name = NULL;
dummy->next = NULL;
s->vars_head = dummy;
s->vars_tail = dummy;
advance(s);
}
static void parser_finish(struct parser_state *s)
{
free(s->buffer);
if (s->fcallback != NULL)
(*s->fcallback)(s->callback_ctx);
struct var_list *head = s->vars_head;
while (head != NULL) {
struct var_list *next = head->next;
free(head->name);
free(head);
head = next;
}
}
void parser(FILE * istream, void * callback_ctx, variables_callback_t v,
monomial_callback_t m, polynomial_callback_t p, finalization_callback_t f)
{
struct parser_state s;
s.istream = istream;
s.callback_ctx = callback_ctx;
s.vcallback = v;
s.mcallback = m;
s.pcallback = p;
s.fcallback = f;
s.read_variables = false;
parser_setup(&s);
while (true) {
if (s.eof)
break;
if (s.current == '#') {
while (!s.eof && s.current != '\n')
advance(&s);
advance(&s); // skip the \n
} else if (!s.read_variables) {
read_variables(&s);
} else {
read_poly(&s);
}
}
parser_finish(&s);
}
\ No newline at end of file
#ifndef _PARSER_H_
#define _PARSER_H_
/*
* This code parses polynomial systems modulo 2 in the following format:
*
* + Lines begining by a # are ignored.
*
* + Spaces, tabs, etc. are ignored.
*
* + The first non-comment line contains the names of all variables, separated
* by commas. This implicitly numbers them. The first variable has number 0.
*
* + Each subsequent lines describe a polynomial.
*
* + A polynomial is a sum of monomials, separated by +
*
* + A monomial is either 0, 1, a single variable, or a product of several
* variables separated by *.
*
* (It follows that an empty line denote the zero polynomial)
*
* ---------------------------
*
* The parser interface relies on callbacks (this is inspired by the design of
* expat).
*
* + Once the variable names have been read, the "variables callback" is
* invoked, along with the number and names of the variables.
*
* + Once a monomial has been read, the "monomial callback" is invoked, along
* with an array describing the variables in the monomial (they are given by
* index).
*
* + Once a polynomial has been read, the "polynomial callback"is invoked.
*
* + Once parsing is finished, a "finalization callback" is invoked.
*
* + Each callback is given a pointer to an opaque object provided by the caller.
*
*/
#include <stdio.h>
typedef void (*variables_callback_t)(void * opaque, int n, const char ** var_names);
typedef void (*monomial_callback_t)(void * opaque, int line, int column, int degree,
const int * variables);
typedef void (*polynomial_callback_t)(void * opaque, int line);
typedef void (*finalization_callback_t)(void * opaque);
void parser(FILE * input, void * opaque, variables_callback_t v, monomial_callback_t m,
polynomial_callback_t p, finalization_callback_t f);
#endif
\ No newline at end of file
a, b, c
#
a*b + a*c + 1
b*c + a + c
a*b + b*c + a + b + 1
\ No newline at end of file
#include "tools.h"
//////////////////////////////////////////////////////
// Acquiring kernel ////////////////////
///////////////////////////
bool big_endian()
{
return (htonl(0x47) == 0x47);
}
void *load_file(const char *filename, u64 *size_)
{
/* obtain file size */
struct stat infos;
if (stat(filename, &infos))
err(1, "fstat failed on %s", filename);
u64 size = infos.st_size;
assert ((size % 8) == 0);
size /= 8;
/* allocate memory */
u64 *content = malloc(size * 8);
if (content == NULL)
err(1, "failed to allocate memory");
/* read */
FILE *f = fopen(filename, "r");
if (f == NULL)
err(1, "fopen failed (%s)", filename);
u64 check = fread(content, 8, size, f);
if (check != size)
errx(1, "incomplete read %s", filename);
fclose(f);
*size_ = size;
/* byte-swap if necessary */
if (big_endian()) {
#pragma omp parallel for
for (u32 i = 0; i < size; i++)
content[i] = bswap_64(content[i]);
}
return content;
}
/* return a list of vector from the left kernel
*/
monomial_t *left_kernel_from_bin(const char *filename, u64 *size)
{
u64 *content;
/* max number of vector find by cado-nfs*/
u16 n = NB_VEC;
/* getting all vectors from cado-nfs*/
content = load_file(filename, size);
/* allocate memory */
monomial_t *ker = (monomial_t*)malloc(sizeof(monomial_t) * n);
/* memory allow us to know witch vector is null*/
for (u16 i = 0; i < n; i++)
{
ker[i] = 0;
for (u64 j = 0; j < *size; j++)
{
ker[i] <<= 1;
ker[i] += (content[j] >> (n-i-1)&1);
}
}
free(content);
return ker;
}
void print_ker(bool **ker, u64 size)
{
u16 n = NB_VEC;
printf("[\n");
for (u16 i = 0; i < n; i++)
{
printf("[ ");
for (u64 j = 0; j < size-1; j++)
printf("%d ", ker[i][j]);
if (i < n - 1)
printf("%d ],\n\n", ker[i][size-1]);
else
printf("%d ]\n", ker[i][size-1]);
}
printf("]\n");
}
void free_ker(u128 *ker)
{
free(ker);
}
///////////////////////////////////////
///// Dans le fichier de base ///////
///////////////////////////////////////
static inline monomial_t mkvar(int i)
{
return ((monomial_t) 1) << i;
}
/* returns the position of target under the assumption that it is in monomials[lo:hi] */
int binary_search(monomial_t target, int lo, int hi)
{
hi -= 1;
while (lo <= hi) {
int mid = (lo + hi) / 2;
if (target > monomials[mid])
lo = mid + 1;
else if (target < monomials[mid])
hi = mid - 1;
else
return mid;
}
assert(0);
}
int hamming_weight(monomial_t m)
{
return __builtin_popcountl(m) + __builtin_popcountl(m >> 64);
}
int monomial_rank(monomial_t m)
{
int d = hamming_weight(m);
return binary_search(m, Nd[d], Nd[d + 1]);
}
////////////////////////////////
///// Create new system ////
////////////////////////////////
void get_ilog(const char *filename)
{
u64 num_cols;
ilog = load_file(filename, &num_cols);
printf("num_cols = %ld, ncols = %d\n", num_cols, ncols);
//assert((int)num_cols == ncols);
}
void get_jlog(const char *filename)
{
u64 num_rows;
jlog = load_file(filename, &num_rows);
//assert((int)num_rows == nrows);
}
struct output_poly_t *create_next_system(monomial_t *ker)
{
struct output_poly_t *res = (struct output_poly_t *)malloc(sizeof(struct output_poly_t) * NB_VEC);
for (int i = 0; i < NB_VEC; i++)
{
struct input_poly_t tmp = input_system[ilog[i]];
res[i].nterms = tmp.nterms;
monomial_t mem = ker[i] | monomials[jlog[i]];
for (int j = 0; j < tmp.nterms; j++)
res[i].terms[j] = mem | tmp.terms[j];
}
return (res);
}
#include <inttypes.h>
#include <stdbool.h>
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <err.h>
#include <byteswap.h>
#include <sys/wait.h>
typedef int8_t i8;
typedef int16_t i16;
typedef int32_t i32;
typedef int64_t i64;
typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef uint64_t u64;
typedef __int128 u128;
typedef u128 monomial_t;
#define NB_VEC 64
#define MAXDEG 8
struct input_poly_t {
int nterms;
int terms[8257]; /* ok for 128 variables */
};
struct output_poly_t{
int nterms;
monomial_t terms[8127];
};
monomial_t *monomials;
struct input_poly_t *input_system;
int *ilog;
int *jlog;
int ncols;
int nrows;
int Nd[MAXDEG];
bool big_endian();
void *load_file(const char *filename, u64 *size_);
monomial_t *left_kernel_from_bin(const char *filename, u64 *size);
void print_ker(bool **ker, u64 size);
void free_ker(u128 *ker);
static inline monomial_t mkvar(int i);
int binary_search(monomial_t target, int lo, int hi);
int hamming_weight(monomial_t m);
int monomial_rank(monomial_t m);
void get_ilog(const char *filename);
void get_jlog(const char *filename);
struct output_poly_t *create_next_system(monomial_t *ker);
\ No newline at end of file
a, b, c, d
a*c + b*d + a + c + d
b*c + a*d + c*d + a + b + d
b*d + c*d + a + c + 1
a*b + a*c + b*c + c + d + 1
a*b + b*c + a*d + c
a*c + a*d + c*d + a + b + c + d
#
#
#a*e + b*c + b*e + c*d + a + d + e + 1
#a*c + a*d + a*e + b*c + b*d + c*e + d*e + a + b + d
#a*d + b*e + c*d + a + b + d + 1
#a*b + a*d + b*d + b*e + b + d + e
#a*b + a*e + b*c + b*d + c*d + c*e + d*e + a + e + 1
#01001010110
#00110111010
#00001110101
#11010000111
#10110000100
#01100111110
#
#Macaulay reduced
#10000000011
#01000011110
#00100011101
#00010011010
#00001001000
#00000111101
\ No newline at end of file
a, b, c, d
a*c + b*d + a + c + d
b*c + a*d + c*d + a + b + d
b*d + c*d + a + c + 1
a*b + a*c + b*c + c + d + 1
a*b + b*c + a*d + c
a*c + a*d + c*d + a + b + c + d
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment