Trabalho I: Multiplicação de Matrizes
Objectivo
O objectivo principal deste trabalho é fornecer aos alunos um primeiro
contacto com programação avançada em UNIX tendo como base a linguagem
C. Em particular, pretende-se que os alunos sejam capazes de lidar com
argumentos passados através da linha de comando e com chamadas de
sistema para manipulação de processos, tais como:
fork(), pipe(), dup2(),
exec(), wait(), exit(),
entre outras.
Trabalho
O trabalho é composto por 3 etapas independentes que no conjunto
levarão à implementação de uma mini linha de comandos para
multiplicação de matrizes de inteiros. O produto final do trabalho
deve ser um conjunto de 3 programas, cada um implementando cada uma
das etapas. Segue-se a descrição das várias etapas do trabalho.
Etapa 1: vecmult
Crie um programa de nome vecmult para multiplicar um
vector de inteiros por uma matriz de inteiros. O programa deverá
aceitar como argumento o nome do ficheiro contendo a descrição da
matriz e deverá receber do stdin a descrição do
vector. O resultado da multiplicação do vector pela matriz deverá ser
enviado para o stdout.
O ficheiro com a descrição da matriz deverá seguir o formato que se
segue:
L C
M11 M12 ... M1C
M21 M22 ... M2C
...
ML1 ML2 ... MLC
|
em que os dois primeiros valores indicam respectivamente o número de
linhas (L > 0) e colunas (C > 0) da matriz e os restantes valores
indicam o conteúdo da matriz (Mij). Por sua vez a descrição do vector
deverá seguir o seguinte formato:
Por exemplo, considere dois ficheiros matrix.dat e
vector.dat respectivamente com os seguintes conteúdos:
4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
|
e
Sendo assim a execução do comando vecmult matrix.dat <
vector.dat deverá devolver o seguinte resultado:
Como simplicação evite a detecção de erros e considere que os dados
relativos ao vector e à matriz são sempre válidos e compatíveis (o
tamanho do vector é igual ao número de linhas da matriz). Para ler a
informação da matriz e do vector poderá utilizar as funções
da família scanf().
Etapa 2: matmult
Crie um programa de nome matmult para multiplicar duas
matrizes de inteiros. O programa deverá aceitar como argumentos o nome
dos ficheiros contendo a descrição das matrizes e deverá enviar o
resultado da multiplicação para o stdout. A execução
do programa deverá ser algo da forma matmult matrixA.dat
matrixB.dat, em que os ficheiros com a descrição das matrizes
seguem o formato da etapa anterior.
Para calcular a matriz resultado, o programa matmult
deverá criar tantos processos filho quantas as linhas da 1ª
matriz. Por seu lado, cada processo filho deverá executar o
programa vecmult da etapa anterior de modo a calcular
uma das linhas da matriz resultado. O programa vecmult
deverá ser executado através da utilização de uma das funções da
família exec(), enquanto que a comunicação entre o
programa matmult e os diversos filhos
vecmult deverá ser conseguido por utilização de pipes.
Como simplicação evite a detecção de erros e considere que os dados
relativos às matrizes são sempre válidos e compatíveis (neste caso o
número de colunas da 1ª matriz deverá ser igual ao número de linhas da
2ª matriz). A leitura das linhas da 1ª matriz poderá ser feita
utilizando a função getline().
Etapa 3: shellmult
Crie um programa de nome shellmult que implemente uma
mini linha de comandos para multiplicação de matrizes (use o exercício
da aula prática Exercícios II como
referência para implementar o tratamento da linha de comandos). O
programa deverá aceitar os comandos que se seguem:
- inA fich.dat: define fich.dat
como sendo o ficheiro com a descrição da 1ª matriz.
- inB fich.dat: define fich.dat
como sendo o ficheiro com a descrição da 2ª matriz.
- out fich.dat: define fich.dat
como sendo o ficheiro para onde deve ser enviado o output de uma
operação de multiplicação de
matrizes. Se fich.dat for omitido o output
deverá ser enviado para o stdout.
- mult: multiplica as matrizes indicadas pelos
comandos inA e inB e envia o
resultado para o ficheiro indicado pelo
comando out (se algum). Antes de fazer a
multiplicação o comando deverá garantir que as matrizes são
válidas e compatíveis.
- exit: termina o programa.
Possíveis erros de sintaxe ou de semântica na invocação dos comandos
devem ser detectados e reportados para o stderr tal
como se indica a seguir.
- Erros de sintaxe devem ser reportados numa única linha e segundo
o seguinte formato: ERROR(input: <mensagem de erro
apropriada>). Exemplos:
ERROR(input: command not found)
ERROR(input: too many arguments)
|
- Erros de semântica (i.e., erros em que, apesar do comando estar
sintacticamente correcto, este não pode ser executado por alguma
razão) devem ser reportados numa única linha e segundo o
seguinte formato: ERROR(<nome do comando>:
<mensagem de erro apropriada>). Exemplos:
ERROR(inA: cannot open 'fich.dat')
ERROR(mult: incompatible matrices)
|
Prazos
O trabalho deve ser entregue via web até às 12 horas do
dia 20 de Abril de 2009, sendo a sua demonstração feita na aula
prática imediatamente a seguir.
O que entregar? Um ficheiro .tar que inclua:
- Os ficheiros que implementam o conjunto das etapas (de
preferência utilizar os nomes vecmult.c,
matmult.c e shellmult.c);
- A makefile que gera os executáveis (vecmult,
matmult e shellmult) do
trabalho.
O código deve compilar e executar nas máquinas da sala das aulas
práticas. Uma boa estruturação e legibilidade do código será
valorizada.