Commit 525c7bb3 authored by Vivien Kraus's avatar Vivien Kraus
Browse files

Introduce openmp support

parent d205507a
# tarot implements the rules of the tarot game
# Copyright (C) 2017, 2018, 2019 Vivien Kraus
# Copyright (C) 2017, 2018, 2019, 2020 Vivien Kraus
# 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
......@@ -58,9 +58,9 @@ AM_CPPFLAGS += \
-DLIBTAROT_VERSION_INFO="\"$(LIBTOOL_CURRENT):$(LIBTOOL_REVISION):$(LIBTOOL_AGE)\""
AM_YFLAGS = -d
AM_CFLAGS += \
$(NETTLE_CFLAGS) $(XML_CFLAGS)
$(NETTLE_CFLAGS) $(XML_CFLAGS) $(OPENMP_CFLAGS)
AM_LDADD += \
$(NETTLE_LIBS) $(XML_LIBS) $(GUILE_LIBS)
$(NETTLE_LIBS) $(XML_LIBS) $(GUILE_LIBS) $(OPENMP_LIBS)
if WITH_GOBJECT
AM_CFLAGS += $(GOBJECT_CFLAGS)
......
# tarot implements the rules of the tarot game
# Copyright (C) 2017, 2018, 2019 Vivien Kraus
# Copyright (C) 2017, 2018, 2019, 2020 Vivien Kraus
# 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
......@@ -50,6 +50,7 @@ gl_EARLY
AM_INIT_AUTOMAKE
AM_PROG_AR
LT_INIT
AC_OPENMP
AM_MISSING_PROG([INDENT], [indent])
AM_MISSING_PROG([EMACS], [emacs])
AC_ARG_ENABLE([valgrind], AS_HELP_STRING([--enable-valgrind=yes],
......
......@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: tarot 0.4.2.83-ebdc-dirty\n"
"Report-Msgid-Bugs-To: vivien@planete-kraus.eu\n"
"POT-Creation-Date: 2020-01-02 11:32+0100\n"
"POT-Creation-Date: 2020-01-02 12:48+0100\n"
"PO-Revision-Date: 2020-01-02 11:32+0100\n"
"Last-Translator: Vivien Kraus <vivien@planete-kraus.eu>\n"
"Language-Team: French\n"
......@@ -48,7 +48,7 @@ msgstr "Affiche l'information de version et quitte"
#: src/tarot-app/tarot_deal.c:70 src/tarot-app/tarot_mcts.c:88
#: src/tarot-app/tarot_stacking.c:80 src/tarot-app/tarot_features.c:62
#: src/tarot-app/tarot_cnn_features.c:58
#: src/tarot-app/tarot_perceptron_bootstrap.c:94
#: src/tarot-app/tarot_perceptron_bootstrap.c:95
msgid "version"
msgstr "version"
......@@ -56,7 +56,7 @@ msgstr "version"
#: src/tarot-app/tarot_deal.c:112 src/tarot-app/tarot_mcts.c:136
#: src/tarot-app/tarot_stacking.c:112 src/tarot-app/tarot_features.c:93
#: src/tarot-app/tarot_cnn_features.c:89
#: src/tarot-app/tarot_perceptron_bootstrap.c:133
#: src/tarot-app/tarot_perceptron_bootstrap.c:134
#, c-format
msgid ""
"%s (libtarot %s)\n"
......@@ -1210,7 +1210,7 @@ msgstr ""
#: src/tarot-app/tarot_deal.c:69 src/tarot-app/tarot_mcts.c:87
#: src/tarot-app/tarot_stacking.c:79 src/tarot-app/tarot_features.c:61
#: src/tarot-app/tarot_cnn_features.c:57
#: src/tarot-app/tarot_perceptron_bootstrap.c:93
#: src/tarot-app/tarot_perceptron_bootstrap.c:94
msgid "help"
msgstr "aide"
......@@ -1227,7 +1227,7 @@ msgid "no-call-allowed"
msgstr "appel-interdit"
#: src/tarot-app/tarot_deal.c:74 src/tarot-app/tarot_mcts.c:90
#: src/tarot-app/tarot_perceptron_bootstrap.c:98
#: src/tarot-app/tarot_perceptron_bootstrap.c:99
msgid "seed"
msgstr "graine"
......@@ -1570,24 +1570,24 @@ msgstr "Poignée"
msgid "Discarding"
msgstr "Écart"
#: src/tarot-app/tarot_perceptron_bootstrap.c:70
#: src/tarot-app/tarot_perceptron_bootstrap.c:71
#, c-format
msgid "Metric across the epoch\tMaximum weight\tMaximum update\n"
msgstr "Métrique sur toute l'époque\tPoids maximum\tMise à jour maximum\n"
#: src/tarot-app/tarot_perceptron_bootstrap.c:95
#: src/tarot-app/tarot_perceptron_bootstrap.c:96
msgid "learning-rate"
msgstr "taux-d-apprentissage"
#: src/tarot-app/tarot_perceptron_bootstrap.c:96
#: src/tarot-app/tarot_perceptron_bootstrap.c:97
msgid "exploration"
msgstr "exploration"
#: src/tarot-app/tarot_perceptron_bootstrap.c:97
#: src/tarot-app/tarot_perceptron_bootstrap.c:98
msgid "continue"
msgstr "continuer"
#: src/tarot-app/tarot_perceptron_bootstrap.c:119
#: src/tarot-app/tarot_perceptron_bootstrap.c:120
#, c-format
msgid ""
"Usage: tarot-perceptron-bootstrap [OPTIONS]... [HIDDEN_SIZE]...\n"
......@@ -1610,14 +1610,14 @@ msgstr ""
"- -s GRAINE, --seed=GRAINE : définit la graine aléatoire. GRAINE ne\n"
" peut pas être une chaîne vide.\n"
#: src/tarot-app/tarot_perceptron_bootstrap.c:145
#: src/tarot-app/tarot_perceptron_bootstrap.c:146
#, c-format
msgid "Error: the learning rate should be a positive number, not '%s'.\n"
msgstr ""
"Erreur : le taux d'apprentissage doit être un nombre positif, et pas "
"« %s ».\n"
#: src/tarot-app/tarot_perceptron_bootstrap.c:157
#: src/tarot-app/tarot_perceptron_bootstrap.c:158
#, c-format
msgid ""
"Error: the exploration probability should be a probability (between 0 and "
......@@ -1626,18 +1626,18 @@ msgstr ""
"Erreur : la probabilité d'exploration doit être une probabilité (entre\n"
"0 et 1), et pas « %s ».\n"
#: src/tarot-app/tarot_perceptron_bootstrap.c:172
#: src/tarot-app/tarot_perceptron_bootstrap.c:173
#, c-format
msgid "Error: the seed must not be empty.\n"
msgstr "Erreur : la graine ne doit pas être vide.\n"
#: src/tarot-app/tarot_perceptron_bootstrap.c:193
#: src/tarot-app/tarot_perceptron_bootstrap.c:194
#, c-format
msgid "Error: if you are continuing learning, do not specify the structure!\n"
msgstr ""
"Erreur : si vous continuez l'apprentissage, ne spécifiez pas la structure !\n"
#: src/tarot-app/tarot_perceptron_bootstrap.c:208
#: src/tarot-app/tarot_perceptron_bootstrap.c:209
#, c-format
msgid ""
"Error: the %d-th dimension should be a strictly positive integer, not '%s'.\n"
......
......@@ -27,7 +27,8 @@ static struct yarrow256_ctx generator;
static void parse_options (int argc, char *argv[]);
static void epoch (TarotPerceptron * perceptron);
static double self_learn (TarotPerceptron * perceptron);
static double self_learn (struct yarrow256_ctx *prng,
TarotPerceptron * perceptron);
int
main (int argc, char *argv[])
......@@ -268,8 +269,8 @@ custom_ai_destruct (void *data)
}
static inline TarotGame *
play_game (double *metric, TarotPerceptron * p, size_t n_players,
int with_call)
play_game (struct yarrow256_ctx *prng, double *metric, TarotPerceptron * p,
size_t n_players, int with_call)
{
uint8_t next_seed[256];
double sum_metric = 0;
......@@ -284,19 +285,19 @@ play_game (double *metric, TarotPerceptron * p, size_t n_players,
TarotSolo *solo;
int done = 0;
TarotGame *ret = NULL;
yarrow256_random (&generator, sizeof (next_seed), next_seed);
yarrow256_random (prng, sizeof (next_seed), next_seed);
solo =
tarot_solo_alloc_fuzzy (exploration, sizeof (next_seed), next_seed, pure);
fuzzy =
tarot_ai_alloc_fuzzy (exploration, sizeof (next_seed), next_seed, pure);
tarot_ai_free (pure);
yarrow256_random (&generator, sizeof (next_seed), next_seed);
yarrow256_random (prng, sizeof (next_seed), next_seed);
if (tarot_solo_setup_random
(solo, n_players, with_call, sizeof (next_seed),
next_seed) != TAROT_GAME_OK)
{
tarot_solo_free (solo);
ret = play_game (metric, p, n_players, with_call);
ret = play_game (prng, metric, p, n_players, with_call);
tarot_ai_free (fuzzy);
tarot_solo_free (solo);
return ret;
......@@ -337,10 +338,10 @@ play_game (double *metric, TarotPerceptron * p, size_t n_players,
}
static inline void
draw_options (size_t *n_players, int *with_call)
draw_options (struct yarrow256_ctx *prng, size_t *n_players, int *with_call)
{
uint8_t option = 0;
yarrow256_random (&generator, sizeof (option), &option);
yarrow256_random (prng, sizeof (option), &option);
if (option % 4 == 0)
{
*n_players = 3;
......@@ -364,13 +365,14 @@ draw_options (size_t *n_players, int *with_call)
}
static inline TarotGame *
generate (double *metric, TarotPerceptron * perceptron)
generate (struct yarrow256_ctx *prng, double *metric,
TarotPerceptron * perceptron)
{
size_t n_players;
int with_call;
TarotGame *played;
draw_options (&n_players, &with_call);
played = play_game (metric, perceptron, n_players, with_call);
draw_options (prng, &n_players, &with_call);
played = play_game (prng, metric, perceptron, n_players, with_call);
return played;
}
......@@ -386,25 +388,45 @@ epoch (TarotPerceptron * perceptron)
double n_metric = 0;
tarot_perceptron_save_alloc (perceptron, &n_weights, &initial_data);
updates = xcalloc (n_weights, sizeof (double));
#ifdef _OPENMP
#pragma omp parallel for
#endif /* _OPENMP */
for (i = 0; i < 100; i++)
{
TarotPerceptron *my_perceptron = tarot_perceptron_dup (perceptron);
double *final_data;
size_t n_final_weights;
size_t j;
double metric = self_learn (my_perceptron);
struct yarrow256_ctx prng;
double metric;
uint8_t seed[256];
size_t seed_size = sizeof (seed) / sizeof (seed[0]);
#ifdef _OPENMP
#pragma omp critical
#endif /* _OPENMP */
{
yarrow256_random (&generator, seed_size, seed);
}
yarrow256_init (&prng, 0, NULL);
yarrow256_seed (&prng, seed_size, seed);
metric = self_learn (&prng, my_perceptron);
tarot_perceptron_save_alloc (my_perceptron, &n_final_weights,
&final_data);
tarot_perceptron_free (my_perceptron);
assert (n_weights == n_final_weights);
/* Aggregation */
sum_metric += metric;
n_metric += 1;
for (j = 0; j < n_final_weights; j++)
{
double u = final_data[j] - initial_data[j];
updates[j] += u;
}
#ifdef _OPENMP
#pragma omp critical
#endif /* _OPENMP */
{
sum_metric += metric;
n_metric += 1;
for (j = 0; j < n_final_weights; j++)
{
double u = final_data[j] - initial_data[j];
updates[j] += u;
}
}
free (final_data);
}
for (i = 0; i < n_weights; i++)
......@@ -442,10 +464,10 @@ epoch (TarotPerceptron * perceptron)
}
static double
self_learn (TarotPerceptron * perceptron)
self_learn (struct yarrow256_ctx *prng, TarotPerceptron * perceptron)
{
double metric = 0;
TarotGame *generated = generate (&metric, perceptron);
TarotGame *generated = generate (prng, &metric, perceptron);
tarot_game_free (generated);
return metric;
}
Markdown is supported
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