I have rules in Makefile similar to the following.
BOARDS := B1 B2 B3 B4
Rule 1:
.PHONY: $(BOARDS)
$(BOARDS): %: baisc_% debug_%
Rule 2:
SYSTEM_BOARDS = $(foreach board,$(BOARDS),basic_$(board))
.PHONY: $(SYSTEM_BOARDS)
$(SYSTEM_BOARDS):basic_%: packages_%
I think Rule 1 is expanded as following. Please correct me if I am worng.
B1: basic_B1 debug_B1
B2: basic_B2 debug_B2
B3: basic_B3 debug_B3
B4: basic_B4 debug_B4
Can you help to understand how Rule 2 will be expanded.
Related
I've been trying to run the following bioinformatic script:
configfile: "config.yaml"
WORK_TRIM = config["WORK_TRIM"]
WORK_KALL = config["WORK_KALL"]
rule all:
input:
expand(WORK_KALL + "quant_result_{condition}", condition=config["conditions"])
rule kallisto_quant:
input:
fq1 = WORK_TRIM + "{sample}_1_trim.fastq.gz",
fq2 = WORK_TRIM + "{sample}_2_trim.fastq.gz",
idx = WORK_KALL + "Homo_sapiens.GRCh38.cdna.all.fa.index"
output:
WORK_KALL + "quant_result_{condition}"
shell:
"kallisto quant -i {input.idx} -o {output} {input.fq1} {input.fq2}"
However, I keep obtaing an error like this:
WildcardError in line 13 of /home/user/directory/Snakefile:
Wildcards in input files cannot be determined from output files:
'sample'
Just to explain briefly, kallisto quant will produce 3 outputs: abundance.h5, abundance.tsv and run_injo.json. Each of those files need to be sent to their own newly created condition directory. I not getting exactly what is going on wrong. I'll appreciated any help on this.
If you think about it, you are not giving snakemake enough information.
Say "condition" is either "control" or "treated" with samples "C" and "T", respectively. You need to tell snakemake about the association control: C, treated: T. You could do this using functions-as-input files or lambda functions. For example:
cond2samp = {'control': 'C', 'treated': 'T'}
rule all:
input:
expand("quant_result_{condition}", condition=cond2samp.keys())
rule kallisto_quant:
input:
fq1 = lambda wc: "%s_1_trim.fastq.gz" % cond2samp[wc.condition],
fq2 = lambda wc: "%s_2_trim.fastq.gz" % cond2samp[wc.condition],
idx = "Homo_sapiens.GRCh38.cdna.all.fa.index"
output:
"quant_result_{condition}"
shell:
"kallisto quant -i {input.idx} -o {output} {input.fq1} {input.fq2}"
I tried to compile this overflow detection macro of Zend engine:
#define ZEND_SIGNED_MULTIPLY_LONG(a, b, lval, dval, usedval) do { \
long __tmpvar; \
__asm__( \
"mul %0, %2, %3\n" \
"smulh %1, %2, %3\n" \
"sub %1, %1, %0, asr #63\n" \
: "=X"(__tmpvar), "=X"(usedval) \
: "X"(a), "X"(b)); \
if (usedval) (dval) = (double) (a) * (double) (b); \
else (lval) = __tmpvar; \
} while (0)
And got this result in assembly:
; InlineAsm Start
mul x8, x8, x9
smulh x9, x8, x9
sub x9, x9, x8, asr #63
; InlineAsm End
The compiler used only 2 register for both input and output of the macro, which i think it must be at least 3, and lead to wrong result of the calculation (for example, -1 * -1). Any suggestion?
The assembly code is buggy. From GCC's documentation on extended asm:
Use the ‘&’ constraint modifier (see Modifiers) on all output operands that must not overlap an input. Otherwise, GCC may allocate the output operand in the same register as an unrelated input operand, on the assumption that the assembler code consumes its inputs before producing outputs. This assumption may be false if the assembler code actually consists of more than one instruction.
This basically says that from the moment you write to an output parameter not marked with an ampersand, you're not allowed to use the input parameters anymore because they might have been overwritten.
The syntax is designed around the concept of wrapping a single insn which reads its inputs before writing its outputs.
When you use multiple insns, you often need to use an early-clobber modifier on the constraint ("=&x") to let the compiler know you write an output or read-write register before reading all the inputs. Then it will make sure that output register isn't the same register as any of the input registers.
See also the x86 tag wiki, and my collection of inline asm docs and SO answers at the bottom of this answer.
#define ZEND_SIGNED_MULTIPLY_LONG(a, b, lval, dval, usedval) do { \
long __tmpvar; \
__asm__( \
"mul %[tmp], %[a], %[b]\n\t" \
"smulh %[uv], %[a], %[b]\n\t" \
"sub %[uv], %[uv], %[tmp], asr #63\n" \
: [tmp] "=&X"(__tmpvar), [uv] "=&X"(usedval) \
: [a] "X"(a), [b] "X"(b)); \
if (usedval) (dval) = (double) (a) * (double) (b); \
else (lval) = __tmpvar; \
} while (0)
Do you really need all those instructions to be inside the inline asm? Can't you make long tmp = a * b an input operand? Then if the compiler needs a*b elsewhere in the function, CSE can see it.
You can convince gcc to broadcast the sign bit with an arithmetic right shift using a ternary operator. So hopefully you can coax the compiler to do the sub that way. Then it could use subs to set flags from the sub instead of needing a separate test insn on usedval.
If you can't get your target compiler to make the code you want, then sure, give inline asm a shot. But beware, I've seen clang be a lot worse than gcc with inline asm. It tends to make worse code around the inline
asm on x86.
I have this definitions in Makefile:
PREFIX = PRE
POSTFIXES = POST1 POST2 POST3
Now I would like to generate programmatically the following macros:
NAME_1 = PRE_POST1
NAME_2 = PRE_POST2
NAME_3 = PRE_POST3
#...
How to do that?
This does what you want assuming NAME_# was literal.
$(foreach f,$(POSTFIXES),$(eval NAME_$(subst POST,,$f) = $(PREFIX)_$f))
Result:
NAME_1 = PRE_POST1
NAME_2 = PRE_POST2
NAME_3 = PRE_POST3
Explanation:
Remove POST from each postfix leaving just the number: $(subst POST,,$f)
Concatenate NAME_ with the number from the previous step: NAME_$(subst POST,,$f)
Concatenate $(PREFIX) and the current postfix to create the desired value string: $(PREFIX)_$f
Use $(eval) to assign the value to the computed variable name: $(eval NAME_$(subst POST,,$f) = $(PREFIX)_$f)
Do that all for each postfix in the list: $(foreach f,$(POSTFIXES),$(eval NAME_$(subst POST,,$f) = $(PREFIX)_$f))
Update for sequential NAME_# variables unrelated to POSTFIXES values:
make doesn't do math, at all really, so you need to play games to "count". (Thanks to the fantastic GMSL for showing me this trick.)
POSTFIXES = POST_X POST_Y POST_Z
N := x
$(foreach f,$(POSTFIXES),$(eval NAME_$(words $N) = $(PREFIX)_$f)$(eval N += x))
Result:
NAME_1 = PRE_POST_X
NAME_2 = PRE_POST_Y
NAME_3 = PRE_POST_Z
this is the makefile :
TOP=../..
DIRNAME=base_class/string
H = regexp.h regmagic.h string_version.h
CSRCS = regerror.c regsub.c EST_strcasecmp.c
TSRCS =
CPPSRCS = EST_String.cc EST_Regex.cc EST_Chunk.cc regexp.cc
LOCAL_DEFAULT_LIBRARY = eststring
SRCS = $(CPPSRCS) $(CSRCS)
OBJS = $(CPPSRCS:.cc=.o) $(CSRCS:.c=.o)
FILES = $(SRCS) $(TSRCS) $(H) Makefile
LOCAL_INCLUDES=-I.
ALL = .buildlibs
include $(TOP)/config/common_make_rules
now i know these part is variable
TOP=../..
DIRNAME=base_class/string
H = regexp.h regmagic.h string_version.h
CSRCS = regerror.c regsub.c EST_strcasecmp.c
TSRCS =
CPPSRCS = EST_String.cc EST_Regex.cc EST_Chunk.cc regexp.cc
LOCAL_DEFAULT_LIBRARY = eststring
SRCS = $(CPPSRCS) $(CSRCS)
what i do not know is :
OBJS = $(CPPSRCS:.cc=.o) $(CSRCS:.c=.o)
pls tell me the meaning of above statement , it is best if you figure out what above statement omit. thanks.
You can look this up in the GNU make manual. The above is equivalent to writing $(CPPSRCS:%.cc=%.o) (and ditto for CSRCS). In both of these, it goes through each word in the variable and if it matches the left-hand side of the equality, it's replaced with the right-hand side. So if a word matches the pattern %.cc (where % to make matches any sequence of characters), then it's replaced with %.o (where % is the same as in the original). The form you see is a special case where you can omit the % if it's the first thing in both sides.
So, given CPPSRCS = EST_String.cc EST_Regex.cc EST_Chunk.cc regexp.cc, then $(CPPSRCS:.cc=.o) expands to EST_String.o EST_Regex.o EST_Chunk.o regexp.o.
I have a Makefile which looks roughly like this:
FIGURES = A1_B1_C1.eps A2_B2_C2.eps A3_B3_C3.eps
NUMBERS = 1 2 3
all : $(FIGURES)
%.eps : $(foreach num, $(NUMBERS), $(subst B, $(num), %).out)
# my_program($+, $#);
%.out :
The point is that the file names of my figures contain certain information (A, B, C) and that each figure is created by my_program from several (in the example 3) files.
While the filename of each figure has the format Ax_Bx_Cx.eps, the names of the data files to create the figures from look like this:
Ax_1x_Cx.out
Ax_2x_Cx.out
Ax_3x_Cx.out
So for each figure, I need a dynamically created dependency list with several file names. In other words, my desired output for the example above would be:
# my_program(A1_11_C1.out A1_21_C1.out A1_31_C1.out, A1_B1_C1.eps);
# my_program(A2_12_C2.out A2_22_C2.out A2_32_C2.out, A2_B2_C2.eps);
# my_program(A3_13_C3.out A3_23_C3.out A3_33_C3.out, A3_B2_C3.eps);
Unfortunately, the subst command seems to be ignored, for the output looks like this:
# my_program(A1_B1_C1.out A1_B1_C1.out A1_B1_C1.out, A1_B1_C1.eps);
# my_program(A2_B2_C2.out A2_B2_C2.out A2_B2_C2.out, A2_B2_C2.eps);
# my_program(A3_B3_C3.out A3_B3_C3.out A3_B3_C3.out, A3_B3_C3.eps);
I had a look at this possible duplicate but figured that the answer cannot help me, since I am using % and not $#, which should be ok in the prerequisites.
Clearly I am getting something wrong here. Any help is greatly appreciated.
To do fancy prerequisite manipulations you need at least make-3.82 which supports Secondary Expansion feature:
FIGURES = A1_B1_C1.eps A2_B2_C2.eps A3_B3_C3.eps
NUMBERS = 1 2 3
all : $(FIGURES)
.SECONDEXPANSION:
$(FIGURES) : %.eps : $$(foreach num,$$(NUMBERS),$$(subst B,$$(num),$$*).out)
#echo "my_program($+, $#)"
%.out :
touch $#
Output:
$ make
touch A1_11_C1.out
touch A1_21_C1.out
touch A1_31_C1.out
my_program(A1_11_C1.out A1_21_C1.out A1_31_C1.out, A1_B1_C1.eps)
touch A2_12_C2.out
touch A2_22_C2.out
touch A2_32_C2.out
my_program(A2_12_C2.out A2_22_C2.out A2_32_C2.out, A2_B2_C2.eps)
touch A3_13_C3.out
touch A3_23_C3.out
touch A3_33_C3.out
my_program(A3_13_C3.out A3_23_C3.out A3_33_C3.out, A3_B3_C3.eps)